diff --git a/.eslintrc.json b/.eslintrc.json index 53b73aa434..b928e85a3c 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -48,13 +48,7 @@ } ], "no-throw-literal": "warn", - "semi": "off", - "no-restricted-properties": [ - 2, - { - "property": "activeTextEditor" - } - ] + "semi": "off" }, "ignorePatterns": ["**/vendor/**/*.ts", "**/vendor/**/*.js"] } diff --git a/package.json b/package.json index 465d9305bc..d9c4289825 100644 --- a/package.json +++ b/package.json @@ -590,18 +590,20 @@ "@types/chai": "^4.3.3", "@types/glob": "^7.1.3", "@types/js-yaml": "^4.0.2", + "@types/lodash": "^4.14.168", "@types/mocha": "^8.0.4", "@types/node": "^16.11.3", "@types/semver": "^7.3.9", "@types/sinon": "^10.0.2", + "@types/uuid": "^8.3.4", "@types/vscode": "~1.61.0", "@typescript-eslint/eslint-plugin": "^5.20.0", "@typescript-eslint/parser": "^5.20.0", "@vscode/test-electron": "^2.1.3", "chai": "^4.3.6", "esbuild": "^0.11.12", - "eslint": "^8.13.0", "eslint-config-prettier": "^8.5.0", + "eslint": "^8.13.0", "fast-xml-parser": "^3.20.0", "glob": "^7.1.7", "js-yaml": "^4.1.0", @@ -615,12 +617,12 @@ "typescript": "4.6.3" }, "dependencies": { - "@types/lodash": "^4.14.168", "immer": "^9.0.15", "immutability-helper": "^3.1.1", "itertools": "^1.7.1", "lodash": "^4.17.21", "node-html-parser": "^5.3.3", + "uuid": "^9.0.0", "vscode-uri": "^3.0.6" } } diff --git a/src/actions/BringMoveSwap.ts b/src/actions/BringMoveSwap.ts index b13c9e5a57..b3d8badcc0 100644 --- a/src/actions/BringMoveSwap.ts +++ b/src/actions/BringMoveSwap.ts @@ -1,12 +1,13 @@ +import { Selection, TextEditor } from "@cursorless/common"; import { flatten } from "lodash"; -import { DecorationRangeBehavior, Selection, TextEditor } from "vscode"; +import { DecorationRangeBehavior } from "vscode"; import { getSelectionInfo, performEditsAndUpdateFullSelectionInfos, } from "../core/updateSelections/updateSelections"; +import ide from "../libs/cursorless-engine/singletons/ide.singleton"; import { Target } from "../typings/target.types"; import { EditWithRangeUpdater, Graph } from "../typings/Types"; -import { selectionFromRange } from "../util/selectionUtils"; import { setSelectionsWithoutFocusingEditor } from "../util/setSelectionsAndFocusEditor"; import { getContentRange, runForEachEditor } from "../util/targetUtils"; import { unifyRemovalTargets } from "../util/unifyRanges"; @@ -167,7 +168,7 @@ class BringMoveSwap implements Action { ({ edit: { range }, originalTarget }) => getSelectionInfo( editor.document, - selectionFromRange(originalTarget.isReversed, range), + range.toSelection(originalTarget.isReversed), DecorationRangeBehavior.OpenOpen, ), ); @@ -180,10 +181,12 @@ class BringMoveSwap implements Action { ), ); + const editableEditor = ide().getEditableTextEditor(editor); + const [updatedEditSelections, cursorSelections]: Selection[][] = await performEditsAndUpdateFullSelectionInfos( this.graph.rangeUpdater, - editor, + editableEditor, filteredEdits.map(({ edit }) => edit), [editSelectionInfos, cursorSelectionInfos], ); @@ -191,7 +194,7 @@ class BringMoveSwap implements Action { // NB: We set the selections here because we don't trust vscode to // properly move the cursor on a bring. Sometimes it will smear an // empty selection - setSelectionsWithoutFocusingEditor(editor, cursorSelections); + setSelectionsWithoutFocusingEditor(editableEditor, cursorSelections); return edits.map((edit, index): MarkEntry => { const selection = updatedEditSelections[index]; @@ -199,7 +202,7 @@ class BringMoveSwap implements Action { const target = edit.originalTarget; return { editor, - selection: selectionFromRange(target.isReversed, range), + selection: range.toSelection(target.isReversed), isSource: edit.isSource, target, }; diff --git a/src/actions/Clear.ts b/src/actions/Clear.ts index ba55d5ebd5..e3bbd509b3 100644 --- a/src/actions/Clear.ts +++ b/src/actions/Clear.ts @@ -1,3 +1,4 @@ +import ide from "../libs/cursorless-engine/singletons/ide.singleton"; import { PlainTarget } from "../processTargets/targets"; import { Target } from "../typings/target.types"; import { Graph } from "../typings/Types"; @@ -29,7 +30,7 @@ export default class Clear implements Action { if (thatMark != null) { await setSelectionsAndFocusEditor( - editor, + ide().getEditableTextEditor(editor), thatMark.map(({ selection }) => selection), ); } diff --git a/src/actions/CommandAction.ts b/src/actions/CommandAction.ts index 25458003fc..6c49576df1 100644 --- a/src/actions/CommandAction.ts +++ b/src/actions/CommandAction.ts @@ -2,10 +2,10 @@ import { flatten } from "lodash"; import { commands } from "vscode"; import { selectionToThatTarget } from "../core/commandRunner/selectionToThatTarget"; import { callFunctionAndUpdateSelections } from "../core/updateSelections/updateSelections"; +import ide from "../libs/cursorless-engine/singletons/ide.singleton"; import { Target } from "../typings/target.types"; import { Graph } from "../typings/Types"; import { - focusEditor, setSelectionsAndFocusEditor, setSelectionsWithoutFocusingEditor, } from "../util/setSelectionsAndFocusEditor"; @@ -15,7 +15,6 @@ import { runOnTargetsForEachEditor, } from "../util/targetUtils"; import { Action, ActionReturnValue } from "./actions.types"; -import { getActiveTextEditor } from "../ide/vscode/activeTextEditor"; export interface CommandOptions { command?: string; @@ -53,7 +52,11 @@ export default class CommandAction implements Action { ); // For command to the work we have to have the correct editor focused - await setSelectionsAndFocusEditor(editor, targetSelections, false); + await setSelectionsAndFocusEditor( + ide().getEditableTextEditor(editor), + targetSelections, + false, + ); const [updatedOriginalSelections, updatedTargetSelections] = await callFunctionAndUpdateSelections( @@ -70,7 +73,10 @@ export default class CommandAction implements Action { // very end. This code can run on multiple editors in the course of // one command, so we want to avoid focusing the editor multiple // times. - setSelectionsWithoutFocusingEditor(editor, updatedOriginalSelections); + setSelectionsWithoutFocusingEditor( + ide().getEditableTextEditor(editor), + updatedOriginalSelections, + ); } // If the document hasn't changed then we just return the original targets @@ -120,7 +126,7 @@ export default class CommandAction implements Action { ensureSingleTarget(targets); } - const originalEditor = getActiveTextEditor(); + const originalEditor = ide().activeEditableTextEditor; const thatTargets = await this.runCommandAndUpdateSelections( targets, @@ -131,12 +137,12 @@ export default class CommandAction implements Action { if ( actualOptions.restoreSelection && originalEditor != null && - originalEditor !== getActiveTextEditor() + !originalEditor.isActive ) { // NB: We just do one editor focus at the end, instead of using // setSelectionsAndFocusEditor because the command might operate on // multiple editors, so we just do one focus at the end. - await focusEditor(originalEditor); + await originalEditor.focus(); } return { thatTargets }; diff --git a/src/actions/Deselect.ts b/src/actions/Deselect.ts index e181aa928c..f7e4e78524 100644 --- a/src/actions/Deselect.ts +++ b/src/actions/Deselect.ts @@ -1,4 +1,4 @@ -import { Selection } from "vscode"; +import ide from "../libs/cursorless-engine/singletons/ide.singleton"; import { Target } from "../typings/target.types"; import { Graph } from "../typings/Types"; import { setSelectionsWithoutFocusingEditor } from "../util/setSelectionsAndFocusEditor"; @@ -20,12 +20,14 @@ export default class Deselect implements Action { return intersection && (!intersection.isEmpty || selection.isEmpty); }), ); - // The editor requires at least one selection. Keep "primary" selection active + + if (newSelections.length === 0) { + throw new SelectionRequiredError(); + } + setSelectionsWithoutFocusingEditor( - editor, - newSelections.length > 0 - ? newSelections - : [new Selection(editor.selection.active, editor.selection.active)], + ide().getEditableTextEditor(editor), + newSelections, ); }); @@ -34,3 +36,10 @@ export default class Deselect implements Action { }; } } + +class SelectionRequiredError extends Error { + constructor() { + super("Can't deselect every selection. At least one is required"); + this.name = "SelectionRequiredError"; + } +} diff --git a/src/actions/EditNew/EditNew.ts b/src/actions/EditNew/EditNew.ts index a9a2800475..5658e5f6c9 100644 --- a/src/actions/EditNew/EditNew.ts +++ b/src/actions/EditNew/EditNew.ts @@ -1,16 +1,16 @@ +import ide from "../../libs/cursorless-engine/singletons/ide.singleton"; import { containingLineIfUntypedStage } from "../../processTargets/modifiers/commonContainingScopeIfUntypedStages"; import PositionStage from "../../processTargets/modifiers/PositionStage"; import { ModifierStage } from "../../processTargets/PipelineStages.types"; import { Target } from "../../typings/target.types"; import { Graph } from "../../typings/Types"; -import { selectionFromRange } from "../../util/selectionUtils"; import { setSelectionsAndFocusEditor } from "../../util/setSelectionsAndFocusEditor"; import { createThatMark, ensureSingleEditor } from "../../util/targetUtils"; import { Action, ActionReturnValue } from "../actions.types"; import { State } from "./EditNew.types"; -import { runNotebookCellTargets } from "./runNotebookCellTargets"; import { runCommandTargets } from "./runCommandTargets"; import { runEditTargets } from "./runEditTargets"; +import { runNotebookCellTargets } from "./runNotebookCellTargets"; export class EditNew implements Action { getFinalStages(): ModifierStage[] { @@ -29,7 +29,9 @@ export class EditNew implements Action { return runNotebookCellTargets(this.graph, targets); } - const editor = ensureSingleEditor(targets); + const editableEditor = ide().getEditableTextEditor( + ensureSingleEditor(targets), + ); /** * Keeps track of the desired cursor positions and "that" marks as we @@ -41,13 +43,13 @@ export class EditNew implements Action { cursorRanges: new Array(targets.length).fill(undefined) as undefined[], }; - state = await runCommandTargets(this.graph, editor, state); - state = await runEditTargets(this.graph, editor, state); + state = await runCommandTargets(this.graph, editableEditor, state); + state = await runEditTargets(this.graph, editableEditor, state); const newSelections = state.targets.map((target, index) => - selectionFromRange(target.isReversed, state.cursorRanges[index]!), + state.cursorRanges[index]!.toSelection(target.isReversed), ); - await setSelectionsAndFocusEditor(editor, newSelections); + await setSelectionsAndFocusEditor(editableEditor, newSelections); return { thatSelections: createThatMark(state.targets, state.thatRanges), diff --git a/src/actions/EditNew/EditNew.types.ts b/src/actions/EditNew/EditNew.types.ts index 55fdbea8f2..27ca438d36 100644 --- a/src/actions/EditNew/EditNew.types.ts +++ b/src/actions/EditNew/EditNew.types.ts @@ -1,5 +1,5 @@ -import { Range } from "vscode"; -import { Target } from "../../typings/target.types"; +import type { Range } from "@cursorless/common"; +import type { Target } from "../../typings/target.types"; /** * Internal type to be used for storing a reference to a target that will use a diff --git a/src/actions/EditNew/runCommandTargets.ts b/src/actions/EditNew/runCommandTargets.ts index 423645a11a..437a613615 100644 --- a/src/actions/EditNew/runCommandTargets.ts +++ b/src/actions/EditNew/runCommandTargets.ts @@ -1,4 +1,5 @@ -import { commands, TextEditor } from "vscode"; +import { EditableTextEditor } from "@cursorless/common"; +import { commands } from "vscode"; import { callFunctionAndUpdateRanges } from "../../core/updateSelections/updateSelections"; import { Graph } from "../../typings/Types"; import { CommandTarget, State } from "./EditNew.types"; @@ -16,7 +17,7 @@ import { CommandTarget, State } from "./EditNew.types"; */ export async function runCommandTargets( graph: Graph, - editor: TextEditor, + editor: EditableTextEditor, state: State, ): Promise { const commandTargets: CommandTarget[] = state.targets diff --git a/src/actions/EditNew/runEditTargets.ts b/src/actions/EditNew/runEditTargets.ts index b3363405e9..5b97ea6153 100644 --- a/src/actions/EditNew/runEditTargets.ts +++ b/src/actions/EditNew/runEditTargets.ts @@ -1,5 +1,6 @@ +import { Selection, EditableTextEditor } from "@cursorless/common"; import { zip } from "lodash"; -import { DecorationRangeBehavior, Range, Selection, TextEditor } from "vscode"; +import { DecorationRangeBehavior } from "vscode"; import { performEditsAndUpdateSelectionsWithBehavior } from "../../core/updateSelections/updateSelections"; import { Graph } from "../../typings/Types"; import { EditTarget, State } from "./EditNew.types"; @@ -19,7 +20,7 @@ import { EditTarget, State } from "./EditNew.types"; */ export async function runEditTargets( graph: Graph, - editor: TextEditor, + editor: EditableTextEditor, state: State, ): Promise { const editTargets: EditTarget[] = state.targets @@ -43,7 +44,7 @@ export async function runEditTargets( ); const thatSelections = { - selections: state.thatRanges.map(toSelection), + selections: state.thatRanges.map((r) => r.toSelection(false)), }; // We need to remove undefined cursor locations. Note that these undefined @@ -57,11 +58,11 @@ export async function runEditTargets( const cursorIndices = cursorInfos.map(({ index }) => index); const cursorSelections = { - selections: cursorInfos.map(({ range }) => toSelection(range!)), + selections: cursorInfos.map(({ range }) => range!.toSelection(false)), }; const editSelections = { - selections: edits.map((edit) => toSelection(edit.range)), + selections: edits.map((edit) => edit.range.toSelection(false)), rangeBehavior: DecorationRangeBehavior.OpenOpen, }; @@ -96,7 +97,3 @@ export async function runEditTargets( cursorRanges: updatedCursorRanges, }; } - -function toSelection(range: Range) { - return new Selection(range.start, range.end); -} diff --git a/src/actions/EditNew/runNotebookCellTargets.ts b/src/actions/EditNew/runNotebookCellTargets.ts index d014fe9ee6..5ad65b6888 100644 --- a/src/actions/EditNew/runNotebookCellTargets.ts +++ b/src/actions/EditNew/runNotebookCellTargets.ts @@ -1,4 +1,5 @@ -import { commands, Selection } from "vscode"; +import { Selection } from "@cursorless/common"; +import { commands } from "vscode"; import { NotebookCellPositionTarget } from "../../processTargets/targets"; import { Target } from "../../typings/target.types"; import { Graph } from "../../typings/Types"; @@ -20,8 +21,8 @@ export async function runNotebookCellTargets( // Inserting a new jupyter cell above pushes the previous one down two lines if (command === "jupyter.insertCellAbove") { thatMark[0].selection = new Selection( - thatMark[0].selection.anchor.translate({ lineDelta: 2 }), - thatMark[0].selection.active.translate({ lineDelta: 2 }), + thatMark[0].selection.anchor.translate(2, undefined), + thatMark[0].selection.active.translate(2, undefined), ); } diff --git a/src/actions/Fold.ts b/src/actions/Fold.ts index e54032606c..e5ac7c93c1 100644 --- a/src/actions/Fold.ts +++ b/src/actions/Fold.ts @@ -1,10 +1,9 @@ import { commands } from "vscode"; +import ide from "../libs/cursorless-engine/singletons/ide.singleton"; import { Target } from "../typings/target.types"; import { Graph } from "../typings/Types"; -import { focusEditor } from "../util/setSelectionsAndFocusEditor"; import { createThatMark, ensureSingleEditor } from "../util/targetUtils"; import { Action, ActionReturnValue } from "./actions.types"; -import { getActiveTextEditor } from "../ide/vscode/activeTextEditor"; class FoldAction implements Action { constructor(private command: string) { @@ -12,11 +11,11 @@ class FoldAction implements Action { } async run([targets]: [Target[], Target[]]): Promise { - const originalEditor = getActiveTextEditor(); + const originalEditor = ide().activeEditableTextEditor; const editor = ensureSingleEditor(targets); if (originalEditor !== editor) { - await focusEditor(editor); + await ide().getEditableTextEditor(editor).focus(); } const singleLineTargets = targets.filter( @@ -42,7 +41,7 @@ class FoldAction implements Action { // If necessary focus back original editor if (originalEditor != null && originalEditor !== editor) { - await focusEditor(originalEditor); + await originalEditor.focus(); } return { diff --git a/src/actions/FollowLink.ts b/src/actions/FollowLink.ts index a10e1be6db..cc19147620 100644 --- a/src/actions/FollowLink.ts +++ b/src/actions/FollowLink.ts @@ -1,7 +1,6 @@ -import { env, Uri, window } from "vscode"; +import ide from "../libs/cursorless-engine/singletons/ide.singleton"; import { Target } from "../typings/target.types"; import { Graph } from "../typings/Types"; -import { getLinkForTarget } from "../util/getLinks"; import { createThatMark, ensureSingleTarget } from "../util/targetUtils"; import { Action, ActionReturnValue } from "./actions.types"; @@ -18,10 +17,11 @@ export default class FollowLink implements Action { this.graph.editStyles.referenced, ); - const link = await getLinkForTarget(target); - if (link) { - await this.openUri(link.target!); - } else { + const openedLink = await ide() + .getEditableTextEditor(target.editor) + .openLink(target.contentRange); + + if (!openedLink) { await this.graph.actions.executeCommand.run( [targets], "editor.action.revealDefinition", @@ -33,18 +33,4 @@ export default class FollowLink implements Action { thatSelections: createThatMark(targets), }; } - - private async openUri(uri: Uri) { - switch (uri.scheme) { - case "http": - case "https": - await env.openExternal(uri); - break; - case "file": - await window.showTextDocument(uri); - break; - default: - throw Error(`Unknown uri scheme '${uri.scheme}'`); - } - } } diff --git a/src/actions/GenerateSnippet/GenerateSnippet.ts b/src/actions/GenerateSnippet/GenerateSnippet.ts index 4b2c9e4584..f7a9e70dbc 100644 --- a/src/actions/GenerateSnippet/GenerateSnippet.ts +++ b/src/actions/GenerateSnippet/GenerateSnippet.ts @@ -1,12 +1,11 @@ -import { ensureSingleTarget } from "../../util/targetUtils"; - -import { commands, Range, window } from "vscode"; +import { Range } from "@cursorless/common"; +import { commands, window } from "vscode"; +import ide from "../../libs/cursorless-engine/singletons/ide.singleton"; import { Offsets } from "../../processTargets/modifiers/surroundingPair/types"; import isTesting from "../../testUtil/isTesting"; import { Target } from "../../typings/target.types"; import { Graph } from "../../typings/Types"; -import { getDocumentRange } from "../../util/rangeUtils"; -import { selectionFromRange } from "../../util/selectionUtils"; +import { ensureSingleTarget } from "../../util/targetUtils"; import { Action, ActionReturnValue } from "../actions.types"; import { constructSnippetBody } from "./constructSnippetBody"; import { editText } from "./editText"; @@ -214,8 +213,8 @@ export default class GenerateSnippet implements Action { if (isTesting()) { // If we're testing, we just overwrite the current document - editor.selections = [ - selectionFromRange(false, getDocumentRange(editor.document)), + ide().getEditableTextEditor(editor).selections = [ + editor.document.range.toSelection(false), ]; } else { // Otherwise, we create and open a new document for the snippet in the diff --git a/src/actions/InsertCopy.ts b/src/actions/InsertCopy.ts index 4affc78f1c..81be1f11c4 100644 --- a/src/actions/InsertCopy.ts +++ b/src/actions/InsertCopy.ts @@ -1,6 +1,8 @@ +import { Selection, TextEditor } from "@cursorless/common"; import { flatten, zip } from "lodash"; -import { DecorationRangeBehavior, Selection, TextEditor } from "vscode"; +import { DecorationRangeBehavior } from "vscode"; import { performEditsAndUpdateSelectionsWithBehavior } from "../core/updateSelections/updateSelections"; +import ide from "../libs/cursorless-engine/singletons/ide.singleton"; import { containingLineIfUntypedStage } from "../processTargets/modifiers/commonContainingScopeIfUntypedStages"; import { Target } from "../typings/target.types"; import { Graph } from "../typings/Types"; @@ -56,13 +58,15 @@ class InsertCopy implements Action { rangeBehavior: DecorationRangeBehavior.OpenOpen, }; + const editableEditor = ide().getEditableTextEditor(editor); + const [ updatedEditorSelections, updatedContentSelections, updatedEditSelections, ]: Selection[][] = await performEditsAndUpdateSelectionsWithBehavior( this.graph.rangeUpdater, - editor, + editableEditor, edits, [cursorSelections, contentSelections, editSelections], ); @@ -71,8 +75,8 @@ class InsertCopy implements Action { ([edit, selection]) => edit!.updateRange(selection!), ); - setSelectionsWithoutFocusingEditor(editor, updatedEditorSelections); - editor.revealRange(editor.selection); + setSelectionsWithoutFocusingEditor(editableEditor, updatedEditorSelections); + editableEditor.revealRange(editor.selections[0]); return { sourceMark: createThatMark(targets, insertionRanges), diff --git a/src/actions/InsertEmptyLines.ts b/src/actions/InsertEmptyLines.ts index 16acc2274b..c4158a9d1f 100644 --- a/src/actions/InsertEmptyLines.ts +++ b/src/actions/InsertEmptyLines.ts @@ -1,6 +1,7 @@ +import { Range, Selection } from "@cursorless/common"; import { flatten } from "lodash"; -import { Range, Selection } from "vscode"; import { performEditsAndUpdateSelections } from "../core/updateSelections/updateSelections"; +import ide from "../libs/cursorless-engine/singletons/ide.singleton"; import { Target } from "../typings/target.types"; import { Graph } from "../typings/Types"; import { setSelectionsWithoutFocusingEditor } from "../util/setSelectionsAndFocusEditor"; @@ -46,10 +47,12 @@ class InsertEmptyLines implements Action { const ranges = this.getRanges(targets); const edits = this.getEdits(ranges); + const editableEditor = ide().getEditableTextEditor(editor); + const [updatedThatSelections, lineSelections, updatedCursorSelections] = await performEditsAndUpdateSelections( this.graph.rangeUpdater, - editor, + editableEditor, edits, [ targets.map((target) => target.thatTarget.contentSelection), @@ -58,7 +61,10 @@ class InsertEmptyLines implements Action { ], ); - setSelectionsWithoutFocusingEditor(editor, updatedCursorSelections); + setSelectionsWithoutFocusingEditor( + editableEditor, + updatedCursorSelections, + ); return { thatMark: updatedThatSelections.map((selection) => ({ @@ -70,8 +76,8 @@ class InsertEmptyLines implements Action { range: ranges[index].start.line < editor.document.lineCount - 1 ? new Range( - selection.start.translate({ lineDelta: -1 }), - selection.end.translate({ lineDelta: -1 }), + selection.start.translate(-1, undefined), + selection.end.translate(-1, undefined), ) : selection, })), diff --git a/src/actions/MakeshiftActions.ts b/src/actions/MakeshiftActions.ts index 46ae210605..f831eb4ab3 100644 --- a/src/actions/MakeshiftActions.ts +++ b/src/actions/MakeshiftActions.ts @@ -1,5 +1,5 @@ -import { Target } from "../typings/target.types"; import sleep from "../libs/common/util/sleep"; +import { Target } from "../typings/target.types"; import CommandAction from "./CommandAction"; abstract class MakeshiftAction extends CommandAction { diff --git a/src/actions/Paste.ts b/src/actions/Paste.ts index 4fba022341..822b1576f2 100644 --- a/src/actions/Paste.ts +++ b/src/actions/Paste.ts @@ -3,22 +3,19 @@ import { callFunctionAndUpdateSelections, callFunctionAndUpdateSelectionsWithBehavior, } from "../core/updateSelections/updateSelections"; +import ide from "../libs/cursorless-engine/singletons/ide.singleton"; import { Target } from "../typings/target.types"; import { Graph } from "../typings/Types"; -import { - focusEditor, - setSelectionsWithoutFocusingEditor, -} from "../util/setSelectionsAndFocusEditor"; +import { setSelectionsWithoutFocusingEditor } from "../util/setSelectionsAndFocusEditor"; import { ensureSingleEditor } from "../util/targetUtils"; import { ActionReturnValue } from "./actions.types"; -import { getActiveTextEditor } from "../ide/vscode/activeTextEditor"; export class Paste { constructor(private graph: Graph) {} async run([targets]: [Target[]]): Promise { const targetEditor = ensureSingleEditor(targets); - const originalEditor = getActiveTextEditor(); + const originalEditor = ide().activeEditableTextEditor; // First call editNew in order to insert delimiters if necessary and leave // the cursor in the right position. Note that this action will focus the @@ -53,14 +50,17 @@ export class Paste { // Reset cursors on the editor where the edits took place. // NB: We don't focus the editor here because we want to focus the original // editor, not the one where the edits took place - setSelectionsWithoutFocusingEditor(targetEditor, updatedCursorSelections); + setSelectionsWithoutFocusingEditor( + ide().getEditableTextEditor(targetEditor), + updatedCursorSelections, + ); // If necessary focus back original editor - if (originalEditor != null && originalEditor !== getActiveTextEditor()) { + if (originalEditor != null && !originalEditor.isActive) { // NB: We just do one editor focus at the end, instead of using // setSelectionsAndFocusEditor because the command might operate on // multiple editors, so we just do one focus at the end. - await focusEditor(originalEditor); + await originalEditor.focus(); } this.graph.editStyles.displayPendingEditDecorationsForRanges( diff --git a/src/actions/Remove.ts b/src/actions/Remove.ts index 43f5b3c956..cad0b984a7 100644 --- a/src/actions/Remove.ts +++ b/src/actions/Remove.ts @@ -1,5 +1,6 @@ import { flatten } from "lodash"; import { performEditsAndUpdateRanges } from "../core/updateSelections/updateSelections"; +import ide from "../libs/cursorless-engine/singletons/ide.singleton"; import { Target } from "../typings/target.types"; import { Graph } from "../typings/Types"; import { createThatMark, runOnTargetsForEachEditor } from "../util/targetUtils"; @@ -33,7 +34,7 @@ export default class Delete implements Action { const [updatedRanges] = await performEditsAndUpdateRanges( this.graph.rangeUpdater, - editor, + ide().getEditableTextEditor(editor), edits, [ranges], ); diff --git a/src/actions/Replace.ts b/src/actions/Replace.ts index c6a8a60226..5311ac3868 100644 --- a/src/actions/Replace.ts +++ b/src/actions/Replace.ts @@ -1,5 +1,6 @@ import { flatten, zip } from "lodash"; import { performEditsAndUpdateSelections } from "../core/updateSelections/updateSelections"; +import ide from "../libs/cursorless-engine/singletons/ide.singleton"; import { Target } from "../typings/target.types"; import { Graph } from "../typings/Types"; import { runForEachEditor } from "../util/targetUtils"; @@ -57,7 +58,7 @@ export default class Replace implements Action { async (editor, edits) => { const [updatedSelections] = await performEditsAndUpdateSelections( this.graph.rangeUpdater, - editor, + ide().getEditableTextEditor(editor), edits.map(({ edit }) => edit), [targets.map((target) => target.contentSelection)], ); diff --git a/src/actions/Rewrap.ts b/src/actions/Rewrap.ts index 046d4d5d62..181f1a176c 100644 --- a/src/actions/Rewrap.ts +++ b/src/actions/Rewrap.ts @@ -1,4 +1,5 @@ import { performEditsAndUpdateRanges } from "../core/updateSelections/updateSelections"; +import ide from "../libs/cursorless-engine/singletons/ide.singleton"; import { containingSurroundingPairIfUntypedStage } from "../processTargets/modifiers/commonContainingScopeIfUntypedStages"; import { Target } from "../typings/target.types"; import { Graph } from "../typings/Types"; @@ -44,7 +45,7 @@ export default class Rewrap implements Action { const [updatedSourceRanges, updatedThatRanges] = await performEditsAndUpdateRanges( this.graph.rangeUpdater, - editor, + ide().getEditableTextEditor(editor), edits, [ targets.map((target) => target.thatTarget.contentRange), diff --git a/src/actions/Scroll.ts b/src/actions/Scroll.ts index 8eb447ec0b..d5cbd7cadb 100644 --- a/src/actions/Scroll.ts +++ b/src/actions/Scroll.ts @@ -1,10 +1,9 @@ import { commands } from "vscode"; +import ide from "../libs/cursorless-engine/singletons/ide.singleton"; import { Target } from "../typings/target.types"; import { Graph } from "../typings/Types"; import { groupBy } from "../util/itertools"; -import { focusEditor } from "../util/setSelectionsAndFocusEditor"; import { Action, ActionReturnValue } from "./actions.types"; -import { getActiveTextEditor } from "../ide/vscode/activeTextEditor"; class Scroll implements Action { constructor(private graph: Graph, private at: string) { @@ -18,12 +17,12 @@ class Scroll implements Action { return { lineNumber: getLineNumber(targets, this.at), editor }; }); - const originalEditor = getActiveTextEditor(); + const originalEditor = ide().activeEditableTextEditor; for (const lineWithEditor of lines) { // For reveal line to the work we have to have the correct editor focused - if (lineWithEditor.editor !== getActiveTextEditor()) { - await focusEditor(lineWithEditor.editor); + if (!lineWithEditor.editor.isActive) { + await ide().getEditableTextEditor(lineWithEditor.editor).focus(); } await commands.executeCommand("revealLine", { lineNumber: lineWithEditor.lineNumber, @@ -32,8 +31,8 @@ class Scroll implements Action { } // If necessary focus back original editor - if (originalEditor != null && originalEditor !== getActiveTextEditor()) { - await focusEditor(originalEditor); + if (originalEditor != null && !originalEditor.isActive) { + await originalEditor.focus(); } const decorationTargets = targets.filter((target) => { diff --git a/src/actions/SetSelection.ts b/src/actions/SetSelection.ts index 284a94f858..fb7b6b9039 100644 --- a/src/actions/SetSelection.ts +++ b/src/actions/SetSelection.ts @@ -1,4 +1,5 @@ -import { Selection } from "vscode"; +import { Selection } from "@cursorless/common"; +import ide from "../libs/cursorless-engine/singletons/ide.singleton"; import { Target } from "../typings/target.types"; import { Graph } from "../typings/Types"; import { setSelectionsAndFocusEditor } from "../util/setSelectionsAndFocusEditor"; @@ -18,7 +19,10 @@ export class SetSelection implements Action { const editor = ensureSingleEditor(targets); const selections = targets.map(this.getSelection); - await setSelectionsAndFocusEditor(editor, selections); + await setSelectionsAndFocusEditor( + ide().getEditableTextEditor(editor), + selections, + ); return { thatTargets: targets, diff --git a/src/actions/ToggleBreakpoint.ts b/src/actions/ToggleBreakpoint.ts index 0bf1752639..58d66725fd 100644 --- a/src/actions/ToggleBreakpoint.ts +++ b/src/actions/ToggleBreakpoint.ts @@ -1,20 +1,15 @@ -import { - Breakpoint, - debug, - Location, - Range, - SourceBreakpoint, - Uri, -} from "vscode"; +import { toVscodeRange } from "@cursorless/vscode-common"; +import * as vscode from "vscode"; +import { URI } from "vscode-uri"; import { containingLineIfUntypedStage } from "../processTargets/modifiers/commonContainingScopeIfUntypedStages"; import { Target } from "../typings/target.types"; import { Graph } from "../typings/Types"; import { Action, ActionReturnValue } from "./actions.types"; -function getBreakpoints(uri: Uri, range: Range) { - return debug.breakpoints.filter( +function getBreakpoints(uri: URI, range: vscode.Range) { + return vscode.debug.breakpoints.filter( (breakpoint) => - breakpoint instanceof SourceBreakpoint && + breakpoint instanceof vscode.SourceBreakpoint && breakpoint.location.uri.toString() === uri.toString() && breakpoint.location.range.intersection(range) != null, ); @@ -35,11 +30,11 @@ export default class ToggleBreakpoint implements Action { this.graph.editStyles.referenced, ); - const toAdd: Breakpoint[] = []; - const toRemove: Breakpoint[] = []; + const toAdd: vscode.Breakpoint[] = []; + const toRemove: vscode.Breakpoint[] = []; targets.forEach((target) => { - let range = target.contentRange; + let range = toVscodeRange(target.contentRange); // The action preference give us line content but line breakpoints are registered on character 0 if (target.isLine) { range = range.with(range.start.with(undefined, 0), undefined); @@ -52,12 +47,14 @@ export default class ToggleBreakpoint implements Action { if (target.isLine) { range = range.with(undefined, range.end.with(undefined, 0)); } - toAdd.push(new SourceBreakpoint(new Location(uri, range))); + toAdd.push( + new vscode.SourceBreakpoint(new vscode.Location(uri, range)), + ); } }); - debug.addBreakpoints(toAdd); - debug.removeBreakpoints(toRemove); + vscode.debug.addBreakpoints(toAdd); + vscode.debug.removeBreakpoints(toRemove); return { thatTargets: targets, diff --git a/src/actions/Wrap.ts b/src/actions/Wrap.ts index d8551cee06..f702a07cea 100644 --- a/src/actions/Wrap.ts +++ b/src/actions/Wrap.ts @@ -1,8 +1,10 @@ -import { DecorationRangeBehavior, Selection } from "vscode"; +import { Selection } from "@cursorless/common"; +import { DecorationRangeBehavior } from "vscode"; import { getSelectionInfo, performEditsAndUpdateFullSelectionInfos, } from "../core/updateSelections/updateSelections"; +import ide from "../libs/cursorless-engine/singletons/ide.singleton"; import { Target } from "../typings/target.types"; import { Edit, Graph } from "../typings/Types"; import { FullSelectionInfo } from "../typings/updateSelections"; @@ -85,6 +87,8 @@ export default class Wrap implements Action { ), ); + const editableEditor = ide().getEditableTextEditor(editor); + const [ delimiterSelections, cursorSelections, @@ -92,7 +96,7 @@ export default class Wrap implements Action { thatMarkSelections, ] = await performEditsAndUpdateFullSelectionInfos( this.graph.rangeUpdater, - editor, + editableEditor, edits, [ delimiterSelectionInfos, @@ -102,7 +106,7 @@ export default class Wrap implements Action { ], ); - setSelectionsWithoutFocusingEditor(editor, cursorSelections); + setSelectionsWithoutFocusingEditor(editableEditor, cursorSelections); this.graph.editStyles.displayPendingEditDecorationsForRanges( delimiterSelections.map((selection) => ({ diff --git a/src/actions/actions.types.ts b/src/actions/actions.types.ts index 01c142e5b1..ac84d64dbb 100644 --- a/src/actions/actions.types.ts +++ b/src/actions/actions.types.ts @@ -1,6 +1,6 @@ -import { ModifierStage } from "../processTargets/PipelineStages.types"; -import { Target } from "../typings/target.types"; -import { SelectionWithEditor } from "../typings/Types"; +import type { ModifierStage } from "../processTargets/PipelineStages.types"; +import type { Target } from "../typings/target.types"; +import type { SelectionWithEditor } from "../typings/Types"; export type ActionType = | "callAsFunction" diff --git a/src/apps/cursorless-vscode-e2e/suite/backwardCompatibility.test.ts b/src/apps/cursorless-vscode-e2e/suite/backwardCompatibility.test.ts index 6c79a7bf3c..cc315b63be 100644 --- a/src/apps/cursorless-vscode-e2e/suite/backwardCompatibility.test.ts +++ b/src/apps/cursorless-vscode-e2e/suite/backwardCompatibility.test.ts @@ -1,8 +1,7 @@ import { CURSORLESS_COMMAND_ID } from "@cursorless/common"; -import { getCursorlessApi } from "@cursorless/vscode-common"; +import { getCursorlessApi, openNewEditor } from "@cursorless/vscode-common"; import * as assert from "assert"; import * as vscode from "vscode"; -import { openNewEditor } from "../openNewEditor"; import { endToEndTestSetup } from "../endToEndTestSetup"; suite("Backward compatibility", async function () { diff --git a/src/apps/cursorless-vscode-e2e/suite/breakpoints.test.ts b/src/apps/cursorless-vscode-e2e/suite/breakpoints.test.ts index 0f3d1bbb16..f3424f6794 100644 --- a/src/apps/cursorless-vscode-e2e/suite/breakpoints.test.ts +++ b/src/apps/cursorless-vscode-e2e/suite/breakpoints.test.ts @@ -1,9 +1,8 @@ -import { getCursorlessApi } from "@cursorless/vscode-common"; +import { getCursorlessApi, openNewEditor } from "@cursorless/vscode-common"; import * as assert from "assert"; import * as vscode from "vscode"; -import { openNewEditor } from "../openNewEditor"; -import { runCursorlessCommand } from "../runCommand"; import { endToEndTestSetup } from "../endToEndTestSetup"; +import { runCursorlessCommand } from "../runCommand"; suite("breakpoints", async function () { endToEndTestSetup(this); diff --git a/src/apps/cursorless-vscode-e2e/suite/containingTokenTwice.test.ts b/src/apps/cursorless-vscode-e2e/suite/containingTokenTwice.test.ts index 37852a15ab..2f815e211d 100644 --- a/src/apps/cursorless-vscode-e2e/suite/containingTokenTwice.test.ts +++ b/src/apps/cursorless-vscode-e2e/suite/containingTokenTwice.test.ts @@ -1,9 +1,8 @@ -import { getCursorlessApi } from "@cursorless/vscode-common"; +import { getCursorlessApi, openNewEditor } from "@cursorless/vscode-common"; import { assert } from "chai"; import * as vscode from "vscode"; -import { openNewEditor } from "../openNewEditor"; -import { runCursorlessCommand } from "../runCommand"; import { endToEndTestSetup } from "../endToEndTestSetup"; +import { runCursorlessCommand } from "../runCommand"; // Check that we don't run afoul of stateful regex craziness // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec#finding_successive_matches diff --git a/src/apps/cursorless-vscode-e2e/suite/crossCellsSetSelection.test.ts b/src/apps/cursorless-vscode-e2e/suite/crossCellsSetSelection.test.ts index b6368ee054..ff06d86bb7 100644 --- a/src/apps/cursorless-vscode-e2e/suite/crossCellsSetSelection.test.ts +++ b/src/apps/cursorless-vscode-e2e/suite/crossCellsSetSelection.test.ts @@ -1,9 +1,11 @@ -import { getCursorlessApi } from "@cursorless/vscode-common"; +import { + getCursorlessApi, + openNewNotebookEditor, +} from "@cursorless/vscode-common"; import * as assert from "assert"; import { window } from "vscode"; -import { openNewNotebookEditor } from "../openNewEditor"; +import { endToEndTestSetup, sleepWithBackoff } from "../endToEndTestSetup"; import { runCursorlessCommand } from "../runCommand"; -import { sleepWithBackoff, endToEndTestSetup } from "../endToEndTestSetup"; // Check that setSelection is able to focus the correct cell suite("Cross-cell set selection", async function () { diff --git a/src/apps/cursorless-vscode-e2e/suite/editNewCell.test.ts b/src/apps/cursorless-vscode-e2e/suite/editNewCell.test.ts index 4f69941337..b2d86d9749 100644 --- a/src/apps/cursorless-vscode-e2e/suite/editNewCell.test.ts +++ b/src/apps/cursorless-vscode-e2e/suite/editNewCell.test.ts @@ -1,10 +1,13 @@ -import { getCellIndex, getCursorlessApi } from "@cursorless/vscode-common"; +import { + getCellIndex, + getCursorlessApi, + openNewNotebookEditor, +} from "@cursorless/vscode-common"; import * as assert from "assert"; import { window } from "vscode"; +import { endToEndTestSetup, sleepWithBackoff } from "../endToEndTestSetup"; import { getPlainNotebookContents } from "../notebook"; -import { openNewNotebookEditor } from "../openNewEditor"; import { runCursorlessCommand } from "../runCommand"; -import { sleepWithBackoff, endToEndTestSetup } from "../endToEndTestSetup"; // Check that setSelection is able to focus the correct cell suite("Edit new cell", async function () { diff --git a/src/apps/cursorless-vscode-e2e/suite/fold.test.ts b/src/apps/cursorless-vscode-e2e/suite/fold.test.ts index d352ea0913..b43cc88d4e 100644 --- a/src/apps/cursorless-vscode-e2e/suite/fold.test.ts +++ b/src/apps/cursorless-vscode-e2e/suite/fold.test.ts @@ -1,8 +1,8 @@ import * as assert from "assert"; import * as vscode from "vscode"; -import { openNewEditor } from "../openNewEditor"; -import { runCursorlessCommand } from "../runCommand"; +import { openNewEditor } from "@cursorless/vscode-common"; import { endToEndTestSetup } from "../endToEndTestSetup"; +import { runCursorlessCommand } from "../runCommand"; suite("fold", async function () { endToEndTestSetup(this); diff --git a/src/apps/cursorless-vscode-e2e/suite/followLink.test.ts b/src/apps/cursorless-vscode-e2e/suite/followLink.test.ts index 5910ef50b5..3b02ca822c 100644 --- a/src/apps/cursorless-vscode-e2e/suite/followLink.test.ts +++ b/src/apps/cursorless-vscode-e2e/suite/followLink.test.ts @@ -1,10 +1,10 @@ +import { openNewEditor } from "@cursorless/vscode-common"; import * as assert from "assert"; import * as os from "os"; import * as vscode from "vscode"; +import { endToEndTestSetup } from "../endToEndTestSetup"; import { getFixturePath } from "../getFixturePaths"; -import { openNewEditor } from "../openNewEditor"; import { runCursorlessCommand } from "../runCommand"; -import { endToEndTestSetup } from "../endToEndTestSetup"; suite("followLink", async function () { endToEndTestSetup(this); diff --git a/src/apps/cursorless-vscode-e2e/suite/groupByDocument.test.ts b/src/apps/cursorless-vscode-e2e/suite/groupByDocument.test.ts index e857c84694..1c34f811dd 100644 --- a/src/apps/cursorless-vscode-e2e/suite/groupByDocument.test.ts +++ b/src/apps/cursorless-vscode-e2e/suite/groupByDocument.test.ts @@ -1,9 +1,9 @@ -import { getCursorlessApi } from "@cursorless/vscode-common"; +import { splitKey } from "@cursorless/common"; +import { getCursorlessApi, toVscodeEditor } from "@cursorless/vscode-common"; import * as assert from "assert"; import * as vscode from "vscode"; -import { splitKey } from "@cursorless/common"; -import { runCursorlessCommand } from "../runCommand"; import { endToEndTestSetup } from "../endToEndTestSetup"; +import { runCursorlessCommand } from "../runCommand"; suite("Group by document", async function () { endToEndTestSetup(this); @@ -32,10 +32,16 @@ async function runTest() { const hat1 = hatMap .getEntries() - .find(([, token]) => token.editor === editor1 && token.text === "hello"); + .find( + ([, token]) => + toVscodeEditor(token.editor) === editor1 && token.text === "hello", + ); const hat2 = hatMap .getEntries() - .find(([, token]) => token.editor === editor2 && token.text === "world"); + .find( + ([, token]) => + toVscodeEditor(token.editor) === editor2 && token.text === "world", + ); const { hatStyle: hatStyle1, character: char1 } = splitKey(hat1![0]); const { hatStyle: hatStyle2, character: char2 } = splitKey(hat2![0]); diff --git a/src/apps/cursorless-vscode-e2e/suite/intraCellSetSelection.test.ts b/src/apps/cursorless-vscode-e2e/suite/intraCellSetSelection.test.ts index 2aca92e2c7..a6c45e5c85 100644 --- a/src/apps/cursorless-vscode-e2e/suite/intraCellSetSelection.test.ts +++ b/src/apps/cursorless-vscode-e2e/suite/intraCellSetSelection.test.ts @@ -1,9 +1,11 @@ -import { getCursorlessApi } from "@cursorless/vscode-common"; +import { + getCursorlessApi, + openNewNotebookEditor, +} from "@cursorless/vscode-common"; import * as assert from "assert"; import { window } from "vscode"; -import { openNewNotebookEditor } from "../openNewEditor"; +import { endToEndTestSetup, sleepWithBackoff } from "../endToEndTestSetup"; import { runCursorlessCommand } from "../runCommand"; -import { sleepWithBackoff, endToEndTestSetup } from "../endToEndTestSetup"; // Check that setSelection is able to focus the correct cell suite("Within cell set selection", async function () { diff --git a/src/apps/cursorless-vscode-e2e/suite/prePhraseSnapshot.test.ts b/src/apps/cursorless-vscode-e2e/suite/prePhraseSnapshot.test.ts index ab2379a147..1a6c466005 100644 --- a/src/apps/cursorless-vscode-e2e/suite/prePhraseSnapshot.test.ts +++ b/src/apps/cursorless-vscode-e2e/suite/prePhraseSnapshot.test.ts @@ -1,13 +1,14 @@ import { + fromVscodeSelection, getCursorlessApi, + openNewEditor, selectionToPlainObject, } from "@cursorless/vscode-common"; import * as assert from "assert"; import * as vscode from "vscode"; +import { endToEndTestSetup } from "../endToEndTestSetup"; import { mockPrePhraseGetVersion } from "../mockPrePhraseGetVersion"; -import { openNewEditor } from "../openNewEditor"; import { runCursorlessCommand } from "../runCommand"; -import { endToEndTestSetup } from "../endToEndTestSetup"; /** * The selections we expect when the pre-phrase snapshot is used @@ -89,7 +90,7 @@ async function runTest( }); assert.deepStrictEqual( - editor.selections.map(selectionToPlainObject), - expectedSelections.map(selectionToPlainObject), + editor.selections.map(fromVscodeSelection).map(selectionToPlainObject), + expectedSelections.map(fromVscodeSelection).map(selectionToPlainObject), ); } diff --git a/src/apps/cursorless-vscode-e2e/suite/recorded.test.ts b/src/apps/cursorless-vscode-e2e/suite/recorded.test.ts index c39a627216..710ba64ce6 100644 --- a/src/apps/cursorless-vscode-e2e/suite/recorded.test.ts +++ b/src/apps/cursorless-vscode-e2e/suite/recorded.test.ts @@ -1,34 +1,34 @@ +import type { SpyIDE } from "@cursorless/common"; +import { + extractTargetedMarks, + FakeIDE, + serialize, + splitKey, +} from "@cursorless/common"; import { + DEFAULT_TEXT_EDITOR_OPTIONS_FOR_TEST, + ExcludableSnapshotField, getCursorlessApi, marksToPlainObject, + openNewEditor, PositionPlainObject, rangeToPlainObject, SelectionPlainObject, SerializedMarks, - testDecorationsToPlainObject, - DEFAULT_TEXT_EDITOR_OPTIONS_FOR_TEST, - ExcludableSnapshotField, takeSnapshot, + testDecorationsToPlainObject, } from "@cursorless/vscode-common"; -import { - serialize, - splitKey, - extractTargetedMarks, - FakeIDE, -} from "@cursorless/common"; import { assert } from "chai"; import { promises as fsp } from "fs"; import * as yaml from "js-yaml"; import * as vscode from "vscode"; import type { ReadOnlyHatMap } from "../../../core/IndividualHatMap"; -import type { SpyIDE } from "@cursorless/common"; import type { TestCaseFixture } from "../../../testUtil/TestCaseFixture"; import asyncSafety from "../asyncSafety"; +import { endToEndTestSetup, sleepWithBackoff } from "../endToEndTestSetup"; import { getFixturePath, getRecordedTestPaths } from "../getFixturePaths"; -import { openNewEditor } from "../openNewEditor"; import { runCursorlessCommand } from "../runCommand"; import shouldUpdateFixtures from "../shouldUpdateFixtures"; -import { sleepWithBackoff, endToEndTestSetup } from "../endToEndTestSetup"; function createPosition(position: PositionPlainObject) { return new vscode.Position(position.line, position.character); @@ -177,7 +177,7 @@ async function runTest(file: string, spyIde: SpyIDE) { cursorlessApi.sourceMark, excludeFields, [], - vscode.window.activeTextEditor!, // eslint-disable-line no-restricted-properties + spyIde.activeTextEditor!, spyIde, marks, undefined, diff --git a/src/apps/cursorless-vscode-e2e/suite/scroll.test.ts b/src/apps/cursorless-vscode-e2e/suite/scroll.test.ts index d24e07dd90..b1d09bb92f 100644 --- a/src/apps/cursorless-vscode-e2e/suite/scroll.test.ts +++ b/src/apps/cursorless-vscode-e2e/suite/scroll.test.ts @@ -1,8 +1,8 @@ +import { openNewEditor } from "@cursorless/vscode-common"; import * as assert from "assert"; import * as vscode from "vscode"; -import { openNewEditor } from "../openNewEditor"; -import { runCursorlessCommand } from "../runCommand"; import { endToEndTestSetup } from "../endToEndTestSetup"; +import { runCursorlessCommand } from "../runCommand"; suite("scroll", async function () { endToEndTestSetup(this); diff --git a/src/apps/cursorless-vscode-e2e/suite/toggleDecorations.test.ts b/src/apps/cursorless-vscode-e2e/suite/toggleDecorations.test.ts index 9b6cd63472..c01a709d6b 100644 --- a/src/apps/cursorless-vscode-e2e/suite/toggleDecorations.test.ts +++ b/src/apps/cursorless-vscode-e2e/suite/toggleDecorations.test.ts @@ -1,7 +1,6 @@ -import { getCursorlessApi } from "@cursorless/vscode-common"; +import { getCursorlessApi, openNewEditor } from "@cursorless/vscode-common"; import * as assert from "assert"; import * as vscode from "vscode"; -import { openNewEditor } from "../openNewEditor"; import { endToEndTestSetup } from "../endToEndTestSetup"; suite("toggle decorations", async function () { diff --git a/src/apps/cursorless-vscode/getMatchesInRange.ts b/src/apps/cursorless-vscode/getMatchesInRange.ts index 4b19c302b5..324e6bedb4 100644 --- a/src/apps/cursorless-vscode/getMatchesInRange.ts +++ b/src/apps/cursorless-vscode/getMatchesInRange.ts @@ -1,7 +1,7 @@ +import { Range, TextEditor } from "@cursorless/common"; import { imap } from "itertools"; -import { Range, TextEditor } from "vscode"; -import { Direction } from "../../typings/targetDescriptor.types"; import { matchAll } from "../../libs/cursorless-engine/util/regex"; +import { Direction } from "../../typings/targetDescriptor.types"; export function getMatchesInRange( regex: RegExp, diff --git a/src/core/Debug.ts b/src/core/Debug.ts index 4716f771ae..7e0b5db811 100644 --- a/src/core/Debug.ts +++ b/src/core/Debug.ts @@ -1,6 +1,6 @@ +import { fromVscodeRange } from "@cursorless/vscode-common"; import { Disposable, - Location, TextEditorSelectionChangeEvent, window, workspace, @@ -8,7 +8,6 @@ import { import { SyntaxNode, TreeCursor } from "web-tree-sitter"; import ide from "../libs/cursorless-engine/singletons/ide.singleton"; import { Graph } from "../typings/Types"; -import { getActiveTextEditor } from "../ide/vscode/activeTextEditor"; export default class Debug { private disposableConfiguration?: Disposable; @@ -87,14 +86,12 @@ export default class Debug { } private logBranchTypes(event: TextEditorSelectionChangeEvent) { - const location = new Location( - getActiveTextEditor()!.document.uri, - event.selections[0], - ); - let node: SyntaxNode; try { - node = this.graph.getNodeAtLocation(location); + node = this.graph.getNodeAtLocation( + ide().activeTextEditor!.document, + fromVscodeRange(event.selections[0]), + ); } catch (error) { return; } diff --git a/src/core/IndividualHatMap.ts b/src/core/IndividualHatMap.ts index 4ab9fe6d7b..1345515d4d 100644 --- a/src/core/IndividualHatMap.ts +++ b/src/core/IndividualHatMap.ts @@ -1,5 +1,4 @@ -import { getKey } from "@cursorless/common"; -import { TextDocument } from "vscode"; +import { getKey, TextDocument } from "@cursorless/common"; import tokenGraphemeSplitter from "../libs/cursorless-engine/singletons/tokenGraphemeSplitter.singleton"; import { Graph, Token } from "../typings/Types"; import { HatStyleName } from "./hatStyles"; diff --git a/src/core/commandRunner/CommandRunner.ts b/src/core/commandRunner/CommandRunner.ts index 26f62ef8a1..dcc82a9dea 100644 --- a/src/core/commandRunner/CommandRunner.ts +++ b/src/core/commandRunner/CommandRunner.ts @@ -1,9 +1,8 @@ import * as vscode from "vscode"; import { ActionType } from "../../actions/actions.types"; -import { CURSORLESS_COMMAND_ID } from "../../libs/common/commandIds"; import { OutdatedExtensionError } from "../../errors"; +import { CURSORLESS_COMMAND_ID } from "../../libs/common/commandIds"; import ide from "../../libs/cursorless-engine/singletons/ide.singleton"; -import { getActiveTextEditor } from "../../ide/vscode/activeTextEditor"; import processTargets from "../../processTargets"; import isTesting from "../../testUtil/isTesting"; import { Target } from "../../typings/target.types"; @@ -114,11 +113,11 @@ export default class CommandRunner { actionPrePositionStages, actionFinalStages, currentSelections: - getActiveTextEditor()?.selections.map((selection) => ({ + ide().activeTextEditor?.selections.map((selection) => ({ selection, - editor: getActiveTextEditor()!, + editor: ide().activeTextEditor!, })) ?? [], - currentEditor: getActiveTextEditor(), + currentEditor: ide().activeTextEditor, hatTokenMap: readableHatMap, thatMark: this.thatMark.exists() ? this.thatMark.get() : [], sourceMark: this.sourceMark.exists() ? this.sourceMark.get() : [], diff --git a/src/core/commandRunner/selectionToThatTarget.ts b/src/core/commandRunner/selectionToThatTarget.ts index 7c41c01ad0..52e1cccc1d 100644 --- a/src/core/commandRunner/selectionToThatTarget.ts +++ b/src/core/commandRunner/selectionToThatTarget.ts @@ -1,6 +1,5 @@ import { UntypedTarget } from "../../processTargets/targets"; import { SelectionWithEditor } from "../../typings/Types"; -import { isReversed } from "../../util/selectionUtils"; /** * Given a selection with an editor, constructs an appropriate `Target` to use @@ -13,7 +12,7 @@ import { isReversed } from "../../util/selectionUtils"; export const selectionToThatTarget = (selection: SelectionWithEditor) => new UntypedTarget({ editor: selection.editor, - isReversed: isReversed(selection.selection), + isReversed: selection.selection.isReversed, contentRange: selection.selection, hasExplicitRange: !selection.selection.isEmpty, }); diff --git a/src/core/editStyles.ts b/src/core/editStyles.ts index b8da397529..c3792493b7 100644 --- a/src/core/editStyles.ts +++ b/src/core/editStyles.ts @@ -1,19 +1,17 @@ +import { EditableTextEditor, Position, Range } from "@cursorless/common"; import { DecorationRangeBehavior, DecorationRenderOptions, - Position, - Range, - TextEditor, TextEditorDecorationType, ThemeColor, window, workspace, } from "vscode"; +import sleep from "../libs/common/util/sleep"; import ide from "../libs/cursorless-engine/singletons/ide.singleton"; import isTesting from "../testUtil/isTesting"; import { Target } from "../typings/target.types"; import { Graph, RangeWithEditor } from "../typings/Types"; -import sleep from "../libs/common/util/sleep"; import { getContentRange, runForEachEditor, @@ -123,7 +121,7 @@ export class EditStyles implements Record { (range) => range.editor, async (editor, ranges) => { this.setEditorDecorations( - editor, + ide().getEditableTextEditor(editor), style, isToken, ranges.map((range) => range.range), @@ -137,7 +135,9 @@ export class EditStyles implements Record { ranges, (range) => range.editor, async (editor) => { - editor.setDecorations(style.getDecoration(isToken), []); + ide() + .getEditableTextEditor(editor) + .setDecorations(style.getDecoration(isToken), []); }, ); } @@ -149,7 +149,7 @@ export class EditStyles implements Record { ) { return runOnTargetsForEachEditor(targets, async (editor, targets) => { this.setEditorDecorations( - editor, + ide().getEditableTextEditor(editor), style, true, targets @@ -158,7 +158,7 @@ export class EditStyles implements Record { .filter((range): range is Range => !!range), ); this.setEditorDecorations( - editor, + ide().getEditableTextEditor(editor), style, false, targets @@ -177,7 +177,7 @@ export class EditStyles implements Record { } private setEditorDecorations( - editor: TextEditor, + editor: EditableTextEditor, style: EditStyle, isToken: boolean, ranges: Range[], diff --git a/src/core/updateSelections/RangeUpdater.ts b/src/core/updateSelections/RangeUpdater.ts index 678ff97844..ddd2e70cd6 100644 --- a/src/core/updateSelections/RangeUpdater.ts +++ b/src/core/updateSelections/RangeUpdater.ts @@ -1,12 +1,12 @@ +import type { TextDocument } from "@cursorless/common"; import { pull } from "lodash"; -import { - workspace, - TextDocument, +import type { TextDocumentChangeEvent, - Disposable, TextDocumentContentChangeEvent, -} from "vscode"; -import { Edit } from "../../typings/Types"; +} from "../../libs/common/ide/types/Events"; +import type { Disposable } from "../../libs/common/ide/types/ide.types"; +import ide from "../../libs/cursorless-engine/singletons/ide.singleton"; +import type { Edit } from "../../typings/Types"; import { ExtendedTextDocumentChangeEvent, FullRangeInfo, @@ -90,7 +90,7 @@ export class RangeUpdater { } private listenForDocumentChanges() { - this.disposable = workspace.onDidChangeTextDocument( + this.disposable = ide().onDidChangeTextDocument( (event: TextDocumentChangeEvent) => { const documentReplaceEditLists = this.getDocumentReplaceEditLists( event.document, @@ -128,7 +128,7 @@ function isReplace( for (const replaceEditLists of documentReplaceEditLists) { for (const replaceEdit of replaceEditLists) { if ( - replaceEdit.range.isEqual(change.range) && + replaceEdit.range.isRangeEqual(change.range) && replaceEdit.text === change.text ) { return true; diff --git a/src/core/updateSelections/updateSelections.ts b/src/core/updateSelections/updateSelections.ts index 3701f190c5..77d879a319 100644 --- a/src/core/updateSelections/updateSelections.ts +++ b/src/core/updateSelections/updateSelections.ts @@ -1,18 +1,17 @@ -import { flatten } from "lodash"; import { - DecorationRangeBehavior, + EditableTextEditor, Range, Selection, TextDocument, - TextEditor, -} from "vscode"; +} from "@cursorless/common"; +import { flatten } from "lodash"; +import { DecorationRangeBehavior } from "vscode"; import { Edit } from "../../typings/Types"; import { FullSelectionInfo, SelectionInfo, } from "../../typings/updateSelections"; import { performDocumentEdits } from "../../util/performDocumentEdits"; -import { isForward } from "../../util/selectionUtils"; import { RangeUpdater } from "./RangeUpdater"; interface SelectionsWithBehavior { @@ -37,7 +36,7 @@ export function getSelectionInfo( return getSelectionInfoInternal( document, selection, - isForward(selection), + !selection.isReversed, rangeBehavior, ); } @@ -250,7 +249,7 @@ export function callFunctionAndUpdateSelectionsWithBehavior( */ export async function performEditsAndUpdateSelections( rangeUpdater: RangeUpdater, - editor: TextEditor, + editor: EditableTextEditor, edits: Edit[], originalSelections: (readonly Selection[])[], ) { @@ -279,7 +278,7 @@ export async function performEditsAndUpdateSelections( */ export function performEditsAndUpdateSelectionsWithBehavior( rangeUpdater: RangeUpdater, - editor: TextEditor, + editor: EditableTextEditor, edits: Edit[], originalSelections: SelectionsWithBehavior[], ) { @@ -302,7 +301,7 @@ export function performEditsAndUpdateSelectionsWithBehavior( export async function performEditsAndUpdateRanges( rangeUpdater: RangeUpdater, - editor: TextEditor, + editor: EditableTextEditor, edits: Edit[], originalRanges: (readonly Range[])[], ): Promise { @@ -318,7 +317,7 @@ export async function performEditsAndUpdateRanges( async function performEditsAndUpdateInternal( rangeUpdater: RangeUpdater, - editor: TextEditor, + editor: EditableTextEditor, edits: Edit[], selectionInfoMatrix: FullSelectionInfo[][], ) { @@ -334,7 +333,7 @@ async function performEditsAndUpdateInternal( // TODO: Remove this function if we don't end up using it for the next couple use cases, eg `that` mark and cursor history export async function performEditsAndUpdateSelectionInfos( rangeUpdater: RangeUpdater, - editor: TextEditor, + editor: EditableTextEditor, edits: Edit[], originalSelectionInfos: SelectionInfo[][], ): Promise { @@ -359,7 +358,7 @@ export async function performEditsAndUpdateSelectionInfos( */ export async function performEditsAndUpdateFullSelectionInfos( rangeUpdater: RangeUpdater, - editor: TextEditor, + editor: EditableTextEditor, edits: Edit[], originalSelectionInfos: FullSelectionInfo[][], ): Promise { diff --git a/src/extension.ts b/src/extension.ts index dc163b274a..cc3ecb1166 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,3 +1,5 @@ +import { Range, TextDocument } from "@cursorless/common"; +import { toVscodeRange } from "@cursorless/vscode-common"; import * as vscode from "vscode"; import CommandRunner from "./core/commandRunner/CommandRunner"; import { ThatMark } from "./core/ThatMark"; @@ -11,6 +13,7 @@ import { getCommandServerApi, getParseTreeApi, } from "./libs/vscode-common/getExtensionApi"; +import { TargetPlainObject } from "./libs/vscode-common/testUtil/toPlainObject"; import { plainObjectToTarget } from "./testUtil/fromPlainObject"; import isTesting from "./testUtil/isTesting"; import { Graph } from "./typings/Types"; @@ -28,19 +31,27 @@ import makeGraph, { FactoryMap } from "./util/makeGraph"; export async function activate( context: vscode.ExtensionContext, ): Promise { - const { getNodeAtLocation } = await getParseTreeApi(); + const parseTreeApi = await getParseTreeApi(); const commandServerApi = await getCommandServerApi(); + const vscodeIDE = new VscodeIDE(context); + if (isTesting()) { // FIXME: At some point we'll probably want to support partial mocking // rather than mocking away everything that we can - const fake = new FakeIDE(); + const fake = new FakeIDE(vscodeIDE); fake.mockAssetsRoot(context.extensionPath); injectIde(fake); } else { - injectIde(new VscodeIDE(context)); + injectIde(vscodeIDE); } + const getNodeAtLocation = (document: TextDocument, range: Range) => { + return parseTreeApi.getNodeAtLocation( + new vscode.Location(document.uri, toVscodeRange(range)), + ); + }; + const graph = makeGraph({ ...graphFactories, extensionContext: () => context, @@ -73,7 +84,15 @@ export async function activate( // FIXME: Remove this once we have a better way to get this function // accessible from our tests - plainObjectToTarget, + plainObjectToTarget: ( + editor: vscode.TextEditor, + plainObject: TargetPlainObject, + ) => { + return plainObjectToTarget( + vscodeIDE.fromVscodeEditor(editor), + plainObject, + ); + }, } : undefined, diff --git a/src/ide/vscode/VscodeEdit.ts b/src/ide/vscode/VscodeEdit.ts new file mode 100644 index 0000000000..c80184301b --- /dev/null +++ b/src/ide/vscode/VscodeEdit.ts @@ -0,0 +1,31 @@ +import { TextEditorEdit } from "@cursorless/common"; +import { + toVscodeEndOfLine, + toVscodePosition, + toVscodePositionOrRange, + toVscodeRange, +} from "@cursorless/vscode-common"; +import type * as vscode from "vscode"; + +export default function vscodeEdit( + editor: vscode.TextEditor, + callback: (editBuilder: TextEditorEdit) => void, + options?: { undoStopBefore: boolean; undoStopAfter: boolean }, +): Thenable { + return editor.edit((editBuilder) => { + callback({ + replace: (location, value) => { + editBuilder.replace(toVscodePositionOrRange(location), value); + }, + insert: (location, value) => { + editBuilder.insert(toVscodePosition(location), value); + }, + delete: (location) => { + editBuilder.delete(toVscodeRange(location)); + }, + setEndOfLine: (endOfLine) => { + editBuilder.setEndOfLine(toVscodeEndOfLine(endOfLine)); + }, + }); + }, options); +} diff --git a/src/ide/vscode/VscodeEvents.ts b/src/ide/vscode/VscodeEvents.ts new file mode 100644 index 0000000000..a5346babfb --- /dev/null +++ b/src/ide/vscode/VscodeEvents.ts @@ -0,0 +1,45 @@ +import { fromVscodeRange } from "@cursorless/vscode-common"; +import * as vscode from "vscode"; +import type { + TextDocumentChangeEvent, + TextDocumentChangeReason, + TextDocumentContentChangeEvent, +} from "../../libs/common/ide/types/Events"; +import type { Disposable } from "../../libs/common/ide/types/ide.types"; +import { VscodeTextDocumentImpl } from "./VscodeTextDocumentImpl"; + +export function vscodeOnDidChangeTextDocument( + listener: (event: TextDocumentChangeEvent) => void, +): Disposable { + return vscode.workspace.onDidChangeTextDocument((e) => { + listener({ + document: new VscodeTextDocumentImpl(e.document), + contentChanges: e.contentChanges.map(fromVscodeContentChange), + reason: fromVscodeReason(e.reason), + }); + }); +} + +function fromVscodeContentChange( + change: vscode.TextDocumentContentChangeEvent, +): TextDocumentContentChangeEvent { + return { + range: fromVscodeRange(change.range), + rangeOffset: change.rangeOffset, + rangeLength: change.rangeLength, + text: change.text, + }; +} + +function fromVscodeReason( + reason?: vscode.TextDocumentChangeReason, +): TextDocumentChangeReason | undefined { + switch (reason) { + case vscode.TextDocumentChangeReason.Redo: + return "redo"; + case vscode.TextDocumentChangeReason.Undo: + return "undo"; + default: + return undefined; + } +} diff --git a/src/ide/vscode/VscodeFocusEditor.ts b/src/ide/vscode/VscodeFocusEditor.ts new file mode 100644 index 0000000000..69b26abc56 --- /dev/null +++ b/src/ide/vscode/VscodeFocusEditor.ts @@ -0,0 +1,105 @@ +import * as semver from "semver"; +import { + commands, + NotebookDocument, + TextEditor, + version, + ViewColumn, + window, +} from "vscode"; +import { getCellIndex } from "../../libs/vscode-common/notebook"; +import { getNotebookFromCellDocument } from "../../util/notebook"; +import { + focusNotebookCellLegacy, + isVscodeLegacyNotebookVersion, +} from "../../util/notebookLegacy"; +import type VscodeIDE from "./VscodeIDE"; +import { VscodeTextEditorImpl } from "./VscodeTextEditorImpl"; + +const columnFocusCommands = { + [ViewColumn.One]: "workbench.action.focusFirstEditorGroup", + [ViewColumn.Two]: "workbench.action.focusSecondEditorGroup", + [ViewColumn.Three]: "workbench.action.focusThirdEditorGroup", + [ViewColumn.Four]: "workbench.action.focusFourthEditorGroup", + [ViewColumn.Five]: "workbench.action.focusFifthEditorGroup", + [ViewColumn.Six]: "workbench.action.focusSixthEditorGroup", + [ViewColumn.Seven]: "workbench.action.focusSeventhEditorGroup", + [ViewColumn.Eight]: "workbench.action.focusEighthEditorGroup", + [ViewColumn.Nine]: "workbench.action.focusNinthEditorGroup", + [ViewColumn.Active]: "", + [ViewColumn.Beside]: "", +}; + +export default async function vscodeFocusEditor( + ide: VscodeIDE, + editor: VscodeTextEditorImpl, +) { + const viewColumn = getViewColumn(editor.vscodeEditor); + if (viewColumn != null) { + await commands.executeCommand(columnFocusCommands[viewColumn]); + } else { + // If the view column is null we see if it's a notebook and try to see if we + // can just move around in the notebook to focus the correct editor + + if (isVscodeLegacyNotebookVersion()) { + return await focusNotebookCellLegacy(ide, editor); + } + + await focusNotebookCell(editor); + } +} + +function getViewColumn(editor: TextEditor): ViewColumn | undefined { + if (editor.viewColumn != null) { + return editor.viewColumn; + } + // TODO: tabGroups is not available on older versions of vscode we still support. + // Remove any cast as soon as version is updated. + if (semver.lt(version, "1.67.0")) { + return undefined; + } + const uri = editor.document.uri.toString(); + const tabGroup = (window as any)?.tabGroups?.all?.find((tabGroup: any) => + tabGroup?.tabs.find((tab: any) => tab?.input?.modified?.toString() === uri), + ); + return tabGroup?.viewColumn; +} + +async function focusNotebookCell(editor: VscodeTextEditorImpl) { + const desiredNotebookEditor = getNotebookFromCellDocument( + editor.vscodeEditor.document, + ); + if (desiredNotebookEditor == null) { + throw new Error("Couldn't find notebook editor for given document"); + } + + const desiredNotebookDocument: NotebookDocument = + desiredNotebookEditor.notebook; + + await commands.executeCommand( + columnFocusCommands[ + desiredNotebookEditor.viewColumn as keyof typeof columnFocusCommands + ], + ); + + const desiredEditorIndex = getCellIndex( + desiredNotebookDocument, + editor.vscodeEditor.document, + ); + + const desiredSelections = [ + desiredNotebookEditor.selection.with({ + start: desiredEditorIndex, + end: desiredEditorIndex + 1, + }), + ]; + desiredNotebookEditor.selections = desiredSelections; + desiredNotebookEditor.revealRange(desiredSelections[0]); + + // Issue a command to tell VSCode to focus the cell input editor + // NB: We don't issue the command if it's already focused, because it turns + // out that this command is actually a toggle, so that causes it to de-focus! + if (!editor.isActive) { + await commands.executeCommand("notebook.cell.edit"); + } +} diff --git a/src/ide/vscode/VscodeIDE.ts b/src/ide/vscode/VscodeIDE.ts index 0768181d39..e9ac7a668d 100644 --- a/src/ide/vscode/VscodeIDE.ts +++ b/src/ide/vscode/VscodeIDE.ts @@ -1,37 +1,35 @@ +import type { EditableTextEditor, TextEditor } from "@cursorless/common"; import { pull } from "lodash"; -import { - ExtensionContext, - ExtensionMode, - workspace, - WorkspaceFolder, -} from "vscode"; -import { +import type * as vscode from "vscode"; +import { ExtensionContext, window, workspace, WorkspaceFolder } from "vscode"; +import type { TextDocumentChangeEvent } from "../../libs/common/ide/types/Events"; +import type { Disposable, IDE, RunMode, } from "../../libs/common/ide/types/ide.types"; import VscodeClipboard from "./VscodeClipboard"; import VscodeConfiguration from "./VscodeConfiguration"; +import { VscodeTextEditorImpl } from "./VscodeTextEditorImpl"; +import { vscodeOnDidChangeTextDocument } from "./VscodeEvents"; import VscodeGlobalState from "./VscodeGlobalState"; import VscodeMessages from "./VscodeMessages"; - -const EXTENSION_MODE_MAP: Record = { - [ExtensionMode.Development]: "development", - [ExtensionMode.Production]: "production", - [ExtensionMode.Test]: "test", -}; +import { vscodeRunMode } from "./VscodeRunMode"; +import { v4 as uuid } from "uuid"; export default class VscodeIDE implements IDE { configuration: VscodeConfiguration; globalState: VscodeGlobalState; messages: VscodeMessages; clipboard: VscodeClipboard; + private editorMap; constructor(private extensionContext: ExtensionContext) { this.configuration = new VscodeConfiguration(this); this.globalState = new VscodeGlobalState(extensionContext); this.messages = new VscodeMessages(); this.clipboard = new VscodeClipboard(); + this.editorMap = new WeakMap(); } get assetsRoot(): string { @@ -39,13 +37,51 @@ export default class VscodeIDE implements IDE { } get runMode(): RunMode { - return EXTENSION_MODE_MAP[this.extensionContext.extensionMode]; + return vscodeRunMode(this.extensionContext); } get workspaceFolders(): readonly WorkspaceFolder[] | undefined { return workspace.workspaceFolders; } + get activeTextEditor(): TextEditor | undefined { + return this.getActiveTextEditor(); + } + + get activeEditableTextEditor(): EditableTextEditor | undefined { + return this.getActiveTextEditor(); + } + + private getActiveTextEditor() { + return window.activeTextEditor != null + ? this.fromVscodeEditor(window.activeTextEditor) + : undefined; + } + + get visibleTextEditors(): TextEditor[] { + return window.visibleTextEditors.map((e) => this.fromVscodeEditor(e)); + } + + public getEditableTextEditor(editor: TextEditor): EditableTextEditor { + return editor as EditableTextEditor; + } + + public onDidChangeTextDocument( + listener: (event: TextDocumentChangeEvent) => void, + ): Disposable { + return vscodeOnDidChangeTextDocument(listener); + } + + public fromVscodeEditor(editor: vscode.TextEditor): VscodeTextEditorImpl { + if (!this.editorMap.has(editor)) { + this.editorMap.set( + editor, + new VscodeTextEditorImpl(uuid(), this, editor), + ); + } + return this.editorMap.get(editor)!; + } + disposeOnExit(...disposables: Disposable[]): () => void { this.extensionContext.subscriptions.push(...disposables); diff --git a/src/ide/vscode/VscodeOpenLink.ts b/src/ide/vscode/VscodeOpenLink.ts new file mode 100644 index 0000000000..2c6e6996e2 --- /dev/null +++ b/src/ide/vscode/VscodeOpenLink.ts @@ -0,0 +1,49 @@ +import * as vscode from "vscode"; + +export default async function vscodeOpenLink( + editor: vscode.TextEditor, + location: vscode.Position | vscode.Range, +): Promise { + const links = await getLinksForEditor(editor); + const filteredLinks = links.filter((link) => link.range.contains(location)); + + if (filteredLinks.length > 1) { + throw Error("Multiple links found at location"); + } + + if (filteredLinks.length === 0) { + return false; + } + + await openLink(filteredLinks[0]); + + return true; +} + +function getLinksForEditor(editor: vscode.TextEditor) { + return vscode.commands.executeCommand( + "vscode.executeLinkProvider", + editor.document.uri, + ) as Thenable; +} + +function openLink(link: vscode.DocumentLink) { + if (link.target == null) { + throw Error("Document link is missing uri"); + } + return openUri(link.target); +} + +async function openUri(uri: vscode.Uri) { + switch (uri.scheme) { + case "http": + case "https": + await vscode.env.openExternal(uri); + break; + case "file": + await vscode.window.showTextDocument(uri); + break; + default: + throw Error(`Unknown uri scheme '${uri.scheme}'`); + } +} diff --git a/src/ide/vscode/VscodeRunMode.ts b/src/ide/vscode/VscodeRunMode.ts new file mode 100644 index 0000000000..c11428d124 --- /dev/null +++ b/src/ide/vscode/VscodeRunMode.ts @@ -0,0 +1,12 @@ +import { ExtensionContext, ExtensionMode } from "vscode"; +import type { RunMode } from "@cursorless/common"; + +const EXTENSION_MODE_MAP: Record = { + [ExtensionMode.Development]: "development", + [ExtensionMode.Production]: "production", + [ExtensionMode.Test]: "test", +}; + +export function vscodeRunMode(extensionContext: ExtensionContext): RunMode { + return EXTENSION_MODE_MAP[extensionContext.extensionMode]; +} diff --git a/src/ide/vscode/VscodeTextDocumentImpl.ts b/src/ide/vscode/VscodeTextDocumentImpl.ts new file mode 100644 index 0000000000..6844b6533d --- /dev/null +++ b/src/ide/vscode/VscodeTextDocumentImpl.ts @@ -0,0 +1,58 @@ +import { Position, Range, TextDocument, TextLine } from "@cursorless/common"; +import { + fromVscodePosition, + toVscodePosition, + toVscodeRange, +} from "@cursorless/vscode-common"; +import * as vscode from "vscode"; +import type { URI } from "vscode-uri"; +import VscodeTextLineImpl from "./VscodeTextLineImpl"; + +export class VscodeTextDocumentImpl implements TextDocument { + get uri(): URI { + return this.document.uri; + } + + get languageId(): string { + return this.document.languageId; + } + + get version(): number { + return this.document.version; + } + + get lineCount(): number { + return this.document.lineCount; + } + + get range(): Range { + const { end } = this.document.lineAt(this.document.lineCount - 1).range; + return new Range(0, 0, end.line, end.character); + } + + constructor(private document: vscode.TextDocument) {} + + public lineAt(lineOrPosition: number | Position): TextLine { + return new VscodeTextLineImpl( + this.document.lineAt( + typeof lineOrPosition === "number" + ? lineOrPosition + : lineOrPosition.line, + ), + ); + } + + public offsetAt(position: Position): number { + return this.document.offsetAt(toVscodePosition(position)); + } + + public positionAt(offset: number): Position { + return fromVscodePosition(this.document.positionAt(offset)); + } + + public getText(range?: Range): string { + return this.document.getText( + range != null ? toVscodeRange(range) : undefined, + ); + } +} diff --git a/src/ide/vscode/VscodeTextEditorImpl.ts b/src/ide/vscode/VscodeTextEditorImpl.ts new file mode 100644 index 0000000000..d569e26f6d --- /dev/null +++ b/src/ide/vscode/VscodeTextEditorImpl.ts @@ -0,0 +1,93 @@ +import type { + Position, + Range, + Selection, + TextDocument, + TextEditor, + TextEditorDecorationType, + TextEditorEdit, + TextEditorOptions, +} from "@cursorless/common"; +import { + fromVscodeRange, + fromVscodeSelection, + toVscodePositionOrRange, + toVscodeRange, + toVscodeSelection, +} from "@cursorless/vscode-common"; +import * as vscode from "vscode"; +import vscodeEdit from "./VscodeEdit"; +import vscodeFocusEditor from "./VscodeFocusEditor"; +import VscodeIDE from "./VscodeIDE"; +import vscodeOpenLink from "./VscodeOpenLink"; +import { VscodeTextDocumentImpl } from "./VscodeTextDocumentImpl"; + +export class VscodeTextEditorImpl implements TextEditor { + readonly document: TextDocument; + + constructor( + public readonly id: string, + private ide: VscodeIDE, + private editor: vscode.TextEditor, + ) { + this.document = new VscodeTextDocumentImpl(editor.document); + } + + get vscodeEditor(): vscode.TextEditor { + return this.editor; + } + + get selections(): Selection[] { + return this.editor.selections.map(fromVscodeSelection); + } + + set selections(selections: Selection[]) { + this.editor.selections = selections.map(toVscodeSelection); + } + + get visibleRanges(): Range[] { + return this.editor.visibleRanges.map(fromVscodeRange); + } + + get options(): TextEditorOptions { + return this.editor.options; + } + + set options(options: TextEditorOptions) { + this.editor.options = options; + } + + get isActive(): boolean { + return this.editor === vscode.window.activeTextEditor; + } + + public isEqual(other: TextEditor): boolean { + return this.id === other.id; + } + + public revealRange(range: Range): void { + this.editor.revealRange(toVscodeRange(range)); + } + + public setDecorations( + decorationType: TextEditorDecorationType, + ranges: readonly Range[], + ): void { + this.editor.setDecorations(decorationType, ranges.map(toVscodeRange)); + } + + public edit( + callback: (editBuilder: TextEditorEdit) => void, + options?: { undoStopBefore: boolean; undoStopAfter: boolean }, + ): Thenable { + return vscodeEdit(this.editor, callback, options); + } + + public focus(): Promise { + return vscodeFocusEditor(this.ide, this); + } + + public openLink(location: Position | Range): Promise { + return vscodeOpenLink(this.editor, toVscodePositionOrRange(location)); + } +} diff --git a/src/ide/vscode/VscodeTextLineImpl.ts b/src/ide/vscode/VscodeTextLineImpl.ts new file mode 100644 index 0000000000..2f19862870 --- /dev/null +++ b/src/ide/vscode/VscodeTextLineImpl.ts @@ -0,0 +1,35 @@ +import { Range, TextLine } from "@cursorless/common"; +import { fromVscodeRange } from "@cursorless/vscode-common"; +import * as vscode from "vscode"; + +export default class VscodeTextLineImpl implements TextLine { + constructor(private line: vscode.TextLine) {} + + get lineNumber(): number { + return this.line.lineNumber; + } + + get text(): string { + return this.line.text; + } + + get range(): Range { + return fromVscodeRange(this.line.range); + } + + get rangeIncludingLineBreak(): Range { + return fromVscodeRange(this.line.rangeIncludingLineBreak); + } + + get firstNonWhitespaceCharacterIndex(): number { + return this.line.firstNonWhitespaceCharacterIndex; + } + + get lastNonWhitespaceCharacterIndex(): number { + return this.line.text.trimEnd().length; + } + + get isEmptyOrWhitespace(): boolean { + return this.line.isEmptyOrWhitespace; + } +} diff --git a/src/ide/vscode/activeTextEditor.ts b/src/ide/vscode/activeTextEditor.ts deleted file mode 100644 index 63fa2ba2b6..0000000000 --- a/src/ide/vscode/activeTextEditor.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { TextEditor, window } from "vscode"; - -/** - * Returns the active text editor; should be used rather than reading - * `vscode.window.activeTextEditor` directly. - * - * This exists for ease of overriding in Cursorless Everywhere. - * - * It will eventually be replaced by `ide`'s `Editor` abstraction. - */ -export function getActiveTextEditor(): TextEditor | undefined { - return window.activeTextEditor; // eslint-disable-line no-restricted-properties -} diff --git a/src/ide/vscode/textLine.test.ts b/src/ide/vscode/textLine.test.ts new file mode 100644 index 0000000000..713850e157 --- /dev/null +++ b/src/ide/vscode/textLine.test.ts @@ -0,0 +1,38 @@ +import * as assert from "assert"; +import { openNewEditor } from "../../libs/vscode-common/testUtil/openNewEditor"; +import VscodeTextLineImpl from "./VscodeTextLineImpl"; + +/** + * Each test is of the form: + * + * `[text, firstNonWhitespaceCharacterIndex, lastNonWhitespaceCharacterIndex]` + */ +const whiteSpaceTests: [string, number, number][] = [ + [" ", 3, 0], + ["foo", 0, 3], + [" foo ", 1, 4], +]; + +suite("TextLine", () => { + whiteSpaceTests.forEach( + ([ + text, + firstNonWhitespaceCharacterIndex, + lastNonWhitespaceCharacterIndex, + ]) => { + test(`whitespace '${text}'`, async () => { + const editor = await openNewEditor(text); + const line = new VscodeTextLineImpl(editor.document.lineAt(0)); + + assert.equal( + line.firstNonWhitespaceCharacterIndex, + firstNonWhitespaceCharacterIndex, + ); + assert.equal( + line.lastNonWhitespaceCharacterIndex, + lastNonWhitespaceCharacterIndex, + ); + }); + }, + ); +}); diff --git a/src/languages/getTextFragmentExtractor.ts b/src/languages/getTextFragmentExtractor.ts index bdcee7c9e0..f157c71a8b 100644 --- a/src/languages/getTextFragmentExtractor.ts +++ b/src/languages/getTextFragmentExtractor.ts @@ -1,17 +1,17 @@ +import { Range } from "@cursorless/common"; import { SyntaxNode } from "web-tree-sitter"; +import { UnsupportedLanguageError } from "../errors"; +import { SupportedLanguageId } from "../libs/cursorless-engine/languages/constants"; import { SelectionWithEditor } from "../typings/Types"; +import { notSupported } from "../util/nodeMatchers"; +import { getNodeInternalRange, getNodeRange } from "../util/nodeSelectors"; +import { getNodeMatcher } from "./getNodeMatcher"; import { stringTextFragmentExtractor as htmlStringTextFragmentExtractor } from "./html"; import { stringTextFragmentExtractor as jsonStringTextFragmentExtractor } from "./json"; import { stringTextFragmentExtractor as phpStringTextFragmentExtractor } from "./php"; import { stringTextFragmentExtractor as rubyStringTextFragmentExtractor } from "./ruby"; -import { stringTextFragmentExtractor as typescriptStringTextFragmentExtractor } from "./typescript"; import { stringTextFragmentExtractor as scssStringTextFragmentExtractor } from "./scss"; -import { UnsupportedLanguageError } from "../errors"; -import { Range } from "vscode"; -import { SupportedLanguageId } from "../libs/cursorless-engine/languages/constants"; -import { getNodeInternalRange, getNodeRange } from "../util/nodeSelectors"; -import { getNodeMatcher } from "./getNodeMatcher"; -import { notSupported } from "../util/nodeMatchers"; +import { stringTextFragmentExtractor as typescriptStringTextFragmentExtractor } from "./typescript"; export type TextFragmentExtractor = ( node: SyntaxNode, diff --git a/src/languages/latex.ts b/src/languages/latex.ts index 3b682bb6d8..c3a04c5876 100644 --- a/src/languages/latex.ts +++ b/src/languages/latex.ts @@ -1,4 +1,4 @@ -import { Range, Selection, TextEditor } from "vscode"; +import { Range, Selection, TextEditor } from "@cursorless/common"; import { SyntaxNode } from "web-tree-sitter"; import { SimpleScopeTypeType } from "../typings/targetDescriptor.types"; import { NodeMatcherAlternative, SelectionWithContext } from "../typings/Types"; diff --git a/src/languages/markdown.ts b/src/languages/markdown.ts index b8fcb3cf0c..f591a29a1a 100644 --- a/src/languages/markdown.ts +++ b/src/languages/markdown.ts @@ -1,5 +1,6 @@ -import { Range, Selection, TextEditor } from "vscode"; +import { Range, Selection, TextEditor } from "@cursorless/common"; import { SyntaxNode } from "web-tree-sitter"; +import { getMatchesInRange } from "../apps/cursorless-vscode/getMatchesInRange"; import { SimpleScopeTypeType } from "../typings/targetDescriptor.types"; import { NodeFinder, @@ -13,12 +14,7 @@ import { getNodeRange, selectWithLeadingDelimiter, } from "../util/nodeSelectors"; -import { getMatchesInRange } from "../apps/cursorless-vscode/getMatchesInRange"; -import { - isReversed, - selectionFromRange, - shrinkRangeToFitContent, -} from "../util/selectionUtils"; +import { shrinkRangeToFitContent } from "../util/selectionUtils"; /** * Given a node representing the text of a section heading (without leading @@ -90,9 +86,8 @@ function sectionExtractor(editor: TextEditor, node: SyntaxNode) { ); return { context, - selection: selectionFromRange( - isReversed(selection), - shrinkRangeToFitContent(editor, selection), + selection: shrinkRangeToFitContent(editor, selection).toSelection( + selection.isReversed, ), }; } @@ -126,9 +121,8 @@ function itemExtractor(editor: TextEditor, node: SyntaxNode) { return { context, - selection: selectionFromRange( - isReversed(selection), - excludeTrailingNewline(editor, selection), + selection: excludeTrailingNewline(editor, selection).toSelection( + selection.isReversed, ), }; } diff --git a/src/languages/php.ts b/src/languages/php.ts index 63d00a1b1d..be5bfa19d5 100644 --- a/src/languages/php.ts +++ b/src/languages/php.ts @@ -1,11 +1,11 @@ -import { Selection, TextEditor } from "vscode"; +import { Selection, TextEditor } from "@cursorless/common"; import { SyntaxNode } from "web-tree-sitter"; +import { SimpleScopeTypeType } from "../typings/targetDescriptor.types"; import { NodeMatcherAlternative, SelectionWithContext, SelectionWithEditor, } from "../typings/Types"; -import { SimpleScopeTypeType } from "../typings/targetDescriptor.types"; import { patternFinder } from "../util/nodeFinders"; import { argumentMatcher, diff --git a/src/languages/python.ts b/src/languages/python.ts index 281edc608c..bd1251844f 100644 --- a/src/languages/python.ts +++ b/src/languages/python.ts @@ -1,4 +1,4 @@ -import { Selection } from "vscode"; +import { Selection } from "@cursorless/common"; import { SyntaxNode } from "web-tree-sitter"; import { SimpleScopeTypeType } from "../typings/targetDescriptor.types"; import { NodeFinder, NodeMatcherAlternative } from "../typings/Types"; diff --git a/src/languages/rust.ts b/src/languages/rust.ts index d28eddc909..8976393dec 100644 --- a/src/languages/rust.ts +++ b/src/languages/rust.ts @@ -1,4 +1,4 @@ -import { TextEditor } from "vscode"; +import { TextEditor } from "@cursorless/common"; import { SyntaxNode } from "web-tree-sitter"; import { SimpleScopeTypeType } from "../typings/targetDescriptor.types"; import { NodeMatcherAlternative, SelectionWithContext } from "../typings/Types"; diff --git a/src/libs/common/ide/fake/FakeIDE.ts b/src/libs/common/ide/fake/FakeIDE.ts index f490552122..7af41a817c 100644 --- a/src/libs/common/ide/fake/FakeIDE.ts +++ b/src/libs/common/ide/fake/FakeIDE.ts @@ -1,4 +1,6 @@ +import type { EditableTextEditor, TextEditor } from "@cursorless/common"; import { pull } from "lodash"; +import type { TextDocumentChangeEvent } from "../types/Events"; import type { Disposable, IDE, @@ -17,7 +19,7 @@ export default class FakeIDE implements IDE { clipboard: FakeClipboard; private disposables: Disposable[] = []; - constructor() { + constructor(private original?: IDE) { this.configuration = new FakeConfiguration(); this.messages = new FakeMessages(); this.globalState = new FakeGlobalState(); @@ -41,6 +43,34 @@ export default class FakeIDE implements IDE { runMode: RunMode = "test"; workspaceFolders: readonly WorkspaceFolder[] | undefined = undefined; + get activeTextEditor(): TextEditor | undefined { + return this.original?.activeTextEditor; + } + + get activeEditableTextEditor(): EditableTextEditor | undefined { + return this.original?.activeEditableTextEditor; + } + + get visibleTextEditors(): TextEditor[] { + return this.original?.visibleTextEditors ?? []; + } + + public getEditableTextEditor(editor: TextEditor): EditableTextEditor { + if (this.original == null) { + throw Error("Original ide is missing"); + } + return this.original.getEditableTextEditor(editor); + } + + onDidChangeTextDocument( + listener: (event: TextDocumentChangeEvent) => void, + ): Disposable { + if (this.original == null) { + throw Error("Original ide is missing"); + } + return this.original.onDidChangeTextDocument(listener); + } + disposeOnExit(...disposables: Disposable[]): () => void { this.disposables.push(...disposables); diff --git a/src/libs/common/ide/spy/SpyIDE.ts b/src/libs/common/ide/spy/SpyIDE.ts index 50536ca664..d1b96977f3 100644 --- a/src/libs/common/ide/spy/SpyIDE.ts +++ b/src/libs/common/ide/spy/SpyIDE.ts @@ -1,14 +1,16 @@ +import { EditableTextEditor, TextEditor } from "@cursorless/common"; import { pickBy, values } from "lodash"; +import type { Clipboard } from "../types/Clipboard"; +import type { Configuration } from "../types/Configuration"; +import type { TextDocumentChangeEvent } from "../types/Events"; import type { Disposable, IDE, RunMode, WorkspaceFolder, } from "../types/ide.types"; -import type { Configuration } from "../types/Configuration"; import type { State } from "../types/State"; import SpyMessages, { Message } from "./SpyMessages"; -import type { Clipboard } from "../types/Clipboard"; export interface SpyIDERecordedValues { messages?: Message[]; @@ -27,6 +29,18 @@ export default class SpyIDE implements IDE { this.messages = new SpyMessages(original.messages); } + public get activeTextEditor(): TextEditor | undefined { + return this.original.activeTextEditor; + } + + public get activeEditableTextEditor(): EditableTextEditor | undefined { + return this.original.activeEditableTextEditor; + } + + public get visibleTextEditors(): TextEditor[] { + return this.original.visibleTextEditors; + } + public get assetsRoot(): string { return this.original.assetsRoot; } @@ -39,6 +53,16 @@ export default class SpyIDE implements IDE { return this.original.workspaceFolders; } + public getEditableTextEditor(editor: TextEditor): EditableTextEditor { + return this.original.getEditableTextEditor(editor); + } + + onDidChangeTextDocument( + listener: (event: TextDocumentChangeEvent) => void, + ): Disposable { + return this.original.onDidChangeTextDocument(listener); + } + disposeOnExit(...disposables: Disposable[]): () => void { return this.original.disposeOnExit(...disposables); } diff --git a/src/libs/common/ide/types/Events.ts b/src/libs/common/ide/types/Events.ts new file mode 100644 index 0000000000..4d80d968db --- /dev/null +++ b/src/libs/common/ide/types/Events.ts @@ -0,0 +1,49 @@ +import type { TextDocument, Range } from "@cursorless/common"; + +/** + * An event describing a transactional {@link TextDocument document} change. + */ +export interface TextDocumentChangeEvent { + /** + * The affected document. + */ + readonly document: TextDocument; + + /** + * An array of content changes. + */ + readonly contentChanges: readonly TextDocumentContentChangeEvent[]; + + /** + * The reason why the document was changed. + * Is undefined if the reason is not known. + */ + readonly reason?: TextDocumentChangeReason; +} + +/** + * An event describing an individual change in the text of a {@link TextDocument document}. + */ +export interface TextDocumentContentChangeEvent { + /** + * The range that got replaced. + */ + readonly range: Range; + + /** + * The offset of the range that got replaced. + */ + readonly rangeOffset: number; + + /** + * The length of the range that got replaced. + */ + readonly rangeLength: number; + + /** + * The new text for the range. + */ + readonly text: string; +} + +export type TextDocumentChangeReason = "undo" | "redo"; diff --git a/src/libs/common/ide/types/README.md b/src/libs/common/ide/types/README.md new file mode 100644 index 0000000000..70255b9477 --- /dev/null +++ b/src/libs/common/ide/types/README.md @@ -0,0 +1,3 @@ +# Core IDE types + +This directory contains the core IDE types used throughout the cursorless code base. Note that a lot of the types as well as their JSDocs were taken and modified from the core vscode types, which are available under the [MIT license](https://github.com/microsoft/vscode/blob/main/LICENSE.txt). diff --git a/src/libs/common/ide/types/ide.types.ts b/src/libs/common/ide/types/ide.types.ts index 3ad5d0f2a1..8ed9ff02b2 100644 --- a/src/libs/common/ide/types/ide.types.ts +++ b/src/libs/common/ide/types/ide.types.ts @@ -1,6 +1,8 @@ +import type { EditableTextEditor, TextEditor } from "@cursorless/common"; import { URI } from "vscode-uri"; import { Clipboard } from "./Clipboard"; import { Configuration } from "./Configuration"; +import { TextDocumentChangeEvent } from "./Events"; import { Messages } from "./Messages"; import { State } from "./State"; @@ -24,17 +26,49 @@ export interface IDE { * The root directory of this shipped code. Can be used to access bundled * assets. */ - assetsRoot: string; + readonly assetsRoot: string; /** * Whether we are running in development, test, or production */ - runMode: RunMode; + readonly runMode: RunMode; /** * A list of workspace folders for the currently active workspace */ - workspaceFolders: readonly WorkspaceFolder[] | undefined; + readonly workspaceFolders: readonly WorkspaceFolder[] | undefined; + + /** + * The currently active editor or `undefined`. The active editor is the one + * that currently has focus or, when none has focus, the one that has changed + * input most recently. + */ + readonly activeTextEditor: TextEditor | undefined; + + /** + * Same as {@link activeTextEditor} but editable + */ + readonly activeEditableTextEditor: EditableTextEditor | undefined; + + /** + * The currently visible editors or an empty array. + */ + readonly visibleTextEditors: TextEditor[]; + + /** + * Get an editable version of the text editor. + * @param editor A editable text editor + */ + getEditableTextEditor(editor: TextEditor): EditableTextEditor; + + /** + * An event that is emitted when a {@link TextDocument text document} is changed. This usually happens + * when the {@link TextDocument.getText contents} changes but also when other things like the + * {@link TextDocument.isDirty dirty}-state changes. + */ + onDidChangeTextDocument( + listener: (event: TextDocumentChangeEvent) => void, + ): Disposable; } export interface WorkspaceFolder { @@ -45,3 +79,8 @@ export interface WorkspaceFolder { export interface Disposable { dispose(): void; } + +/** + * Represents an end of line character sequence in a {@link TextDocument document}. + */ +export type EndOfLine = "LF" | "CRLF"; diff --git a/src/libs/common/index.ts b/src/libs/common/index.ts index 3777a0b357..47ad83280b 100644 --- a/src/libs/common/index.ts +++ b/src/libs/common/index.ts @@ -17,3 +17,12 @@ export { walkFilesSync } from "./util/walkSync"; export { Listener, Notifier } from "./util/Notifier"; export { TokenHatSplittingMode } from "./ide/types/Configuration"; export * from "./ide/types/ide.types"; +export * from "./types/Position"; +export * from "./types/Range"; +export * from "./types/Selection"; +export * from "./types/TextDocument"; +export * from "./types/TextEditor"; +export * from "./types/TextEditorDecorationType"; +export * from "./types/TextEditorEdit"; +export * from "./types/TextEditorOptions"; +export * from "./types/TextLine"; diff --git a/src/libs/common/types/Position.ts b/src/libs/common/types/Position.ts new file mode 100644 index 0000000000..35f5e604df --- /dev/null +++ b/src/libs/common/types/Position.ts @@ -0,0 +1,141 @@ +import { Range } from "@cursorless/common"; + +export class Position { + /** + * The zero-based line value. + */ + public readonly line: number; + + /** + * The zero-based character value. + */ + public readonly character: number; + + /** + * @param line A zero-based line value. + * @param character A zero-based character value. + */ + constructor(line: number, character: number) { + this.line = line; + this.character = character; + } + + /** + * Check if this position is equal to `other`. + * + * @param other A position. + * @return `true` if the line and character of the given position are equal to + * the line and character of this position. + */ + public isEqual(other: Position): boolean { + return this.line === other.line && this.character === other.character; + } + + /** + * Check if this position is before `other`. + * + * @param other A position. + * @return `true` if position is on a smaller line + * or on the same line on a smaller character. + */ + public isBefore(other: Position): boolean { + if (this.line < other.line) { + return true; + } + if (this.line > other.line) { + return false; + } + return this.character < other.character; + } + + /** + * Check if this position is after `other`. + * + * @param other A position. + * @return `true` if position is on a greater line + * or on the same line on a greater character. + */ + public isAfter(other: Position): boolean { + if (this.line > other.line) { + return true; + } + if (this.line < other.line) { + return false; + } + return this.character > other.character; + } + + /** + * Check if this position is before or equal to `other`. + * + * @param other A position. + * @return `true` if position is on a smaller line + * or on the same line on a smaller or equal character. + */ + public isBeforeOrEqual(other: Position): boolean { + return this.isEqual(other) || this.isBefore(other); + } + + /** + * Check if this position is after or equal to `other`. + * + * @param other A position. + * @return `true` if position is on a greater line + * or on the same line on a greater or equal character. + */ + public isAfterOrEqual(other: Position): boolean { + return this.isEqual(other) || this.isAfter(other); + } + + /** + * Compare this to `other`. + * + * @param other A position. + * @return A number smaller than zero if this position is before the given position, + * a number greater than zero if this position is after the given position, or zero when + * this and the given position are equal. + */ + public compareTo(other: Position): number { + if (this.isBefore(other)) { + return -1; + } + if (this.isAfter(other)) { + return 1; + } + return 0; + } + + /** + * Create a new position derived from this position. + * + * @param line Value that should be used as line value, default is the {@link Position.line existing value} + * @param character Value that should be used as character value, default is the {@link Position.character existing value} + * @return A position where line and character are replaced by the given values. + */ + public with(line?: number, character?: number): Position { + return new Position(line ?? this.line, character ?? this.character); + } + + /** + * Create a new position relative to this position. + * + * @param lineDelta Delta value for the line value, default is `0`. + * @param characterDelta Delta value for the character value, default is `0`. + * @return A position which line and character is the sum of the current line and + * character and the corresponding deltas. + */ + public translate(lineDelta?: number, characterDelta?: number): Position { + return new Position( + this.line + (lineDelta ?? 0), + this.character + (characterDelta ?? 0), + ); + } + + /** + * Create a new empty range from this position. + * @returns A {@link Range} + */ + public toEmptyRange(): Range { + return new Range(this, this); + } +} diff --git a/src/libs/common/types/Range.ts b/src/libs/common/types/Range.ts new file mode 100644 index 0000000000..ea4f4e3ba0 --- /dev/null +++ b/src/libs/common/types/Range.ts @@ -0,0 +1,149 @@ +import { Position, Selection } from "@cursorless/common"; + +export class Range { + /** + * The start position. It is before or equal to {@link Range.end end}. + */ + readonly start: Position; + + /** + * The end position. It is after or equal to {@link Range.start start}. + */ + readonly end: Position; + + /** + * Create a new range from two positions. If `start` is not + * before or equal to `end`, the values will be swapped. + * + * @param start A position. + * @param end A position. + */ + constructor(start: Position, end: Position); + + /** + * Create a new range from number coordinates. It is a shorter equivalent of + * using `new Range(new Position(startLine, startCharacter), new Position(endLine, endCharacter))` + * + * @param startLine A zero-based line value. + * @param startCharacter A zero-based character value. + * @param endLine A zero-based line value. + * @param endCharacter A zero-based character value. + */ + constructor( + startLine: number, + startCharacter: number, + endLine: number, + endCharacter: number, + ); + + constructor(...args: any[]) { + const [start, end]: [Position, Position] = (() => { + // Arguments are two positions + if (args.length === 2) { + return args as [Position, Position]; + } + + // Arguments are four numbers + return [new Position(args[0], args[1]), new Position(args[2], args[3])]; + })(); + + // Ranges are always non-reversed + if (start.isBefore(end)) { + this.start = start; + this.end = end; + } else { + this.start = end; + this.end = start; + } + } + + /** + * `true` if `start` and `end` are equal. + */ + get isEmpty(): boolean { + return this.start.isEqual(this.end); + } + + /** + * `true` if `start.line` and `end.line` are equal. + */ + get isSingleLine(): boolean { + return this.start.line === this.end.line; + } + + /** + * Check if `other` equals this range. + * + * @param other A range. + * @return `true` when start and end are {@link Position.isEqual equal} to + * start and end of this range. + */ + public isRangeEqual(other: Range): boolean { + return this.start.isEqual(other.start) && this.end.isEqual(other.end); + } + + /** + * Check if a position or a range is contained in this range. + * + * @param positionOrRange A position or a range. + * @return `true` if the position or range is inside or equal + * to this range. + */ + public contains(positionOrRange: Position | Range): boolean { + const [start, end] = + positionOrRange instanceof Position + ? [positionOrRange, positionOrRange] + : [positionOrRange.start, positionOrRange.end]; + return start.isAfterOrEqual(this.start) && end.isBeforeOrEqual(this.end); + } + + /** + * Intersect `range` with this range and returns a new range or `undefined` + * if the ranges have no overlap. + * + * @param other A range. + * @return A range of the greater start and smaller end positions. Will + * return undefined when there is no overlap. + */ + public intersection(other: Range): Range | undefined { + const start = this.start.isAfter(other.start) ? this.start : other.start; + const end = this.end.isBefore(other.end) ? this.end : other.end; + return start.isBeforeOrEqual(end) ? new Range(start, end) : undefined; + } + + /** + * Compute the union of `other` with this range. + * + * @param other A range. + * @return A range of smaller start position and the greater end position. + */ + public union(other: Range): Range { + return new Range( + this.start.isBefore(other.start) ? this.start : other.start, + this.end.isAfter(other.end) ? this.end : other.end, + ); + } + + /** + * Derived a new range from this range. + * + * @param start A position that should be used as start. The default value is the {@link Range.start current start}. + * @param end A position that should be used as end. The default value is the {@link Range.end current end}. + * @return A range derived from this range with the given start and end position. + * If start and end are not different `this` range will be returned. + */ + public with(start?: Position, end?: Position): Range { + return new Range(start ?? this.start, end ?? this.end); + } + + /** + * Construct a new selection from this range + * @param isReversed If true active is before anchor + * @returns A new selection + */ + public toSelection(isReversed: boolean): Selection { + return isReversed + ? new Selection(this.end, this.start) + : new Selection(this.start, this.end); + } +} diff --git a/src/libs/common/types/Selection.ts b/src/libs/common/types/Selection.ts new file mode 100644 index 0000000000..8a84da2392 --- /dev/null +++ b/src/libs/common/types/Selection.ts @@ -0,0 +1,75 @@ +import { Position, Range } from "@cursorless/common"; + +export class Selection extends Range { + /** + * The position at which the selection starts. + * This position might be before or after {@link Selection.active active}. + */ + readonly anchor: Position; + + /** + * The position of the cursor. + * This position might be before or after {@link Selection.anchor anchor}. + */ + readonly active: Position; + + /** + * Is true if active position is before anchor position. + */ + get isReversed(): boolean { + return this.active.isBefore(this.anchor); + } + + /** + * Create a selection from two positions. + * + * @param anchor A position. + * @param active A position. + */ + constructor(anchor: Position, active: Position); + + /** + * Create a selection from four coordinates. + * + * @param anchorLine A zero-based line value. + * @param anchorCharacter A zero-based character value. + * @param activeLine A zero-based line value. + * @param activeCharacter A zero-based character value. + */ + constructor( + anchorLine: number, + anchorCharacter: number, + activeLine: number, + activeCharacter: number, + ); + + constructor(...args: any[]) { + const [anchor, active]: [Position, Position] = (() => { + // Arguments are two positions + if (args.length === 2) { + return args as [Position, Position]; + } + + // Arguments are four numbers + return [new Position(args[0], args[1]), new Position(args[2], args[3])]; + })(); + + super(anchor, active); + + this.anchor = anchor; + this.active = active; + } + + /** + * Check if `other` equals this range. + * + * @param other A selection. + * @return `true` when anchor and active are {@link Position.isEqual equal} to + * anchor and active of this range. + */ + public isEqual(other: Selection): boolean { + return ( + this.anchor.isEqual(other.anchor) && this.active.isEqual(other.active) + ); + } +} diff --git a/src/libs/common/types/TextDocument.ts b/src/libs/common/types/TextDocument.ts new file mode 100644 index 0000000000..6cfe3250bd --- /dev/null +++ b/src/libs/common/types/TextDocument.ts @@ -0,0 +1,86 @@ +import type { Position, Range, TextLine } from "@cursorless/common"; +import type { URI } from "vscode-uri"; + +export interface TextDocument { + /** + * The associated uri for this document. + * + * *Note* that most documents use the `file`-scheme, which means they are files on disk. However, **not** all documents are + * saved on disk and therefore the `scheme` must be checked before trying to access the underlying file or siblings on disk. + */ + readonly uri: URI; + + /** + * The identifier of the language associated with this document. + */ + readonly languageId: string; + + /** + * The version number of this document (it will strictly increase after each + * change, including undo/redo). + */ + readonly version: number; + + /** + * The number of lines in this document. + */ + readonly lineCount: number; + + /** + * The range of the text document. + */ + readonly range: Range; + + /** + * Returns a text line denoted by the line number. Note + * that the returned object is *not* live and changes to the + * document are not reflected. + * + * @param line A line number in [0, lineCount). + * @return A {@link TextLine line}. + */ + lineAt(line: number): TextLine; + + /** + * Returns a text line denoted by the position. Note + * that the returned object is *not* live and changes to the + * document are not reflected. + * + * The position will be adjusted if it is outside {@link range}. + * + * @see {@link TextDocument.lineAt} + * + * @param position A position. + * @return A {@link TextLine line}. + */ + lineAt(position: Position): TextLine; + + /** + * Converts the position to a zero-based offset. + * + * The position will be adjusted if it is outside {@link range}. + * + * @param position A position. + * @return A valid zero-based offset. + */ + offsetAt(position: Position): number; + + /** + * Converts a zero-based offset to a position. + * + * @param offset A zero-based offset. + * @return A valid {@link Position}. + */ + positionAt(offset: number): Position; + + /** + * Get the text of this document. A substring can be retrieved by providing + * a range. + * + * The range will be adjusted if it extends outside {@link TextDocument.range}. + * + * @param range Include only the text included by the range. + * @return The text inside the provided range or the entire text. + */ + getText(range?: Range): string; +} diff --git a/src/libs/common/types/TextEditor.ts b/src/libs/common/types/TextEditor.ts new file mode 100644 index 0000000000..79219d9b8a --- /dev/null +++ b/src/libs/common/types/TextEditor.ts @@ -0,0 +1,109 @@ +import type { + Position, + Range, + Selection, + TextDocument, + TextEditorDecorationType, + TextEditorEdit, + TextEditorOptions, +} from "@cursorless/common"; + +/** + * Represents a read-only reference to a text editor. If you need to modify the + * editor, use {@link IDE.getEditableTextEditor}. + */ +export interface TextEditor { + /** + * Unique identifier for this text editor + */ + readonly id: string; + + /** + * The document associated with this text editor. The document will be the same for the entire lifetime of this text editor. + */ + readonly document: TextDocument; + + /** + * The current visible ranges in the editor (vertically). + * This accounts only for vertical scrolling, and not for horizontal scrolling. + */ + readonly visibleRanges: Range[]; + + /** + * The selections in this text editor. + */ + readonly selections: Selection[]; + + /** + * Text editor options. + */ + readonly options: TextEditorOptions; + + /** + * True if this text editor is active. + */ + readonly isActive: boolean; + + /** + * Check if this text editor is equal to `other`. + * + * @param other A text editor. + * @return `true` if the this text editor is equal to `other`. + */ + isEqual(other: TextEditor): boolean; +} + +export interface EditableTextEditor extends TextEditor { + selections: Selection[]; + + options: TextEditorOptions; + + /** + * Scroll to reveal the given range. + * + * @param range A range. + */ + revealRange(range: Range): void; + + /** + * Focus the editor. + */ + focus(): Promise; + + /** + * Adds a set of decorations to the text editor. If a set of decorations already exists with + * the given {@link TextEditorDecorationType decoration type}, they will be replaced. If + * `ranges` is empty, the existing decorations with the given {@link TextEditorDecorationType decoration type} + * will be removed. + * + * @param decorationType A decoration type. + * @param ranges {@link Range ranges} + */ + setDecorations( + decorationType: TextEditorDecorationType, + ranges: readonly Range[], + ): void; + + /** + * Perform an edit on the document associated with this text editor. + * + * The given callback-function is invoked with an {@link TextEditorEdit edit-builder} which must + * be used to make edits. Note that the edit-builder is only valid while the + * callback executes. + * + * @param callback A function which can create edits using an {@link TextEditorEdit edit-builder}. + * @param options The undo/redo behavior around this edit. By default, undo stops will be created before and after this edit. + * @return A promise that resolves with a value indicating if the edits could be applied. + */ + edit( + callback: (editBuilder: TextEditorEdit) => void, + options?: { undoStopBefore: boolean; undoStopAfter: boolean }, + ): Thenable; + + /** + * Open link at location. + * @param location Position or range + * @return True if a link was opened + */ + openLink(location: Position | Range): Promise; +} diff --git a/src/libs/common/types/TextEditorDecorationType.ts b/src/libs/common/types/TextEditorDecorationType.ts new file mode 100644 index 0000000000..8d22dd3842 --- /dev/null +++ b/src/libs/common/types/TextEditorDecorationType.ts @@ -0,0 +1,15 @@ +/** + * Represents a handle to a set of decorations sharing the same + * {@link DecorationRenderOptions styling options}. + */ +export interface TextEditorDecorationType { + /** + * Internal representation of the handle. + */ + readonly key: string; + + /** + * this decoration type and all decorations on all text editors using it. + */ + dispose(): void; +} diff --git a/src/libs/common/types/TextEditorEdit.ts b/src/libs/common/types/TextEditorEdit.ts new file mode 100644 index 0000000000..6015c6fb52 --- /dev/null +++ b/src/libs/common/types/TextEditorEdit.ts @@ -0,0 +1,41 @@ +import type { EndOfLine, Position, Range } from "@cursorless/common"; + +/** + * A complex edit that will be applied in one transaction on a TextEditor. + * This holds a description of the edits and if the edits are valid (i.e. no overlapping regions, document was not changed in the meantime, etc.) + * they can be applied on a {@link TextDocument document} associated with a {@link TextEditor text editor}. + */ +export interface TextEditorEdit { + /** + * Replace a certain text region with a new value. + * You can use \r\n or \n in `value` and they will be normalized to the current {@link TextDocument document}. + * + * @param location The range this operation should remove. + * @param value The new text this operation should insert after removing `location`. + */ + replace(location: Position | Range, value: string): void; + + /** + * Insert text at a location. + * You can use \r\n or \n in `value` and they will be normalized to the current {@link TextDocument document}. + * Although the equivalent text edit can be made with {@link TextEditorEdit.replace replace}, `insert` will produce a different resulting selection (it will get moved). + * + * @param location The position where the new text should be inserted. + * @param value The new text this operation should insert. + */ + insert(location: Position, value: string): void; + + /** + * Delete a certain text region. + * + * @param location The range this operation should remove. + */ + delete(location: Range): void; + + /** + * Set the end of line sequence. + * + * @param endOfLine The new end of line for the {@link TextDocument document}. + */ + setEndOfLine(endOfLine: EndOfLine): void; +} diff --git a/src/libs/common/types/TextEditorOptions.ts b/src/libs/common/types/TextEditorOptions.ts new file mode 100644 index 0000000000..041286b979 --- /dev/null +++ b/src/libs/common/types/TextEditorOptions.ts @@ -0,0 +1,21 @@ +/** + * Represents a {@link TextEditor text editor}'s {@link TextEditor.options options}. + */ +export interface TextEditorOptions { + /** + * The size in spaces a tab takes. This is used for two purposes: + * - the rendering width of a tab character; + * - the number of spaces to insert when {@link TextEditorOptions.insertSpaces insertSpaces} is true. + * + * When getting a text editor's options, this property will always be a number (resolved). + * When setting a text editor's options, this property is optional and it can be a number or `"auto"`. + */ + tabSize?: number | string; + + /** + * When pressing Tab insert {@link TextEditorOptions.tabSize n} spaces. + * When getting a text editor's options, this property will always be a boolean (resolved). + * When setting a text editor's options, this property is optional and it can be a boolean or `"auto"`. + */ + insertSpaces?: boolean | string; +} diff --git a/src/libs/common/types/TextLine.ts b/src/libs/common/types/TextLine.ts new file mode 100644 index 0000000000..3ba38b17e9 --- /dev/null +++ b/src/libs/common/types/TextLine.ts @@ -0,0 +1,47 @@ +import type { Range } from "@cursorless/common"; + +/** + * Represents a line of text, such as a line of source code. + * + * TextLine objects are __immutable__. When a {@link TextDocument document} changes, + * previously retrieved lines will not represent the latest state. + */ +export interface TextLine { + /** + * The zero-based line number. + */ + readonly lineNumber: number; + + /** + * The text of this line without the line separator characters. + */ + readonly text: string; + + /** + * The range this line covers without the line separator characters. + */ + readonly range: Range; + + /** + * The range this line covers with the line separator characters. + */ + readonly rangeIncludingLineBreak: Range; + + /** + * The offset of the first character which is not a whitespace character as defined + * by `/\s/`. **Note** that if a line is all whitespace the length of the line is returned. + */ + readonly firstNonWhitespaceCharacterIndex: number; + + /** + * The offset of the last character which is not a whitespace character as defined + * by `/\s/`. **Note** that if a line is all whitespace 0 is returned. + */ + readonly lastNonWhitespaceCharacterIndex: number; + + /** + * Whether this line is whitespace only, shorthand + * for {@link TextLine.firstNonWhitespaceCharacterIndex} === {@link TextLine.text TextLine.text.length}. + */ + readonly isEmptyOrWhitespace: boolean; +} diff --git a/src/libs/common/types/position.test.ts b/src/libs/common/types/position.test.ts new file mode 100644 index 0000000000..ca8a2462f7 --- /dev/null +++ b/src/libs/common/types/position.test.ts @@ -0,0 +1,71 @@ +import * as assert from "assert"; +import { Position } from "@cursorless/common"; + +suite("Position", () => { + test("constructor", () => { + assert.equal(new Position(5, 0).line, 5); + assert.equal(new Position(0, 5).character, 5); + }); + + test("isEqual", () => { + assert.ok(new Position(0, 0).isEqual(new Position(0, 0))); + assert.ok(new Position(1, 2).isEqual(new Position(1, 2))); + assert.ok(new Position(3, 2).isEqual(new Position(3, 2))); + assert.ok(!new Position(0, 0).isEqual(new Position(0, 1))); + assert.ok(!new Position(0, 0).isEqual(new Position(1, 0))); + }); + + test("isBefore", () => { + assert.ok(new Position(0, 0).isBefore(new Position(1, 0))); + assert.ok(new Position(0, 0).isBefore(new Position(0, 1))); + assert.ok(!new Position(1, 0).isBefore(new Position(0, 0))); + assert.ok(!new Position(0, 1).isBefore(new Position(0, 0))); + assert.ok(!new Position(0, 0).isBefore(new Position(0, 0))); + }); + + test("isAfter", () => { + assert.ok(new Position(1, 0).isAfter(new Position(0, 0))); + assert.ok(new Position(0, 1).isAfter(new Position(0, 0))); + assert.ok(!new Position(0, 0).isAfter(new Position(1, 0))); + assert.ok(!new Position(0, 0).isAfter(new Position(0, 1))); + assert.ok(!new Position(0, 0).isBefore(new Position(0, 0))); + }); + + test("isBeforeOrEqual", () => { + assert.ok(new Position(0, 0).isBeforeOrEqual(new Position(0, 0))); + assert.ok(new Position(0, 0).isBeforeOrEqual(new Position(1, 0))); + assert.ok(new Position(0, 0).isBeforeOrEqual(new Position(0, 1))); + }); + + test("isAfterOrEqual", () => { + assert.ok(new Position(0, 0).isAfterOrEqual(new Position(0, 0))); + assert.ok(new Position(1, 0).isAfterOrEqual(new Position(0, 0))); + assert.ok(new Position(0, 1).isAfterOrEqual(new Position(0, 0))); + }); + + test("compareTo", () => { + assert.equal(new Position(0, 0).compareTo(new Position(0, 0)), 0); + assert.equal(new Position(0, 0).compareTo(new Position(1, 0)), -1); + assert.equal(new Position(0, 0).compareTo(new Position(0, 1)), -1); + assert.equal(new Position(1, 0).compareTo(new Position(0, 0)), 1); + assert.equal(new Position(0, 1).compareTo(new Position(0, 0)), 1); + }); + + test("with", () => { + assert.ok( + new Position(1, 1).with(5, undefined).isEqual(new Position(5, 1)), + ); + assert.ok( + new Position(1, 1).with(undefined, 5).isEqual(new Position(1, 5)), + ); + }); + + test("translate", () => { + assert.ok( + new Position(1, 1).translate(5, undefined).isEqual(new Position(6, 1)), + ); + assert.ok( + new Position(1, 1).translate(undefined, 5).isEqual(new Position(1, 6)), + ); + }); +}); diff --git a/src/libs/common/types/range.test.ts b/src/libs/common/types/range.test.ts new file mode 100644 index 0000000000..64e6a84bbd --- /dev/null +++ b/src/libs/common/types/range.test.ts @@ -0,0 +1,116 @@ +import * as assert from "assert"; +import { Position, Range } from "@cursorless/common"; + +suite("Range", () => { + test("constructor", () => { + assert.equal(new Range(5, 0, 10, 0).start.line, 5); + assert.equal(new Range(0, 5, 0, 10).start.character, 5); + assert.equal(new Range(0, 0, 5, 0).end.line, 5); + assert.equal(new Range(0, 0, 0, 5).end.character, 5); + assert.equal(new Range(5, 0, 0, 0).start.line, 0); + assert.equal(new Range(0, 5, 0, 0).start.character, 0); + assert.equal(new Range(5, 0, 0, 0).end.line, 5); + assert.equal(new Range(0, 5, 0, 0).end.character, 5); + assert.ok( + new Range(new Position(1, 2), new Position(3, 4)).isRangeEqual( + new Range(1, 2, 3, 4), + ), + ); + }); + + test("isEmpty", () => { + assert.ok(new Range(0, 0, 0, 0).isEmpty); + assert.ok(!new Range(0, 0, 1, 0).isEmpty); + assert.ok(!new Range(0, 0, 0, 1).isEmpty); + }); + + test("isSingleLine", () => { + assert.ok(new Range(0, 0, 0, 0).isSingleLine); + assert.ok(new Range(0, 0, 0, 1).isSingleLine); + assert.ok(new Range(0, 1, 0, 2).isSingleLine); + assert.ok(!new Range(0, 0, 1, 0).isSingleLine); + assert.ok(!new Range(1, 0, 2, 0).isSingleLine); + }); + + test("isRangeEqual", () => { + assert.ok(new Range(0, 0, 0, 0).isRangeEqual(new Range(0, 0, 0, 0))); + assert.ok(new Range(1, 0, 0, 0).isRangeEqual(new Range(1, 0, 0, 0))); + assert.ok(new Range(0, 1, 0, 0).isRangeEqual(new Range(0, 1, 0, 0))); + assert.ok(new Range(0, 0, 1, 0).isRangeEqual(new Range(0, 0, 1, 0))); + assert.ok(new Range(0, 0, 0, 1).isRangeEqual(new Range(0, 0, 0, 1))); + assert.ok(!new Range(0, 0, 0, 0).isRangeEqual(new Range(1, 0, 0, 0))); + assert.ok(!new Range(0, 0, 0, 0).isRangeEqual(new Range(0, 1, 0, 0))); + assert.ok(!new Range(0, 0, 0, 0).isRangeEqual(new Range(0, 0, 1, 0))); + assert.ok(!new Range(0, 0, 0, 0).isRangeEqual(new Range(0, 0, 0, 1))); + }); + + test("contains", () => { + assert.ok(new Range(0, 0, 0, 0).contains(new Range(0, 0, 0, 0))); + assert.ok(new Range(0, 0, 4, 0).contains(new Range(1, 0, 2, 0))); + assert.ok(new Range(0, 0, 0, 4).contains(new Range(0, 1, 0, 2))); + assert.ok(new Range(0, 0, 0, 4).contains(new Range(0, 2, 0, 4))); + assert.ok(new Range(0, 0, 4, 0).contains(new Range(2, 0, 4, 0))); + assert.ok(new Range(0, 0, 0, 1).contains(new Range(0, 0, 0, 0))); + assert.ok(new Range(0, 0, 1, 0).contains(new Range(0, 0, 0, 0))); + assert.ok(new Range(0, 0, 0, 1).contains(new Range(0, 1, 0, 1))); + assert.ok(new Range(0, 0, 1, 0).contains(new Range(1, 0, 1, 0))); + assert.ok(!new Range(0, 0, 0, 0).contains(new Range(0, 0, 0, 1))); + assert.ok(!new Range(0, 0, 0, 0).contains(new Range(0, 0, 1, 0))); + assert.ok(!new Range(0, 0, 0, 1).contains(new Range(0, 1, 0, 2))); + assert.ok(!new Range(0, 1, 0, 2).contains(new Range(0, 0, 0, 1))); + assert.ok(new Range(0, 0, 0, 7).contains(new Position(0, 2))); + assert.ok(new Range(0, 0, 0, 1).contains(new Position(0, 1))); + assert.ok(!new Range(0, 0, 0, 1).contains(new Position(0, 2))); + }); + + test("intersection", () => { + assert.ok( + new Range(1, 2, 3, 4) + .intersection(new Range(1, 7, 5, 2)) + ?.isRangeEqual(new Range(1, 7, 3, 4)), + ); + assert.ok( + new Range(1, 2, 1, 6).intersection(new Range(1, 6, 5, 2))?.isEmpty, + ); + assert.equal( + new Range(1, 2, 1, 5).intersection(new Range(1, 6, 1, 9)), + undefined, + ); + }); + + test("with", () => { + assert.ok( + new Range(1, 2, 3, 4) + .with(new Position(4, 5), undefined) + .isRangeEqual(new Range(4, 5, 3, 4)), + ); + assert.ok( + new Range(1, 2, 3, 4) + .with(undefined, new Position(4, 5)) + .isRangeEqual(new Range(1, 2, 4, 5)), + ); + }); + + test("union", () => { + assert.ok( + new Range(1, 2, 3, 4) + .union(new Range(4, 2, 6, 1)) + .isRangeEqual(new Range(1, 2, 6, 1)), + ); + assert.ok( + new Range(1, 2, 3, 4) + .union(new Range(0, 1, 0, 1)) + .isRangeEqual(new Range(0, 1, 3, 4)), + ); + assert.ok( + new Range(1, 2, 3, 4) + .union(new Range(1, 3, 2, 4)) + .isRangeEqual(new Range(1, 2, 3, 4)), + ); + }); + + test("toSelection", () => { + assert.ok(new Range(1, 2, 3, 4).toSelection(true).isReversed); + assert.ok(!new Range(1, 2, 3, 4).toSelection(false).isReversed); + }); +}); diff --git a/src/libs/common/types/selection.test.ts b/src/libs/common/types/selection.test.ts new file mode 100644 index 0000000000..6d606350e2 --- /dev/null +++ b/src/libs/common/types/selection.test.ts @@ -0,0 +1,52 @@ +import * as assert from "assert"; +import { Position, Selection } from "@cursorless/common"; + +suite("Selection", () => { + test("constructor", () => { + assert.equal(new Selection(5, 0, 10, 0).anchor.line, 5); + assert.equal(new Selection(0, 5, 0, 10).anchor.character, 5); + assert.equal(new Selection(0, 0, 5, 0).active.line, 5); + assert.equal(new Selection(0, 0, 0, 5).active.character, 5); + assert.equal(new Selection(5, 0, 0, 0).active.line, 0); + assert.equal(new Selection(0, 5, 0, 0).active.character, 0); + assert.equal(new Selection(5, 0, 0, 0).anchor.line, 5); + assert.equal(new Selection(0, 5, 0, 0).anchor.character, 5); + assert.ok( + new Selection(new Position(1, 2), new Position(3, 4)).isEqual( + new Selection(1, 2, 3, 4), + ), + ); + }); + + test("isReversed", () => { + assert.ok(!new Selection(0, 0, 0, 0).isReversed); + assert.ok(new Selection(1, 0, 0, 0).isReversed); + assert.ok(new Selection(0, 1, 0, 0).isReversed); + assert.ok(!new Selection(0, 0, 1, 0).isReversed); + assert.ok(!new Selection(0, 0, 0, 1).isReversed); + }); + + test("isEqual", () => { + assert.ok(new Selection(0, 0, 0, 0).isEqual(new Selection(0, 0, 0, 0))); + assert.ok(new Selection(1, 0, 0, 0).isEqual(new Selection(1, 0, 0, 0))); + assert.ok(new Selection(0, 1, 0, 0).isEqual(new Selection(0, 1, 0, 0))); + assert.ok(new Selection(0, 0, 1, 0).isEqual(new Selection(0, 0, 1, 0))); + assert.ok(new Selection(0, 0, 0, 1).isEqual(new Selection(0, 0, 0, 1))); + assert.ok(!new Selection(0, 0, 0, 0).isEqual(new Selection(1, 0, 0, 0))); + assert.ok(!new Selection(0, 0, 0, 0).isEqual(new Selection(0, 1, 0, 0))); + assert.ok(!new Selection(0, 0, 0, 0).isEqual(new Selection(0, 0, 1, 0))); + assert.ok(!new Selection(0, 0, 0, 0).isEqual(new Selection(0, 0, 0, 1))); + assert.ok(!new Selection(0, 0, 0, 1).isEqual(new Selection(0, 1, 0, 0))); + }); + + test("isRangeEqual", () => { + assert.ok( + new Selection(0, 0, 0, 1).isRangeEqual(new Selection(0, 1, 0, 0)), + ); + }); + + test("toSelection", () => { + assert.ok(new Selection(1, 2, 3, 4).toSelection(true).isReversed); + assert.ok(!new Selection(1, 2, 3, 4).toSelection(false).isReversed); + }); +}); diff --git a/src/libs/vscode-common/getExtensionApi.ts b/src/libs/vscode-common/getExtensionApi.ts index f774cc3912..602e92ba2a 100644 --- a/src/libs/vscode-common/getExtensionApi.ts +++ b/src/libs/vscode-common/getExtensionApi.ts @@ -6,7 +6,7 @@ import type { Target } from "../../typings/target.types"; import type { Graph } from "../../typings/Types"; import type FakeIDE from "../common/ide/fake/FakeIDE"; import type { IDE } from "../common/ide/types/ide.types"; -import type { TargetPlainObject } from "./toPlainObject"; +import type { TargetPlainObject } from "./testUtil/toPlainObject"; interface TestHelpers { graph: Graph; diff --git a/src/libs/vscode-common/index.ts b/src/libs/vscode-common/index.ts index a88399b58a..e3d331a9df 100644 --- a/src/libs/vscode-common/index.ts +++ b/src/libs/vscode-common/index.ts @@ -1,7 +1,9 @@ export * from "./getExtensionApi"; export * from "./notebook"; -export * from "./toPlainObject"; +export * from "./testUtil/toPlainObject"; export * from "./testUtil/testConstants"; +export * from "./testUtil/openNewEditor"; +export * from "./vscodeUtil"; export { takeSnapshot, TestCaseSnapshot, diff --git a/src/apps/cursorless-vscode-e2e/openNewEditor.ts b/src/libs/vscode-common/testUtil/openNewEditor.ts similarity index 100% rename from src/apps/cursorless-vscode-e2e/openNewEditor.ts rename to src/libs/vscode-common/testUtil/openNewEditor.ts diff --git a/src/libs/vscode-common/testUtil/takeSnapshot.ts b/src/libs/vscode-common/testUtil/takeSnapshot.ts index 7f02284ca2..275b17df33 100644 --- a/src/libs/vscode-common/testUtil/takeSnapshot.ts +++ b/src/libs/vscode-common/testUtil/takeSnapshot.ts @@ -1,5 +1,8 @@ -import type { ThatMark } from "../../../core/ThatMark"; +import type { TextEditor } from "@cursorless/common"; import { hrtimeBigintToSeconds } from "@cursorless/common"; +import type { ThatMark } from "../../../core/ThatMark"; +import type { Clipboard } from "../../common/ide/types/Clipboard"; +import type { IDE } from "../../common/ide/types/ide.types"; import { RangePlainObject, rangeToPlainObject, @@ -8,10 +11,7 @@ import { SerializedMarks, TargetPlainObject, targetToPlainObject, -} from "../toPlainObject"; -import { TextEditor } from "vscode"; -import type { IDE } from "../../common/ide/types/ide.types"; -import type { Clipboard } from "../../common/ide/types/Clipboard"; +} from "./toPlainObject"; export type ExtraSnapshotField = keyof TestCaseSnapshot; export type ExcludableSnapshotField = keyof TestCaseSnapshot; diff --git a/src/libs/vscode-common/testUtil/testConstants.ts b/src/libs/vscode-common/testUtil/testConstants.ts index 22bc06de80..26c9692115 100644 --- a/src/libs/vscode-common/testUtil/testConstants.ts +++ b/src/libs/vscode-common/testUtil/testConstants.ts @@ -1,6 +1,6 @@ -import * as vscode from "vscode"; +import type { TextEditorOptions } from "@cursorless/common"; -export const DEFAULT_TEXT_EDITOR_OPTIONS_FOR_TEST: vscode.TextEditorOptions = { +export const DEFAULT_TEXT_EDITOR_OPTIONS_FOR_TEST: TextEditorOptions = { tabSize: 4, insertSpaces: true, }; diff --git a/src/libs/vscode-common/toPlainObject.ts b/src/libs/vscode-common/testUtil/toPlainObject.ts similarity index 92% rename from src/libs/vscode-common/toPlainObject.ts rename to src/libs/vscode-common/testUtil/toPlainObject.ts index 85a72bd393..28ff8c84c8 100644 --- a/src/libs/vscode-common/toPlainObject.ts +++ b/src/libs/vscode-common/testUtil/toPlainObject.ts @@ -1,7 +1,7 @@ -import type { Position, Range, Selection } from "vscode"; -import type { TestDecoration } from "../../core/editStyles"; -import type { Target } from "../../typings/target.types"; -import type { Token } from "../../typings/Types"; +import type { TestDecoration } from "../../../core/editStyles"; +import type { Target } from "../../../typings/target.types"; +import type { Token } from "../../../typings/Types"; +import type { Range, Selection, Position } from "@cursorless/common"; export type PositionPlainObject = { line: number; diff --git a/src/libs/vscode-common/vscodeUtil.ts b/src/libs/vscode-common/vscodeUtil.ts new file mode 100644 index 0000000000..bf8077363f --- /dev/null +++ b/src/libs/vscode-common/vscodeUtil.ts @@ -0,0 +1,76 @@ +import { + EndOfLine, + Position, + Range, + Selection, + TextEditor, +} from "@cursorless/common"; +import * as vscode from "vscode"; +import type { VscodeTextEditorImpl } from "../../ide/vscode/VscodeTextEditorImpl"; + +export function toVscodeRange(range: Range): vscode.Range { + return new vscode.Range( + range.start.line, + range.start.character, + range.end.line, + range.end.character, + ); +} + +export function fromVscodeRange(range: vscode.Range): Range { + return new Range( + range.start.line, + range.start.character, + range.end.line, + range.end.character, + ); +} + +export function toVscodeSelection(range: Selection): vscode.Selection { + return new vscode.Selection( + range.anchor.line, + range.anchor.character, + range.active.line, + range.active.character, + ); +} + +export function fromVscodeSelection(range: vscode.Selection): Selection { + return new Selection( + range.anchor.line, + range.anchor.character, + range.active.line, + range.active.character, + ); +} + +export function toVscodePosition(position: Position): vscode.Position { + return new vscode.Position(position.line, position.character); +} + +export function fromVscodePosition(position: vscode.Position): Position { + return new Position(position.line, position.character); +} + +export function toVscodePositionOrRange( + location: Position | Range, +): vscode.Position | vscode.Range { + return location instanceof Position + ? toVscodePosition(location) + : toVscodeRange(location); +} + +export function toVscodeEndOfLine(eol: EndOfLine): vscode.EndOfLine { + return eol === "LF" ? vscode.EndOfLine.LF : vscode.EndOfLine.CRLF; +} + +export function fromVscodeEndOfLine(eol: vscode.EndOfLine): EndOfLine { + return eol === vscode.EndOfLine.LF ? "LF" : "CRLF"; +} + +export function toVscodeEditor(editor: TextEditor): vscode.TextEditor { + if ("vscodeEditor" in editor) { + return (editor as VscodeTextEditorImpl).vscodeEditor; + } + throw Error("Can't get vscode editor from non vscode implementation"); +} diff --git a/src/processTargets/marks/CursorStage.ts b/src/processTargets/marks/CursorStage.ts index 6664439c06..ebf3049cae 100644 --- a/src/processTargets/marks/CursorStage.ts +++ b/src/processTargets/marks/CursorStage.ts @@ -1,7 +1,6 @@ import type { Target } from "../../typings/target.types"; import type { CursorMark } from "../../typings/targetDescriptor.types"; import type { ProcessedTargetsContext } from "../../typings/Types"; -import { isReversed } from "../../util/selectionUtils"; import type { MarkStage } from "../PipelineStages.types"; import { UntypedTarget } from "../targets"; @@ -13,7 +12,7 @@ export default class CursorStage implements MarkStage { (selection) => new UntypedTarget({ editor: selection.editor, - isReversed: isReversed(selection.selection), + isReversed: selection.selection.isReversed, contentRange: selection.selection, hasExplicitRange: !selection.selection.isEmpty, }), diff --git a/src/processTargets/marks/LineNumberStage.ts b/src/processTargets/marks/LineNumberStage.ts index 6e67da3928..81bc962df9 100644 --- a/src/processTargets/marks/LineNumberStage.ts +++ b/src/processTargets/marks/LineNumberStage.ts @@ -1,4 +1,4 @@ -import type { TextEditor } from "vscode"; +import { TextEditor } from "@cursorless/common"; import type { LineNumberMark, LineNumberType, @@ -35,7 +35,7 @@ const getLineNumber = ( case "absolute": return lineNumber; case "relative": - return editor.selection.active.line + lineNumber; + return editor.selections[0].active.line + lineNumber; case "modulo100": { const stepSize = 100; const startLine = editor.visibleRanges[0].start.line; diff --git a/src/processTargets/modifiers/ContainingScopeStage.ts b/src/processTargets/modifiers/ContainingScopeStage.ts index 737d13f63f..4b74ec87da 100644 --- a/src/processTargets/modifiers/ContainingScopeStage.ts +++ b/src/processTargets/modifiers/ContainingScopeStage.ts @@ -1,3 +1,4 @@ +import { Position, TextEditor } from "@cursorless/common"; import { NoContainingScopeError } from "../../errors"; import type { Target } from "../../typings/target.types"; import type { @@ -5,14 +6,13 @@ import type { Direction, } from "../../typings/targetDescriptor.types"; import type { ProcessedTargetsContext } from "../../typings/Types"; -import getScopeHandler from "./scopeHandlers/getScopeHandler"; import type { ModifierStage } from "../PipelineStages.types"; import { constructScopeRangeTarget } from "./constructScopeRangeTarget"; +import { getContainingScope } from "./getContainingScope"; import getLegacyScopeStage from "./getLegacyScopeStage"; +import getScopeHandler from "./scopeHandlers/getScopeHandler"; import { TargetScope } from "./scopeHandlers/scope.types"; -import { TextEditor, Position } from "vscode"; import { ScopeHandler } from "./scopeHandlers/scopeHandler.types"; -import { getContainingScope } from "./getContainingScope"; /** * This modifier stage expands from the input target to the smallest containing diff --git a/src/processTargets/modifiers/EveryScopeStage.ts b/src/processTargets/modifiers/EveryScopeStage.ts index 3d0a728fa3..e859cf816d 100644 --- a/src/processTargets/modifiers/EveryScopeStage.ts +++ b/src/processTargets/modifiers/EveryScopeStage.ts @@ -1,4 +1,4 @@ -import { Range } from "vscode"; +import { Range } from "@cursorless/common"; import { NoContainingScopeError } from "../../errors"; import type { Target } from "../../typings/target.types"; import type { EveryScopeModifier } from "../../typings/targetDescriptor.types"; diff --git a/src/processTargets/modifiers/HeadTailStage.ts b/src/processTargets/modifiers/HeadTailStage.ts index 9f91024cf6..1b46ac2d7f 100644 --- a/src/processTargets/modifiers/HeadTailStage.ts +++ b/src/processTargets/modifiers/HeadTailStage.ts @@ -1,4 +1,4 @@ -import { Range } from "vscode"; +import { Range } from "@cursorless/common"; import { Target } from "../../typings/target.types"; import { HeadTailModifier, diff --git a/src/processTargets/modifiers/ItemStage/ItemStage.ts b/src/processTargets/modifiers/ItemStage/ItemStage.ts index 37cff7fe75..0f2b3424f8 100644 --- a/src/processTargets/modifiers/ItemStage/ItemStage.ts +++ b/src/processTargets/modifiers/ItemStage/ItemStage.ts @@ -1,4 +1,4 @@ -import { Range, TextEditor } from "vscode"; +import { Range, TextEditor } from "@cursorless/common"; import { NoContainingScopeError } from "../../../errors"; import { Target } from "../../../typings/target.types"; import { diff --git a/src/processTargets/modifiers/ItemStage/getIterationScope.ts b/src/processTargets/modifiers/ItemStage/getIterationScope.ts index fbe75b5ce0..e0d1831fad 100644 --- a/src/processTargets/modifiers/ItemStage/getIterationScope.ts +++ b/src/processTargets/modifiers/ItemStage/getIterationScope.ts @@ -1,4 +1,4 @@ -import { Range, TextEditor } from "vscode"; +import { Range, TextEditor } from "@cursorless/common"; import { Target } from "../../../typings/target.types"; import { ProcessedTargetsContext } from "../../../typings/Types"; import { fitRangeToLineContent } from "../scopeHandlers"; diff --git a/src/processTargets/modifiers/ItemStage/tokenizeRange.ts b/src/processTargets/modifiers/ItemStage/tokenizeRange.ts index 2101290aca..4bbaf87673 100644 --- a/src/processTargets/modifiers/ItemStage/tokenizeRange.ts +++ b/src/processTargets/modifiers/ItemStage/tokenizeRange.ts @@ -1,4 +1,4 @@ -import { Range, TextEditor } from "vscode"; +import { Range, TextEditor } from "@cursorless/common"; /** * Given the iteration scope, returns a list of "tokens" within that collection diff --git a/src/processTargets/modifiers/RelativeInclusiveScopeStage.ts b/src/processTargets/modifiers/RelativeInclusiveScopeStage.ts index dc50118b37..79bd7f796e 100644 --- a/src/processTargets/modifiers/RelativeInclusiveScopeStage.ts +++ b/src/processTargets/modifiers/RelativeInclusiveScopeStage.ts @@ -1,4 +1,4 @@ -import type { Range, TextEditor } from "vscode"; +import { Range, TextEditor } from "@cursorless/common"; import { NoContainingScopeError } from "../../errors"; import type { Target } from "../../typings/target.types"; import type { diff --git a/src/processTargets/modifiers/getContainingScope.ts b/src/processTargets/modifiers/getContainingScope.ts index fb42246251..95539ba8a4 100644 --- a/src/processTargets/modifiers/getContainingScope.ts +++ b/src/processTargets/modifiers/getContainingScope.ts @@ -1,5 +1,5 @@ +import { TextEditor, Position } from "@cursorless/common"; import { Direction } from "../../typings/targetDescriptor.types"; -import { TextEditor, Position } from "vscode"; import { ScopeHandler } from "./scopeHandlers/scopeHandler.types"; /** diff --git a/src/processTargets/modifiers/relativeScopeLegacy.ts b/src/processTargets/modifiers/relativeScopeLegacy.ts index 030b79c867..0044008c75 100644 --- a/src/processTargets/modifiers/relativeScopeLegacy.ts +++ b/src/processTargets/modifiers/relativeScopeLegacy.ts @@ -1,5 +1,5 @@ +import { Range } from "@cursorless/common"; import { findLastIndex } from "lodash"; -import { Range } from "vscode"; import { Target } from "../../typings/target.types"; import { RelativeScopeModifier } from "../../typings/targetDescriptor.types"; import { ProcessedTargetsContext } from "../../typings/Types"; diff --git a/src/processTargets/modifiers/scopeHandlers/BaseScopeHandler.ts b/src/processTargets/modifiers/scopeHandlers/BaseScopeHandler.ts index 8402452496..aeaeec31e2 100644 --- a/src/processTargets/modifiers/scopeHandlers/BaseScopeHandler.ts +++ b/src/processTargets/modifiers/scopeHandlers/BaseScopeHandler.ts @@ -1,5 +1,5 @@ // eslint-disable-next-line @typescript-eslint/no-unused-vars -import type { Position, Range, TextEditor } from "vscode"; +import { Position, Range, TextEditor } from "@cursorless/common"; import type { Direction, ScopeType, diff --git a/src/processTargets/modifiers/scopeHandlers/DocumentScopeHandler.ts b/src/processTargets/modifiers/scopeHandlers/DocumentScopeHandler.ts index e3e0f60d90..1cc7e70649 100644 --- a/src/processTargets/modifiers/scopeHandlers/DocumentScopeHandler.ts +++ b/src/processTargets/modifiers/scopeHandlers/DocumentScopeHandler.ts @@ -1,6 +1,5 @@ -import { Position, TextEditor } from "vscode"; +import { TextEditor, Position } from "@cursorless/common"; import { Direction, ScopeType } from "../../../typings/targetDescriptor.types"; -import { getDocumentRange } from "../../../util/rangeUtils"; import { DocumentTarget } from "../../targets"; import BaseScopeHandler from "./BaseScopeHandler"; import { TargetScope } from "./scope.types"; @@ -19,7 +18,7 @@ export default class DocumentScopeHandler extends BaseScopeHandler { _position: Position, _direction: Direction, ): Iterable { - const contentRange = getDocumentRange(editor.document); + const contentRange = editor.document.range; yield { editor, diff --git a/src/processTargets/modifiers/scopeHandlers/LineScopeHandler.ts b/src/processTargets/modifiers/scopeHandlers/LineScopeHandler.ts index c9b88b2921..03ef92d369 100644 --- a/src/processTargets/modifiers/scopeHandlers/LineScopeHandler.ts +++ b/src/processTargets/modifiers/scopeHandlers/LineScopeHandler.ts @@ -1,4 +1,4 @@ -import { Position, Range, TextEditor } from "vscode"; +import { Position, Range, TextEditor } from "@cursorless/common"; import { Direction, ScopeType } from "../../../typings/targetDescriptor.types"; import { LineTarget } from "../../targets"; import BaseScopeHandler from "./BaseScopeHandler"; @@ -58,14 +58,11 @@ export function createLineTarget( export function fitRangeToLineContent(editor: TextEditor, range: Range) { const startLine = editor.document.lineAt(range.start); const endLine = editor.document.lineAt(range.end); - const endCharacterIndex = - endLine.range.end.character - - (endLine.text.length - endLine.text.trimEnd().length); return new Range( startLine.lineNumber, startLine.firstNonWhitespaceCharacterIndex, endLine.lineNumber, - endCharacterIndex, + endLine.lastNonWhitespaceCharacterIndex, ); } diff --git a/src/processTargets/modifiers/scopeHandlers/NestedScopeHandler.ts b/src/processTargets/modifiers/scopeHandlers/NestedScopeHandler.ts index 595cd7aab1..03368fb14e 100644 --- a/src/processTargets/modifiers/scopeHandlers/NestedScopeHandler.ts +++ b/src/processTargets/modifiers/scopeHandlers/NestedScopeHandler.ts @@ -1,5 +1,5 @@ +import { Position, TextEditor } from "@cursorless/common"; import { flatten, imap } from "itertools"; -import type { Position, TextEditor } from "vscode"; import { getScopeHandler } from "."; import type { Direction, diff --git a/src/processTargets/modifiers/scopeHandlers/OneOfScopeHandler.ts b/src/processTargets/modifiers/scopeHandlers/OneOfScopeHandler.ts index 5652aaa634..9965ea1c93 100644 --- a/src/processTargets/modifiers/scopeHandlers/OneOfScopeHandler.ts +++ b/src/processTargets/modifiers/scopeHandlers/OneOfScopeHandler.ts @@ -1,5 +1,5 @@ -import { Position, TextEditor } from "vscode"; import { getScopeHandler } from "."; +import { TextEditor, Position } from "@cursorless/common"; import { Direction, OneOfScopeType, diff --git a/src/processTargets/modifiers/scopeHandlers/ParagraphScopeHandler.ts b/src/processTargets/modifiers/scopeHandlers/ParagraphScopeHandler.ts index 0452ddc816..072a87d55e 100644 --- a/src/processTargets/modifiers/scopeHandlers/ParagraphScopeHandler.ts +++ b/src/processTargets/modifiers/scopeHandlers/ParagraphScopeHandler.ts @@ -1,4 +1,10 @@ -import { Position, Range, TextDocument, TextEditor, TextLine } from "vscode"; +import { + Position, + Range, + TextDocument, + TextEditor, + TextLine, +} from "@cursorless/common"; import { Direction, ScopeType } from "../../../typings/targetDescriptor.types"; import { ParagraphTarget } from "../../targets"; import BaseScopeHandler from "./BaseScopeHandler"; diff --git a/src/processTargets/modifiers/scopeHandlers/SurroundingPairScopeHandler.ts b/src/processTargets/modifiers/scopeHandlers/SurroundingPairScopeHandler.ts index d3fd41eaf4..65064aa986 100644 --- a/src/processTargets/modifiers/scopeHandlers/SurroundingPairScopeHandler.ts +++ b/src/processTargets/modifiers/scopeHandlers/SurroundingPairScopeHandler.ts @@ -1,4 +1,4 @@ -import { Position, TextEditor } from "vscode"; +import { Position, TextEditor } from "@cursorless/common"; import { Direction, SurroundingPairScopeType, diff --git a/src/processTargets/modifiers/scopeHandlers/WordScopeHandler.ts b/src/processTargets/modifiers/scopeHandlers/WordScopeHandler.ts index 8e2d7ae7a6..5fb4deb3e8 100644 --- a/src/processTargets/modifiers/scopeHandlers/WordScopeHandler.ts +++ b/src/processTargets/modifiers/scopeHandlers/WordScopeHandler.ts @@ -1,9 +1,9 @@ -import { Range, TextEditor } from "vscode"; +import { Range, TextEditor } from "@cursorless/common"; import { NestedScopeHandler } from "."; +import WordTokenizer from "../../../libs/cursorless-engine/scopeHandlers/WordScopeHandler/WordTokenizer"; import { Direction } from "../../../typings/targetDescriptor.types"; import { SubTokenWordTarget } from "../../targets"; import type { TargetScope } from "./scope.types"; -import WordTokenizer from "../../../libs/cursorless-engine/scopeHandlers/WordScopeHandler/WordTokenizer"; export default class WordScopeHandler extends NestedScopeHandler { public readonly scopeType = { type: "word" } as const; diff --git a/src/processTargets/modifiers/scopeHandlers/compareTargetScopes.ts b/src/processTargets/modifiers/scopeHandlers/compareTargetScopes.ts index bc4df11ad7..caa6ea692c 100644 --- a/src/processTargets/modifiers/scopeHandlers/compareTargetScopes.ts +++ b/src/processTargets/modifiers/scopeHandlers/compareTargetScopes.ts @@ -1,4 +1,4 @@ -import { Position, Range } from "vscode"; +import { Position, Range } from "@cursorless/common"; import { Direction } from "../../../typings/targetDescriptor.types"; import { TargetScope } from "./scope.types"; diff --git a/src/processTargets/modifiers/scopeHandlers/getScopeRelativeToPosition.ts b/src/processTargets/modifiers/scopeHandlers/getScopeRelativeToPosition.ts index dfd9a6defc..36fe466c95 100644 --- a/src/processTargets/modifiers/scopeHandlers/getScopeRelativeToPosition.ts +++ b/src/processTargets/modifiers/scopeHandlers/getScopeRelativeToPosition.ts @@ -1,4 +1,4 @@ -import { Position, TextEditor } from "vscode"; +import { Position, TextEditor } from "@cursorless/common"; import { Direction } from "../../../typings/targetDescriptor.types"; import { OutOfRangeError } from "../targetSequenceUtils"; import { TargetScope } from "./scope.types"; diff --git a/src/processTargets/modifiers/scopeHandlers/getScopesOverlappingRange.ts b/src/processTargets/modifiers/scopeHandlers/getScopesOverlappingRange.ts index 2764c3a689..d937b26755 100644 --- a/src/processTargets/modifiers/scopeHandlers/getScopesOverlappingRange.ts +++ b/src/processTargets/modifiers/scopeHandlers/getScopesOverlappingRange.ts @@ -1,4 +1,4 @@ -import { Range, TextEditor } from "vscode"; +import { Range, TextEditor } from "@cursorless/common"; import { TargetScope } from "./scope.types"; import { ScopeHandler } from "./scopeHandler.types"; diff --git a/src/processTargets/modifiers/scopeHandlers/scope.types.ts b/src/processTargets/modifiers/scopeHandlers/scope.types.ts index 6f6d02e685..d253547d8a 100644 --- a/src/processTargets/modifiers/scopeHandlers/scope.types.ts +++ b/src/processTargets/modifiers/scopeHandlers/scope.types.ts @@ -1,4 +1,4 @@ -import type { Range, TextEditor } from "vscode"; +import { Range, TextEditor } from "@cursorless/common"; import type { Target } from "../../../typings/target.types"; /** diff --git a/src/processTargets/modifiers/scopeHandlers/scopeHandler.types.ts b/src/processTargets/modifiers/scopeHandlers/scopeHandler.types.ts index 2eff08ac6e..490619fb33 100644 --- a/src/processTargets/modifiers/scopeHandlers/scopeHandler.types.ts +++ b/src/processTargets/modifiers/scopeHandlers/scopeHandler.types.ts @@ -1,4 +1,4 @@ -import type { Position, TextEditor } from "vscode"; +import type { Position, TextEditor } from "@cursorless/common"; import type { Direction, ScopeType, diff --git a/src/processTargets/modifiers/scopeHandlers/shouldYieldScope.ts b/src/processTargets/modifiers/scopeHandlers/shouldYieldScope.ts index 0e4d06797b..33585f917a 100644 --- a/src/processTargets/modifiers/scopeHandlers/shouldYieldScope.ts +++ b/src/processTargets/modifiers/scopeHandlers/shouldYieldScope.ts @@ -1,4 +1,4 @@ -import { Position } from "vscode"; +import { Position } from "@cursorless/common"; import { Direction } from "../../../typings/targetDescriptor.types"; import { strictlyContains } from "../../../util/rangeUtils"; import { compareTargetScopes } from "./compareTargetScopes"; diff --git a/src/processTargets/modifiers/scopeTypeStages/ContainingSyntaxScopeStage.ts b/src/processTargets/modifiers/scopeTypeStages/ContainingSyntaxScopeStage.ts index 3c4e13aef4..da29e7c281 100644 --- a/src/processTargets/modifiers/scopeTypeStages/ContainingSyntaxScopeStage.ts +++ b/src/processTargets/modifiers/scopeTypeStages/ContainingSyntaxScopeStage.ts @@ -1,4 +1,4 @@ -import { Location, Selection } from "vscode"; +import { Selection } from "@cursorless/common"; import type { SyntaxNode } from "web-tree-sitter"; import { NoContainingScopeError } from "../../../errors"; import { getNodeMatcher } from "../../../languages/getNodeMatcher"; @@ -39,7 +39,8 @@ export default class implements ModifierStage { ); const node: SyntaxNode | null = context.getNodeAtLocation( - new Location(target.editor.document.uri, target.contentRange), + target.editor.document, + target.contentRange, ); const scopeNodes = findNearestContainingAncestorNode(node, nodeMatcher, { diff --git a/src/processTargets/modifiers/scopeTypeStages/RegexStage.ts b/src/processTargets/modifiers/scopeTypeStages/RegexStage.ts index 7c62be2dbf..632502cfad 100644 --- a/src/processTargets/modifiers/scopeTypeStages/RegexStage.ts +++ b/src/processTargets/modifiers/scopeTypeStages/RegexStage.ts @@ -1,4 +1,4 @@ -import { Position, Range, TextEditor } from "vscode"; +import { Position, Range, TextEditor } from "@cursorless/common"; import { NoContainingScopeError } from "../../../errors"; import { Target } from "../../../typings/target.types"; import { diff --git a/src/processTargets/modifiers/surroundingPair/extractSelectionFromSurroundingPairOffsets.ts b/src/processTargets/modifiers/surroundingPair/extractSelectionFromSurroundingPairOffsets.ts index d488ea7e0e..a25fbf334c 100644 --- a/src/processTargets/modifiers/surroundingPair/extractSelectionFromSurroundingPairOffsets.ts +++ b/src/processTargets/modifiers/surroundingPair/extractSelectionFromSurroundingPairOffsets.ts @@ -1,4 +1,4 @@ -import { Range, Selection, TextDocument } from "vscode"; +import { Range, Selection, TextDocument } from "@cursorless/common"; import { SurroundingPairOffsets } from "./types"; export interface SurroundingPairInfo { diff --git a/src/processTargets/modifiers/surroundingPair/findSurroundingPairParseTreeBased.ts b/src/processTargets/modifiers/surroundingPair/findSurroundingPairParseTreeBased.ts index 62feee0608..090ab61d04 100644 --- a/src/processTargets/modifiers/surroundingPair/findSurroundingPairParseTreeBased.ts +++ b/src/processTargets/modifiers/surroundingPair/findSurroundingPairParseTreeBased.ts @@ -1,4 +1,4 @@ -import { Range, TextDocument, TextEditor } from "vscode"; +import { Range, TextDocument, TextEditor } from "@cursorless/common"; import { SyntaxNode } from "web-tree-sitter"; import { SimpleSurroundingPairName, diff --git a/src/processTargets/modifiers/surroundingPair/findSurroundingPairTextBased.ts b/src/processTargets/modifiers/surroundingPair/findSurroundingPairTextBased.ts index 70bd746853..a73ca236dc 100644 --- a/src/processTargets/modifiers/surroundingPair/findSurroundingPairTextBased.ts +++ b/src/processTargets/modifiers/surroundingPair/findSurroundingPairTextBased.ts @@ -1,12 +1,11 @@ +import { Range, TextDocument, TextEditor } from "@cursorless/common"; import { escapeRegExp, findLast, uniq } from "lodash"; -import { Range, TextDocument, TextEditor } from "vscode"; +import { matchAll } from "../../../libs/cursorless-engine/util/regex"; import { SimpleSurroundingPairName, SurroundingPairName, SurroundingPairScopeType, } from "../../../typings/targetDescriptor.types"; -import { getDocumentRange } from "../../../util/rangeUtils"; -import { matchAll } from "../../../libs/cursorless-engine/util/regex"; import { extractSelectionFromSurroundingPairOffsets } from "./extractSelectionFromSurroundingPairOffsets"; import { findSurroundingPairCore } from "./findSurroundingPairCore"; import { getIndividualDelimiters } from "./getIndividualDelimiters"; @@ -73,7 +72,7 @@ export function findSurroundingPairTextBased( scopeType: SurroundingPairScopeType, ) { const document: TextDocument = editor.document; - const fullRange = allowableRange ?? getDocumentRange(document); + const fullRange = allowableRange ?? document.range; const individualDelimiters = getIndividualDelimiters(delimiters); diff --git a/src/processTargets/modifiers/surroundingPair/index.ts b/src/processTargets/modifiers/surroundingPair/index.ts index e42e06c2f2..a0472de3ca 100644 --- a/src/processTargets/modifiers/surroundingPair/index.ts +++ b/src/processTargets/modifiers/surroundingPair/index.ts @@ -1,4 +1,4 @@ -import { Location, Range, Selection, TextEditor } from "vscode"; +import { Range, Selection, TextEditor } from "@cursorless/common"; import { SyntaxNode } from "web-tree-sitter"; import getTextFragmentExtractor, { TextFragmentExtractor, @@ -42,7 +42,7 @@ export function processSurroundingPair( let textFragmentExtractor: TextFragmentExtractor; try { - node = context.getNodeAtLocation(new Location(document.uri, range)); + node = context.getNodeAtLocation(document, range); textFragmentExtractor = getTextFragmentExtractor(document.languageId); } catch (err) { diff --git a/src/processTargets/modifiers/toPositionTarget.ts b/src/processTargets/modifiers/toPositionTarget.ts index 352dd901bc..fb48c6f6f8 100644 --- a/src/processTargets/modifiers/toPositionTarget.ts +++ b/src/processTargets/modifiers/toPositionTarget.ts @@ -1,4 +1,4 @@ -import { Range } from "vscode"; +import { Range } from "@cursorless/common"; import { Target } from "../../typings/target.types"; import { Position } from "../../typings/targetDescriptor.types"; import { PositionTarget } from "../targets"; diff --git a/src/processTargets/processTargets.ts b/src/processTargets/processTargets.ts index d272148a80..166d421fad 100644 --- a/src/processTargets/processTargets.ts +++ b/src/processTargets/processTargets.ts @@ -1,5 +1,5 @@ +import { Range } from "@cursorless/common"; import { uniqWith, zip } from "lodash"; -import { Range } from "vscode"; import { Target } from "../typings/target.types"; import { Modifier, diff --git a/src/processTargets/targetUtil/createContinuousRange.ts b/src/processTargets/targetUtil/createContinuousRange.ts index 8cd0a1cb94..81bf430b97 100644 --- a/src/processTargets/targetUtil/createContinuousRange.ts +++ b/src/processTargets/targetUtil/createContinuousRange.ts @@ -1,4 +1,4 @@ -import { Position, Range } from "vscode"; +import { Position, Range } from "@cursorless/common"; import type { Target } from "../../typings/target.types"; import { UntypedTarget } from "../targets"; diff --git a/src/processTargets/targetUtil/insertionRemovalBehaviors/DelimitedSequenceInsertionRemovalBehavior.ts b/src/processTargets/targetUtil/insertionRemovalBehaviors/DelimitedSequenceInsertionRemovalBehavior.ts index 639490d093..a6f3cb7b40 100644 --- a/src/processTargets/targetUtil/insertionRemovalBehaviors/DelimitedSequenceInsertionRemovalBehavior.ts +++ b/src/processTargets/targetUtil/insertionRemovalBehaviors/DelimitedSequenceInsertionRemovalBehavior.ts @@ -1,4 +1,4 @@ -import { Range } from "vscode"; +import { Range } from "@cursorless/common"; import { Target } from "../../../typings/target.types"; /** diff --git a/src/processTargets/targetUtil/insertionRemovalBehaviors/TokenInsertionRemovalBehavior.ts b/src/processTargets/targetUtil/insertionRemovalBehaviors/TokenInsertionRemovalBehavior.ts index e303596a88..174e5f6d25 100644 --- a/src/processTargets/targetUtil/insertionRemovalBehaviors/TokenInsertionRemovalBehavior.ts +++ b/src/processTargets/targetUtil/insertionRemovalBehaviors/TokenInsertionRemovalBehavior.ts @@ -1,7 +1,7 @@ -import { Range, TextDocument, TextEditor } from "vscode"; +import { Range, TextDocument, TextEditor } from "@cursorless/common"; import { tokenize } from "../../../libs/cursorless-engine/tokenizer"; import type { Target } from "../../../typings/target.types"; -import { expandToFullLine, makeEmptyRange } from "../../../util/rangeUtils"; +import { expandToFullLine } from "../../../util/rangeUtils"; import { PlainTarget } from "../../targets"; export function getTokenLeadingDelimiterTarget( @@ -65,15 +65,17 @@ export function getTokenRemovalRange(target: Target): Range { const { start, end } = contentRange; const leadingWhitespaceRange = - target.getLeadingDelimiterTarget()?.contentRange ?? makeEmptyRange(start); + target.getLeadingDelimiterTarget()?.contentRange ?? start.toEmptyRange(); const trailingWhitespaceRange = - target.getTrailingDelimiterTarget()?.contentRange ?? makeEmptyRange(end); + target.getTrailingDelimiterTarget()?.contentRange ?? end.toEmptyRange(); const fullLineRange = expandToFullLine(editor, contentRange); if ( - leadingWhitespaceRange.union(trailingWhitespaceRange).isEqual(fullLineRange) + leadingWhitespaceRange + .union(trailingWhitespaceRange) + .isRangeEqual(fullLineRange) ) { // If we would just be leaving a line with whitespace on it, we delete the // whitespace diff --git a/src/processTargets/targetUtil/insertionRemovalBehaviors/insertionRemovalBehavior.types.ts b/src/processTargets/targetUtil/insertionRemovalBehaviors/insertionRemovalBehavior.types.ts index 5a4c89d1eb..b81905401d 100644 --- a/src/processTargets/targetUtil/insertionRemovalBehaviors/insertionRemovalBehavior.types.ts +++ b/src/processTargets/targetUtil/insertionRemovalBehaviors/insertionRemovalBehavior.types.ts @@ -1,5 +1,5 @@ -import { Range } from "vscode"; -import { Target } from "../../../typings/target.types"; +import type { Range } from "@cursorless/common"; +import type { Target } from "../../../typings/target.types"; export default interface InsertionRemovalBehavior { getLeadingDelimiterTarget(): Target | undefined; diff --git a/src/processTargets/targets/BaseTarget.ts b/src/processTargets/targets/BaseTarget.ts index 32e4cfceae..e23b4c7a50 100644 --- a/src/processTargets/targets/BaseTarget.ts +++ b/src/processTargets/targets/BaseTarget.ts @@ -1,10 +1,9 @@ +import { Range, Selection, TextEditor } from "@cursorless/common"; import { isEqual } from "lodash"; -import { Range, Selection, TextEditor } from "vscode"; import { NoContainingScopeError } from "../../errors"; import type { EditNewContext, Target } from "../../typings/target.types"; import type { Position } from "../../typings/targetDescriptor.types"; import type { EditWithRangeUpdater } from "../../typings/Types"; -import { selectionFromRange } from "../../util/selectionUtils"; import { isSameType } from "../../util/typeUtils"; import { toPositionTarget } from "../modifiers/toPositionTarget"; import { @@ -60,7 +59,7 @@ export default abstract class BaseTarget implements Target { } get contentSelection(): Selection { - return selectionFromRange(this.isReversed, this.contentRange); + return this.contentRange.toSelection(this.isReversed); } get contentRange(): Range { diff --git a/src/processTargets/targets/DocumentTarget.ts b/src/processTargets/targets/DocumentTarget.ts index 4379e55081..6a6166ceba 100644 --- a/src/processTargets/targets/DocumentTarget.ts +++ b/src/processTargets/targets/DocumentTarget.ts @@ -1,4 +1,4 @@ -import { Range } from "vscode"; +import { Range } from "@cursorless/common"; import { shrinkRangeToFitContent } from "../../util/selectionUtils"; import BaseTarget, { CommonTargetParameters } from "./BaseTarget"; import PlainTarget from "./PlainTarget"; diff --git a/src/processTargets/targets/InteriorTarget.ts b/src/processTargets/targets/InteriorTarget.ts index 08e2e0a1a9..772acd357c 100644 --- a/src/processTargets/targets/InteriorTarget.ts +++ b/src/processTargets/targets/InteriorTarget.ts @@ -1,4 +1,4 @@ -import { Range } from "vscode"; +import { Range } from "@cursorless/common"; import { Target } from "../../typings/target.types"; import { shrinkRangeToFitContent } from "../../util/selectionUtils"; import { isSameType } from "../../util/typeUtils"; diff --git a/src/processTargets/targets/LineTarget.ts b/src/processTargets/targets/LineTarget.ts index 1efdb76ee3..b4d39d829c 100644 --- a/src/processTargets/targets/LineTarget.ts +++ b/src/processTargets/targets/LineTarget.ts @@ -1,4 +1,4 @@ -import { Position, Range, TextEditor } from "vscode"; +import { Position, Range, TextEditor } from "@cursorless/common"; import { Target } from "../../typings/target.types"; import { expandToFullLine } from "../../util/rangeUtils"; import { tryConstructPlainTarget } from "../../util/tryConstructTarget"; diff --git a/src/processTargets/targets/NotebookCellTarget.ts b/src/processTargets/targets/NotebookCellTarget.ts index 4fb3265ab1..08ccb12144 100644 --- a/src/processTargets/targets/NotebookCellTarget.ts +++ b/src/processTargets/targets/NotebookCellTarget.ts @@ -1,4 +1,5 @@ -import { TextEditor } from "vscode"; +import { TextEditor } from "@cursorless/common"; +import { toVscodeEditor } from "@cursorless/vscode-common"; import { Target } from "../../typings/target.types"; import { Position } from "../../typings/targetDescriptor.types"; import { getNotebookFromCellDocument } from "../../util/notebook"; @@ -68,6 +69,7 @@ export class NotebookCellPositionTarget extends BaseTarget { } private isNotebookEditor(editor: TextEditor) { - return getNotebookFromCellDocument(editor.document) != null; + const vscodeEditor = toVscodeEditor(editor); + return getNotebookFromCellDocument(vscodeEditor.document) != null; } } diff --git a/src/processTargets/targets/ParagraphTarget.ts b/src/processTargets/targets/ParagraphTarget.ts index 8e049e4047..220c928fc7 100644 --- a/src/processTargets/targets/ParagraphTarget.ts +++ b/src/processTargets/targets/ParagraphTarget.ts @@ -1,8 +1,14 @@ -import { Position, Range, TextDocument, TextEditor, TextLine } from "vscode"; +import { + Position, + Range, + TextDocument, + TextEditor, + TextLine, +} from "@cursorless/common"; import { Target } from "../../typings/target.types"; import { expandToFullLine } from "../../util/rangeUtils"; -import { isSameType } from "../../util/typeUtils"; import { constructLineTarget } from "../../util/tryConstructTarget"; +import { isSameType } from "../../util/typeUtils"; import { createContinuousLineRange } from "../targetUtil/createContinuousRange"; import BaseTarget from "./BaseTarget"; import LineTarget from "./LineTarget"; @@ -114,8 +120,7 @@ export default class ParagraphTarget extends BaseTarget { function getLeadingDelimiterRange(editor: TextEditor, contentRange: Range) { const { document } = editor; - const { lineAt } = document; - const startLine = lineAt(contentRange.start); + const startLine = document.lineAt(contentRange.start); const leadingLine = getPreviousNonEmptyLine(document, startLine); // Lines are next to each other so they can be no delimiter range if (leadingLine != null) { @@ -124,14 +129,14 @@ function getLeadingDelimiterRange(editor: TextEditor, contentRange: Range) { } return new Range( new Position(leadingLine.lineNumber + 1, 0), - lineAt(startLine.lineNumber - 1).range.end, + document.lineAt(startLine.lineNumber - 1).range.end, ); } // Leading delimiter to start of file if (startLine.lineNumber > 0) { return new Range( new Position(0, 0), - lineAt(startLine.lineNumber - 1).range.end, + document.lineAt(startLine.lineNumber - 1).range.end, ); } return undefined; @@ -139,8 +144,7 @@ function getLeadingDelimiterRange(editor: TextEditor, contentRange: Range) { function getTrailingDelimiterRange(editor: TextEditor, contentRange: Range) { const { document } = editor; - const { lineAt } = document; - const endLine = lineAt(contentRange.end); + const endLine = document.lineAt(contentRange.end); const trailingLine = getNextNonEmptyLine(document, endLine); if (trailingLine != null) { if (trailingLine.lineNumber - 1 === endLine.lineNumber) { @@ -148,14 +152,14 @@ function getTrailingDelimiterRange(editor: TextEditor, contentRange: Range) { } return new Range( new Position(endLine.lineNumber + 1, 0), - lineAt(trailingLine.lineNumber - 1).range.end, + document.lineAt(trailingLine.lineNumber - 1).range.end, ); } // Trailing delimiter to end of file if (endLine.lineNumber < document.lineCount - 1) { return new Range( new Position(endLine.lineNumber + 1, 0), - lineAt(document.lineCount - 1).range.end, + document.lineAt(document.lineCount - 1).range.end, ); } return undefined; diff --git a/src/processTargets/targets/PositionTarget.ts b/src/processTargets/targets/PositionTarget.ts index 091bd1f2cd..bd246301a0 100644 --- a/src/processTargets/targets/PositionTarget.ts +++ b/src/processTargets/targets/PositionTarget.ts @@ -1,4 +1,4 @@ -import { Range, TextEditor } from "vscode"; +import { Range, TextEditor } from "@cursorless/common"; import { BaseTarget, CommonTargetParameters } from "."; import { UnsupportedError } from "../../errors"; import { EditNewContext } from "../../typings/target.types"; diff --git a/src/processTargets/targets/ScopeTypeTarget.ts b/src/processTargets/targets/ScopeTypeTarget.ts index 0b488e63c5..499679ef91 100644 --- a/src/processTargets/targets/ScopeTypeTarget.ts +++ b/src/processTargets/targets/ScopeTypeTarget.ts @@ -1,4 +1,4 @@ -import { Range } from "vscode"; +import { Range } from "@cursorless/common"; import { Target } from "../../typings/target.types"; import { SimpleScopeTypeType } from "../../typings/targetDescriptor.types"; import { isSameType } from "../../util/typeUtils"; diff --git a/src/processTargets/targets/SubTokenWordTarget.ts b/src/processTargets/targets/SubTokenWordTarget.ts index 0cbe46dd9b..e5482c618e 100644 --- a/src/processTargets/targets/SubTokenWordTarget.ts +++ b/src/processTargets/targets/SubTokenWordTarget.ts @@ -1,5 +1,5 @@ -import { Range } from "vscode"; -import { tryConstructPlainTarget as tryConstructPlainTarget } from "../../util/tryConstructTarget"; +import { Range } from "@cursorless/common"; +import { tryConstructPlainTarget } from "../../util/tryConstructTarget"; import { getDelimitedSequenceRemovalRange } from "../targetUtil/insertionRemovalBehaviors/DelimitedSequenceInsertionRemovalBehavior"; import BaseTarget, { CommonTargetParameters } from "./BaseTarget"; diff --git a/src/processTargets/targets/SurroundingPairTarget.ts b/src/processTargets/targets/SurroundingPairTarget.ts index 0ca20c9564..c6d706657b 100644 --- a/src/processTargets/targets/SurroundingPairTarget.ts +++ b/src/processTargets/targets/SurroundingPairTarget.ts @@ -1,4 +1,4 @@ -import { Range } from "vscode"; +import { Range } from "@cursorless/common"; import { Target } from "../../typings/target.types"; import { getTokenLeadingDelimiterTarget, diff --git a/src/processTargets/targets/TokenTarget.ts b/src/processTargets/targets/TokenTarget.ts index fab6e3992f..b2958669a1 100644 --- a/src/processTargets/targets/TokenTarget.ts +++ b/src/processTargets/targets/TokenTarget.ts @@ -1,4 +1,4 @@ -import { Range } from "vscode"; +import { Range } from "@cursorless/common"; import { BaseTarget } from "."; import { Target } from "../../typings/target.types"; import { diff --git a/src/processTargets/targets/UntypedTarget.ts b/src/processTargets/targets/UntypedTarget.ts index d4a4e1ec6c..9411ea4b2e 100644 --- a/src/processTargets/targets/UntypedTarget.ts +++ b/src/processTargets/targets/UntypedTarget.ts @@ -1,4 +1,4 @@ -import { Range } from "vscode"; +import { Range } from "@cursorless/common"; import { BaseTarget, CommonTargetParameters } from "."; import type { Target } from "../../typings/target.types"; import { createContinuousRangeUntypedTarget } from "../targetUtil/createContinuousRange"; diff --git a/src/scripts/transformRecordedTests/upgradeThatMarks.ts b/src/scripts/transformRecordedTests/upgradeThatMarks.ts index 839cf32682..3c689719a5 100644 --- a/src/scripts/transformRecordedTests/upgradeThatMarks.ts +++ b/src/scripts/transformRecordedTests/upgradeThatMarks.ts @@ -2,7 +2,7 @@ import { TestCaseFixture } from "../../testUtil/TestCaseFixture"; import { SelectionPlainObject, TargetPlainObject, -} from "../../libs/vscode-common/toPlainObject"; +} from "../../libs/vscode-common/testUtil/toPlainObject"; import { FixtureTransformation } from "./types"; // FIXME: Remove this before merging the PR diff --git a/src/test/runners/unitTestsOnly.ts b/src/test/runners/unitTestsOnly.ts index a07373b839..4dee9867cf 100644 --- a/src/test/runners/unitTestsOnly.ts +++ b/src/test/runners/unitTestsOnly.ts @@ -2,10 +2,14 @@ // package.json are active import "module-alias/register"; import * as path from "path"; -import { runAllTestsInDir } from "../util/runAllTestsInDir"; +import { runAllTestsInDirs } from "../util/runAllTestsInDir"; + +const testDirectories = ["../../libs/cursorless-engine", "../../libs/common"]; export function run(): Promise { - return runAllTestsInDir( - path.resolve(__dirname, "../../libs/cursorless-engine"), + return runAllTestsInDirs( + testDirectories.map((testDirectory) => + path.resolve(__dirname, testDirectory), + ), ); } diff --git a/src/test/suite/fixtures/recorded/actions/giveHarpAndWhale.yml b/src/test/suite/fixtures/recorded/actions/giveHarpAndWhale.yml index dd8d7dff61..6bfb31c2c2 100644 --- a/src/test/suite/fixtures/recorded/actions/giveHarpAndWhale.yml +++ b/src/test/suite/fixtures/recorded/actions/giveHarpAndWhale.yml @@ -24,22 +24,5 @@ initialState: default.w: start: {line: 0, character: 6} end: {line: 0, character: 11} -finalState: - documentContents: hello world - selections: - - anchor: {line: 0, character: 5} - active: {line: 0, character: 5} - thatMark: - - type: UntypedTarget - contentRange: - start: {line: 0, character: 0} - end: {line: 0, character: 5} - isReversed: false - hasExplicitRange: false - - type: UntypedTarget - contentRange: - start: {line: 0, character: 6} - end: {line: 0, character: 11} - isReversed: false - hasExplicitRange: false fullTargets: [{type: list, elements: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: h}, selectionType: token, position: contents, insideOutsideType: inside, modifier: {type: identity}}, {type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: w}, selectionType: token, position: contents, insideOutsideType: inside, modifier: {type: identity}}]}] +thrownError: {name: SelectionRequiredError} diff --git a/src/test/util/runAllTestsInDir.ts b/src/test/util/runAllTestsInDir.ts index 238d59fe67..c39a6ab445 100644 --- a/src/test/util/runAllTestsInDir.ts +++ b/src/test/util/runAllTestsInDir.ts @@ -1,9 +1,16 @@ -import * as glob from "glob"; +import * as globRaw from "glob"; import * as Mocha from "mocha"; import * as path from "path"; import { runTestSubset, TEST_SUBSET_GREP_STRING } from "@cursorless/common"; +import { promisify } from "util"; -export function runAllTestsInDir(testsRoot: string): Promise { +const glob = promisify(globRaw); + +export function runAllTestsInDir(testRoot: string) { + return runAllTestsInDirs([testRoot]); +} + +export async function runAllTestsInDirs(testRoots: string[]): Promise { // Create the mocha test const mocha = new Mocha({ ui: "tdd", @@ -11,28 +18,26 @@ export function runAllTestsInDir(testsRoot: string): Promise { grep: runTestSubset() ? TEST_SUBSET_GREP_STRING : undefined, // Only run a subset of tests }); - return new Promise((c, e) => { - glob("**/**.test.js", { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } + for (const testRoot of testRoots) { + const files = await glob("**/**.test.js", { cwd: testRoot }); - // Add files to the test suite - files.forEach((f) => mocha.addFile(path.resolve(testsRoot, f))); + // Add files to the test suite + files.forEach((f) => mocha.addFile(path.resolve(testRoot, f))); + } - try { - // Run the mocha test - mocha.run((failures) => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } + try { + // Run the mocha test + await new Promise((c, e) => { + mocha.run((failures) => { + if (failures > 0) { + e(new Error(`${failures} tests failed.`)); + } else { + c(); + } + }); }); - }); + } catch (err) { + console.error(err); + throw err; + } } diff --git a/src/testUtil/TestCase.ts b/src/testUtil/TestCase.ts index feca3cba70..b15477b63a 100644 --- a/src/testUtil/TestCase.ts +++ b/src/testUtil/TestCase.ts @@ -4,14 +4,12 @@ import { TestDecoration } from "../core/editStyles"; import { ReadOnlyHatMap } from "../core/IndividualHatMap"; import { ThatMark } from "../core/ThatMark"; import SpyIDE, { SpyIDERecordedValues } from "../libs/common/ide/spy/SpyIDE"; -import { TargetDescriptor } from "../typings/targetDescriptor.types"; -import { Token } from "../typings/Types"; -import { cleanUpTestCaseCommand } from "./cleanUpTestCaseCommand"; import { extractTargetedMarks, extractTargetKeys, } from "../libs/common/testUtil/extractTargetedMarks"; import serialize from "../libs/common/testUtil/serialize"; +import ide from "../libs/cursorless-engine/singletons/ide.singleton"; import { ExtraSnapshotField, takeSnapshot, @@ -21,15 +19,16 @@ import { marksToPlainObject, SerializedMarks, testDecorationsToPlainObject, -} from "../libs/vscode-common/toPlainObject"; -import { getActiveTextEditor } from "../ide/vscode/activeTextEditor"; +} from "../libs/vscode-common/testUtil/toPlainObject"; +import { TargetDescriptor } from "../typings/targetDescriptor.types"; +import { Token } from "../typings/Types"; +import { cleanUpTestCaseCommand } from "./cleanUpTestCaseCommand"; import type { PlainTestDecoration, - ThrownError, TestCaseCommand, TestCaseFixture, + ThrownError, } from "./TestCaseFixture"; -import ide from "../libs/cursorless-engine/singletons/ide.singleton"; export type TestCaseContext = { thatMark: ThatMark; @@ -63,7 +62,7 @@ export class TestCase { private captureFinalThatMark: boolean, private extraSnapshotFields?: ExtraSnapshotField[], ) { - const activeEditor = getActiveTextEditor()!; + const activeEditor = ide().activeTextEditor!; this.command = cleanUpTestCaseCommand(command); const { targets } = context; @@ -178,7 +177,7 @@ export class TestCase { this.context.sourceMark, excludeFields, this.extraSnapshotFields, - getActiveTextEditor()!, + ide().activeTextEditor!, ide(), this.getMarks(), { startTimestamp: this.startTimestamp }, @@ -193,7 +192,7 @@ export class TestCase { this.context.sourceMark, excludeFields, this.extraSnapshotFields, - getActiveTextEditor()!, + ide().activeTextEditor!, ide(), this.isHatTokenMapTest ? this.getMarks() : undefined, { startTimestamp: this.startTimestamp }, diff --git a/src/testUtil/TestCaseFixture.ts b/src/testUtil/TestCaseFixture.ts index 623fbf28e8..33cc22ac74 100644 --- a/src/testUtil/TestCaseFixture.ts +++ b/src/testUtil/TestCaseFixture.ts @@ -2,7 +2,7 @@ import type { CommandLatest } from "../core/commandRunner/command.types"; import type { SpyIDERecordedValues } from "../libs/common/ide/spy/SpyIDE"; import type { TargetDescriptor } from "../typings/targetDescriptor.types"; import type { TestCaseSnapshot } from "../libs/vscode-common/testUtil/takeSnapshot"; -import type { PositionPlainObject } from "../libs/vscode-common/toPlainObject"; +import type { PositionPlainObject } from "../libs/vscode-common/testUtil/toPlainObject"; export type TestCaseCommand = CommandLatest; export interface PlainTestDecoration { diff --git a/src/testUtil/TestCaseRecorder.ts b/src/testUtil/TestCaseRecorder.ts index 323d6b65e0..24cd4fd4c0 100644 --- a/src/testUtil/TestCaseRecorder.ts +++ b/src/testUtil/TestCaseRecorder.ts @@ -1,20 +1,19 @@ +import { getKey } from "@cursorless/common"; import * as fs from "fs"; import { readFile } from "fs/promises"; import { invariant } from "immutability-helper"; import { merge } from "lodash"; import * as path from "path"; import * as vscode from "vscode"; -import { getActiveTextEditor } from "../ide/vscode/activeTextEditor"; +import SpyIDE from "../libs/common/ide/spy/SpyIDE"; +import { IDE } from "../libs/common/ide/types/ide.types"; import { extractTargetedMarks } from "../libs/common/testUtil/extractTargetedMarks"; import serialize from "../libs/common/testUtil/serialize"; -import SpyIDE from "../libs/common/ide/spy/SpyIDE"; import sleep from "../libs/common/util/sleep"; -import { getKey } from "@cursorless/common"; import { walkDirsSync } from "../libs/common/util/walkSync"; import ide, { injectIde, } from "../libs/cursorless-engine/singletons/ide.singleton"; -import { IDE } from "../libs/common/ide/types/ide.types"; import { ExtraSnapshotField, takeSnapshot, @@ -23,10 +22,9 @@ import { DEFAULT_TEXT_EDITOR_OPTIONS_FOR_TEST } from "../libs/vscode-common/test import { marksToPlainObject, SerializedMarks, -} from "../libs/vscode-common/toPlainObject"; +} from "../libs/vscode-common/testUtil/toPlainObject"; import { DecoratedSymbolMark } from "../typings/targetDescriptor.types"; import { Graph } from "../typings/Types"; -import { getDocumentRange } from "../util/rangeUtils"; import { TestCase, TestCaseContext } from "./TestCase"; import { TestCaseCommand } from "./TestCaseFixture"; @@ -186,7 +184,7 @@ export class TestCaseRecorder { undefined, ["clipboard"], this.active ? this.extraSnapshotFields : undefined, - getActiveTextEditor()!, + ide().activeTextEditor!, ide(), marks, this.active ? { startTimestamp: this.startTimestamp } : undefined, @@ -336,11 +334,12 @@ export class TestCaseRecorder { await this.testCase.recordInitialState(); - const editor = getActiveTextEditor()!; + const editor = ide().activeTextEditor!; // NB: We need to copy the editor options rather than storing a reference // because its properties are lazy this.originalTextEditorOptions = { ...editor.options }; - editor.options = DEFAULT_TEXT_EDITOR_OPTIONS_FOR_TEST; + ide().getEditableTextEditor(editor).options = + DEFAULT_TEXT_EDITOR_OPTIONS_FOR_TEST; } } @@ -469,8 +468,9 @@ export class TestCaseRecorder { this.spyIde = undefined; this.originalIde = undefined; - const editor = getActiveTextEditor()!; - editor.options = this.originalTextEditorOptions; + const editor = ide().activeTextEditor!; + ide().getEditableTextEditor(editor).options = + this.originalTextEditorOptions; } dispose() { @@ -507,3 +507,16 @@ async function readJsonIfExists( return JSON.parse(rawText); } + +/** + * Get a range that corresponds to the entire contents of the given document. + * + * @param document The document to consider + * @returns A range corresponding to the entire document contents + */ +function getDocumentRange(document: vscode.TextDocument) { + return new vscode.Range( + new vscode.Position(0, 0), + document.lineAt(document.lineCount - 1).range.end, + ); +} diff --git a/src/testUtil/fromPlainObject.ts b/src/testUtil/fromPlainObject.ts index 69d0640443..6ff9bca3af 100644 --- a/src/testUtil/fromPlainObject.ts +++ b/src/testUtil/fromPlainObject.ts @@ -1,12 +1,12 @@ -import { Position, Range, Selection, TextEditor } from "vscode"; -import { UntypedTarget } from "../processTargets/targets"; -import type { Target } from "../typings/target.types"; +import { Position, Range, Selection, TextEditor } from "@cursorless/common"; import type { PositionPlainObject, RangePlainObject, SelectionPlainObject, TargetPlainObject, -} from "../libs/vscode-common/toPlainObject"; +} from "../libs/vscode-common/testUtil/toPlainObject"; +import { UntypedTarget } from "../processTargets/targets"; +import type { Target } from "../typings/target.types"; /** * Given a plain object describing a target, constructs a `Target` object. diff --git a/src/typings/Types.ts b/src/typings/Types.ts index 17178b0adc..9520543424 100644 --- a/src/typings/Types.ts +++ b/src/typings/Types.ts @@ -1,5 +1,9 @@ -import * as vscode from "vscode"; -import { Location } from "vscode"; +import type { + Range, + Selection, + TextEditor, + TextDocument, +} from "@cursorless/common"; import { SyntaxNode } from "web-tree-sitter"; import { ActionRecord } from "../actions/actions.types"; import Cheatsheet from "../core/Cheatsheet"; @@ -22,7 +26,7 @@ import { FullRangeInfo } from "./updateSelections"; * A token within a text editor, including the current display line of the token */ export interface Token extends FullRangeInfo { - editor: vscode.TextEditor; + editor: TextEditor; displayLine: number; } @@ -38,21 +42,21 @@ export interface ProcessedTargetsContext { */ actionFinalStages: ModifierStage[]; currentSelections: SelectionWithEditor[]; - currentEditor: vscode.TextEditor | undefined; + currentEditor: TextEditor | undefined; hatTokenMap: ReadOnlyHatMap; thatMark: Target[]; sourceMark: Target[]; - getNodeAtLocation: (location: Location) => SyntaxNode; + getNodeAtLocation: (document: TextDocument, range: Range) => SyntaxNode; } export interface SelectionWithEditor { - selection: vscode.Selection; - editor: vscode.TextEditor; + selection: Selection; + editor: TextEditor; } export interface RangeWithEditor { - range: vscode.Range; - editor: vscode.TextEditor; + range: Range; + editor: TextEditor; } export interface SelectionContext { @@ -61,22 +65,22 @@ export interface SelectionContext { /** * Selection used for removal */ - removalRange?: vscode.Range; + removalRange?: Range; /** * The range used for the interior */ - interiorRange?: vscode.Range; + interiorRange?: Range; /** * The range of the delimiter before the selection */ - leadingDelimiterRange?: vscode.Range; + leadingDelimiterRange?: Range; /** * The range of the delimiter after the selection */ - trailingDelimiterRange?: vscode.Range; + trailingDelimiterRange?: Range; } export type SelectionWithEditorWithContext = { @@ -85,7 +89,7 @@ export type SelectionWithEditorWithContext = { }; export interface SelectionWithContext { - selection: vscode.Selection; + selection: Selection; context: SelectionContext; } @@ -136,7 +140,10 @@ export interface Graph { /** * Function to access nodes in the tree sitter. */ - readonly getNodeAtLocation: (location: vscode.Location) => SyntaxNode; + readonly getNodeAtLocation: ( + document: TextDocument, + range: Range, + ) => SyntaxNode; /** * Debug logger @@ -177,18 +184,18 @@ export type NodeMatcher = ( **/ export type NodeFinder = ( node: SyntaxNode, - selection?: vscode.Selection, + selection?: Selection, ) => SyntaxNode | null; /** Returns one or more selections for a given SyntaxNode */ export type SelectionExtractor = ( - editor: vscode.TextEditor, + editor: TextEditor, nodes: SyntaxNode, ) => SelectionWithContext; /** Represent a single edit/change in the document */ export interface Edit { - range: vscode.Range; + range: Range; text: string; /** @@ -209,7 +216,7 @@ export interface EditWithRangeUpdater extends Edit { * after applying the edit, and should return a new range which excludes any * delimiters that were inserted. */ - updateRange: (range: vscode.Range) => vscode.Range; + updateRange: (range: Range) => Range; } export type TextFormatterName = diff --git a/src/typings/target.types.ts b/src/typings/target.types.ts index 95665006dd..cb661844f3 100644 --- a/src/typings/target.types.ts +++ b/src/typings/target.types.ts @@ -1,4 +1,3 @@ -import type { Range, Selection, TextEditor } from "vscode"; // NB: We import `Target` below just so that @link below resolves. Once one of // the following issues are fixed, we can either remove the above line or // switch to `{import("foo")}` syntax in the `{@link}` tag. @@ -7,7 +6,7 @@ import type { Range, Selection, TextEditor } from "vscode"; // eslint-disable-next-line @typescript-eslint/no-unused-vars import type ModifyIfUntypedStage from "../processTargets/modifiers/ModifyIfUntypedStage"; // eslint-disable-next-line @typescript-eslint/no-unused-vars -import type { SnippetVariable, Snippet } from "./snippet"; +import type { Range, Selection, TextEditor } from "@cursorless/common"; import type { // eslint-disable-next-line @typescript-eslint/no-unused-vars ScopeTypeTarget, @@ -16,6 +15,8 @@ import type { // eslint-disable-next-line @typescript-eslint/no-unused-vars UntypedTarget, } from "../processTargets/targets"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import type { Snippet, SnippetVariable } from "./snippet"; import type { Position } from "./targetDescriptor.types"; import type { EditWithRangeUpdater } from "./Types"; diff --git a/src/typings/updateSelections.ts b/src/typings/updateSelections.ts index d5df1afebd..c31e94e27d 100644 --- a/src/typings/updateSelections.ts +++ b/src/typings/updateSelections.ts @@ -1,8 +1,8 @@ -import { - Range, +import type { Range } from "@cursorless/common"; +import type { TextDocumentChangeEvent, TextDocumentContentChangeEvent, -} from "vscode"; +} from "../libs/common/ide/types/Events"; export interface RangeOffsets { start: number; diff --git a/src/util/addDecorationsToEditor.ts b/src/util/addDecorationsToEditor.ts index a536ee2b9b..468b75a69b 100644 --- a/src/util/addDecorationsToEditor.ts +++ b/src/util/addDecorationsToEditor.ts @@ -1,15 +1,15 @@ +import { Range, TextEditor } from "@cursorless/common"; import { concat, flatten, maxBy, min } from "lodash"; -import * as vscode from "vscode"; import Decorations from "../core/Decorations"; import { HatStyleName } from "../core/hatStyles"; import { IndividualHatMap } from "../core/IndividualHatMap"; +import ide from "../libs/cursorless-engine/singletons/ide.singleton"; import { TokenGraphemeSplitter } from "../libs/cursorless-engine/tokenGraphemeSplitter"; import { getMatcher } from "../libs/cursorless-engine/tokenizer"; import { Token } from "../typings/Types"; import { getDisplayLineMap } from "./getDisplayLineMap"; import { getTokenComparator } from "./getTokenComparator"; import { getTokensInRange } from "./getTokensInRange"; -import { getActiveTextEditor } from "../ide/vscode/activeTextEditor"; export function addDecorationsToEditors( hatTokenMap: IndividualHatMap, @@ -18,15 +18,15 @@ export function addDecorationsToEditors( ) { hatTokenMap.clear(); - let editors: readonly vscode.TextEditor[]; + let editors: readonly TextEditor[]; - if (getActiveTextEditor() == null) { - editors = vscode.window.visibleTextEditors; + if (ide().activeTextEditor == null) { + editors = ide().visibleTextEditors; } else { editors = [ - getActiveTextEditor()!, - ...vscode.window.visibleTextEditors.filter( - (editor) => editor !== getActiveTextEditor(), + ide().activeTextEditor!, + ...ide().visibleTextEditors.filter( + (editor) => editor !== ide().activeTextEditor, ), ]; } @@ -58,8 +58,8 @@ export function addDecorationsToEditors( tokens.sort( getTokenComparator( - displayLineMap.get(editor.selection.active.line)!, - editor.selection.active.character, + displayLineMap.get(editor.selections[0].active.line)!, + editor.selections[0].active.character, ), ); @@ -95,9 +95,9 @@ export function addDecorationsToEditors( const graphemeDecorationIndices: { [grapheme: string]: number } = {}; const decorationRanges: Map< - vscode.TextEditor, + TextEditor, { - [decorationName in HatStyleName]?: vscode.Range[]; + [decorationName in HatStyleName]?: Range[]; } > = new Map( editors.map((editor) => [ @@ -156,7 +156,7 @@ export function addDecorationsToEditors( decorationRanges .get(token.editor)! [hatStyleName]!.push( - new vscode.Range( + new Range( token.range.start.translate(undefined, bestGrapheme.tokenStartOffset), token.range.start.translate(undefined, bestGrapheme.tokenEndOffset), ), @@ -169,10 +169,12 @@ export function addDecorationsToEditors( decorationRanges.forEach((ranges, editor) => { decorations.hatStyleNames.forEach((hatStyleName) => { - editor.setDecorations( - decorations.decorationMap[hatStyleName]!, - ranges[hatStyleName]!, - ); + ide() + .getEditableTextEditor(editor) + .setDecorations( + decorations.decorationMap[hatStyleName]!, + ranges[hatStyleName]!, + ); }); }); } diff --git a/src/util/getDisplayLineMap.ts b/src/util/getDisplayLineMap.ts index 923ace75bb..2aa00e95aa 100644 --- a/src/util/getDisplayLineMap.ts +++ b/src/util/getDisplayLineMap.ts @@ -1,5 +1,5 @@ +import { TextEditor } from "@cursorless/common"; import { concat, flatten, flow, range, uniq } from "lodash"; -import * as vscode from "vscode"; /** * Returns a map from line numbers in the file to display lines, which skip @@ -9,14 +9,14 @@ import * as vscode from "vscode"; * * @param editor A visible editor */ -export function getDisplayLineMap(editor: vscode.TextEditor) { +export function getDisplayLineMap(editor: TextEditor) { return new Map( flow( flatten, uniq, )( concat( - [[editor.selection.start.line]], + [[editor.selections[0].start.line]], editor.visibleRanges.map((visibleRange) => range(visibleRange.start.line, visibleRange.end.line + 1), ), diff --git a/src/util/getLinks.ts b/src/util/getLinks.ts deleted file mode 100644 index ab071bfee7..0000000000 --- a/src/util/getLinks.ts +++ /dev/null @@ -1,24 +0,0 @@ -import * as vscode from "vscode"; -import { Target } from "../typings/target.types"; - -export async function getLinksForSelections( - editor: vscode.TextEditor, - selections: vscode.Selection[], -) { - const links = await getLinksForEditor(editor); - return links.filter((link) => - selections.find((selection) => link.range.contains(selection)), - ); -} - -export async function getLinkForTarget(target: Target) { - const links = await getLinksForEditor(target.editor); - return links.find((link) => link.range.contains(target.contentRange)); -} - -function getLinksForEditor(editor: vscode.TextEditor) { - return vscode.commands.executeCommand( - "vscode.executeLinkProvider", - editor.document.uri, - ) as Thenable; -} diff --git a/src/util/getTokensInRange.ts b/src/util/getTokensInRange.ts index b59f5dd0e8..63720865f0 100644 --- a/src/util/getTokensInRange.ts +++ b/src/util/getTokensInRange.ts @@ -1,16 +1,16 @@ -import * as vscode from "vscode"; +import { Range, TextEditor } from "@cursorless/common"; import { tokenize } from "../libs/cursorless-engine/tokenizer"; import { RangeOffsets } from "../typings/updateSelections"; export interface PartialToken { text: string; - range: vscode.Range; + range: Range; offsets: RangeOffsets; } export function getTokensInRange( - editor: vscode.TextEditor, - range: vscode.Range, + editor: TextEditor, + range: Range, ): PartialToken[] { const languageId = editor.document.languageId; const text = editor.document.getText(range); @@ -19,7 +19,7 @@ export function getTokensInRange( return tokenize(text, languageId, (match) => { const startOffset = rangeOffset + match.index!; const endOffset = rangeOffset + match.index! + match[0].length; - const range = new vscode.Range( + const range = new Range( editor.document.positionAt(startOffset), editor.document.positionAt(endOffset), ); diff --git a/src/util/nodeFinders.ts b/src/util/nodeFinders.ts index 91946f5825..dfa82da566 100644 --- a/src/util/nodeFinders.ts +++ b/src/util/nodeFinders.ts @@ -1,4 +1,4 @@ -import { Position, Selection } from "vscode"; +import { Position, Selection } from "@cursorless/common"; import { Point, SyntaxNode } from "web-tree-sitter"; import { NodeFinder } from "../typings/Types"; diff --git a/src/util/nodeSelectors.ts b/src/util/nodeSelectors.ts index bfc3c66fd0..45ee5c9c1a 100644 --- a/src/util/nodeSelectors.ts +++ b/src/util/nodeSelectors.ts @@ -1,5 +1,5 @@ +import { Position, Range, Selection, TextEditor } from "@cursorless/common"; import { identity, maxBy } from "lodash"; -import { Position, Range, Selection, TextEditor } from "vscode"; import { Point, SyntaxNode } from "web-tree-sitter"; import { NodeFinder, @@ -424,13 +424,13 @@ export function getInsertionDelimiter( trailingDelimiterRange: Range | undefined, defaultDelimiterInsertion: string, ) { - const { getText } = editor.document; + const { document } = editor; const delimiters = [ trailingDelimiterRange != null - ? getText(trailingDelimiterRange) + ? document.getText(trailingDelimiterRange) : defaultDelimiterInsertion, leadingDelimiterRange != null - ? getText(leadingDelimiterRange) + ? document.getText(leadingDelimiterRange) : defaultDelimiterInsertion, ]; diff --git a/src/util/notebookLegacy.ts b/src/util/notebookLegacy.ts index bc7e8f02ba..40cfc3a0fd 100644 --- a/src/util/notebookLegacy.ts +++ b/src/util/notebookLegacy.ts @@ -1,30 +1,33 @@ +import { toVscodeEditor } from "@cursorless/vscode-common"; import { range } from "lodash"; import * as semver from "semver"; -import { - commands, - NotebookDocument, - TextDocument, - TextEditor, - version, -} from "vscode"; -import { getNotebookFromCellDocument } from "./notebook"; +import { commands, NotebookDocument, TextDocument, version } from "vscode"; +import type { VscodeTextEditorImpl } from "../ide/vscode/VscodeTextEditorImpl"; +import type VscodeIDE from "../ide/vscode/VscodeIDE"; import { getCellIndex } from "../libs/vscode-common/notebook"; -import { getActiveTextEditor } from "../ide/vscode/activeTextEditor"; +import { getNotebookFromCellDocument } from "./notebook"; export function isVscodeLegacyNotebookVersion() { return semver.lt(version, "1.68.0"); } -export async function focusNotebookCellLegacy(editor: TextEditor) { - const activeTextEditor = getActiveTextEditor(); +export async function focusNotebookCellLegacy( + ide: VscodeIDE, + editor: VscodeTextEditorImpl, +) { + const { activeTextEditor } = ide; if (activeTextEditor == null) { return; } - const editorNotebook = getNotebookFromCellDocument(editor.document); + const vscodeActiveEditor = toVscodeEditor(activeTextEditor); + + const editorNotebook = getNotebookFromCellDocument( + editor.vscodeEditor.document, + ); const activeEditorNotebook = getNotebookFromCellDocument( - activeTextEditor.document, + vscodeActiveEditor.document, ); if ( @@ -35,10 +38,13 @@ export async function focusNotebookCellLegacy(editor: TextEditor) { return; } - const editorIndex = getCellIndex(editorNotebook, editor.document); + const editorIndex = getCellIndex( + editorNotebook, + editor.vscodeEditor.document, + ); const activeEditorIndex = getCellIndex( editorNotebook, - activeTextEditor.document, + vscodeActiveEditor.document, ); if (editorIndex === -1 || activeEditorIndex === -1) { diff --git a/src/util/performDocumentEdits.ts b/src/util/performDocumentEdits.ts index 5477bc93cd..de573b87f8 100644 --- a/src/util/performDocumentEdits.ts +++ b/src/util/performDocumentEdits.ts @@ -1,10 +1,10 @@ -import { Edit } from "../typings/Types"; -import { TextEditor } from "vscode"; +import { EditableTextEditor } from "@cursorless/common"; import { RangeUpdater } from "../core/updateSelections/RangeUpdater"; +import { Edit } from "../typings/Types"; export async function performDocumentEdits( rangeUpdater: RangeUpdater, - editor: TextEditor, + editor: EditableTextEditor, edits: Edit[], ) { const deregister = rangeUpdater.registerReplaceEditList( diff --git a/src/util/rangeUtils.ts b/src/util/rangeUtils.ts index e3103de981..89bf2aebd3 100644 --- a/src/util/rangeUtils.ts +++ b/src/util/rangeUtils.ts @@ -1,4 +1,4 @@ -import { Position, Range, TextDocument, TextEditor } from "vscode"; +import { Position, Range, TextEditor } from "@cursorless/common"; export function isAtEndOfLine(editor: TextEditor, position: Position) { const endLine = editor.document.lineAt(position); @@ -25,10 +25,6 @@ export function expandToFullLine(editor: TextEditor, range: Range) { ); } -export function makeEmptyRange(position: Position) { - return new Range(position, position); -} - export function getRangeLength(editor: TextEditor, range: Range) { return range.isEmpty ? 0 @@ -51,21 +47,9 @@ export function strictlyContains( range1: Range, rangeOrPosition: Range | Position, ): boolean { - const start = - "start" in rangeOrPosition ? rangeOrPosition.start : rangeOrPosition; - const end = "end" in rangeOrPosition ? rangeOrPosition.end : rangeOrPosition; + const [start, end] = + rangeOrPosition instanceof Position + ? [rangeOrPosition, rangeOrPosition] + : [rangeOrPosition.start, rangeOrPosition.end]; return range1.start.isBefore(start) && range1.end.isAfter(end); } - -/** - * Get a range that corresponds to the entire contents of the given document. - * - * @param document The document to consider - * @returns A range corresponding to the entire document contents - */ -export function getDocumentRange(document: TextDocument) { - return new Range( - new Position(0, 0), - document.lineAt(document.lineCount - 1).range.end, - ); -} diff --git a/src/util/selectionUtils.ts b/src/util/selectionUtils.ts index cc18714f82..e664f67c6b 100644 --- a/src/util/selectionUtils.ts +++ b/src/util/selectionUtils.ts @@ -1,14 +1,6 @@ -import { Position, Range, Selection, TextEditor } from "vscode"; +import { Position, Range, Selection, TextEditor } from "@cursorless/common"; import { SelectionWithEditor } from "../typings/Types"; -export function isForward(selection: Selection) { - return selection.active.isAfterOrEqual(selection.anchor); -} - -export function isReversed(selection: Selection) { - return selection.active.isBefore(selection.anchor); -} - export function selectionWithEditorFromRange( selection: SelectionWithEditor, range: Range, @@ -32,17 +24,11 @@ function selectionFromPositions( start: Position, end: Position, ): Selection { - // The built in isReversed is bugged on empty selection. don't use - return isForward(selection) + return !selection.isReversed ? new Selection(start, end) : new Selection(end, start); } -export function selectionFromRange(isReversed: boolean, range: Range) { - const { start, end } = range; - return isReversed ? new Selection(end, start) : new Selection(start, end); -} - /** * Return a copy of {@link range} excluding any leading or trailing whitespace. * If {@link range} contains only whitespace or is empty {@link range} will be returned unchanged. diff --git a/src/util/setSelectionsAndFocusEditor.ts b/src/util/setSelectionsAndFocusEditor.ts index 34cb15f2d2..bf1dbb457e 100644 --- a/src/util/setSelectionsAndFocusEditor.ts +++ b/src/util/setSelectionsAndFocusEditor.ts @@ -1,124 +1,26 @@ -import * as semver from "semver"; -import { - commands, - NotebookDocument, - Selection, - TextEditor, - version, - ViewColumn, - window, -} from "vscode"; -import { getNotebookFromCellDocument } from "./notebook"; -import { getCellIndex } from "../libs/vscode-common/notebook"; -import { - focusNotebookCellLegacy, - isVscodeLegacyNotebookVersion, -} from "./notebookLegacy"; -import uniqDeep from "./uniqDeep"; -import { getActiveTextEditor } from "../ide/vscode/activeTextEditor"; +import { EditableTextEditor, Selection } from "@cursorless/common"; -const columnFocusCommands = { - [ViewColumn.One]: "workbench.action.focusFirstEditorGroup", - [ViewColumn.Two]: "workbench.action.focusSecondEditorGroup", - [ViewColumn.Three]: "workbench.action.focusThirdEditorGroup", - [ViewColumn.Four]: "workbench.action.focusFourthEditorGroup", - [ViewColumn.Five]: "workbench.action.focusFifthEditorGroup", - [ViewColumn.Six]: "workbench.action.focusSixthEditorGroup", - [ViewColumn.Seven]: "workbench.action.focusSeventhEditorGroup", - [ViewColumn.Eight]: "workbench.action.focusEighthEditorGroup", - [ViewColumn.Nine]: "workbench.action.focusNinthEditorGroup", - [ViewColumn.Active]: "", - [ViewColumn.Beside]: "", -}; +import uniqDeep from "./uniqDeep"; export async function setSelectionsAndFocusEditor( - editor: TextEditor, + editor: EditableTextEditor, selections: Selection[], revealRange: boolean = true, ) { setSelectionsWithoutFocusingEditor(editor, selections); if (revealRange) { - editor.revealRange(editor.selection); + editor.revealRange(editor.selections[0]); } // NB: We focus the editor after setting the selection because otherwise you see // an intermediate state where the old selection persists - await focusEditor(editor); + await editor.focus(); } export function setSelectionsWithoutFocusingEditor( - editor: TextEditor, + editor: EditableTextEditor, selections: Selection[], ) { editor.selections = uniqDeep(selections); } - -export async function focusEditor(editor: TextEditor) { - const viewColumn = getViewColumn(editor); - if (viewColumn != null) { - await commands.executeCommand(columnFocusCommands[viewColumn]); - } else { - // If the view column is null we see if it's a notebook and try to see if we - // can just move around in the notebook to focus the correct editor - - if (isVscodeLegacyNotebookVersion()) { - return await focusNotebookCellLegacy(editor); - } - - await focusNotebookCell(editor); - } -} - -function getViewColumn(editor: TextEditor): ViewColumn | undefined { - if (editor.viewColumn != null) { - return editor.viewColumn; - } - // TODO: tabGroups is not available on older versions of vscode we still support. - // Remove any cast as soon as version is updated. - if (semver.lt(version, "1.67.0")) { - return undefined; - } - const uri = editor.document.uri.toString(); - const tabGroup = (window as any)?.tabGroups?.all?.find((tabGroup: any) => - tabGroup?.tabs.find((tab: any) => tab?.input?.modified?.toString() === uri), - ); - return tabGroup?.viewColumn; -} - -async function focusNotebookCell(editor: TextEditor) { - const desiredNotebookEditor = getNotebookFromCellDocument(editor.document); - if (desiredNotebookEditor == null) { - throw new Error("Couldn't find notebook editor for given document"); - } - - const desiredNotebookDocument: NotebookDocument = - desiredNotebookEditor.notebook; - - await commands.executeCommand( - columnFocusCommands[ - desiredNotebookEditor.viewColumn as keyof typeof columnFocusCommands - ], - ); - - const desiredEditorIndex = getCellIndex( - desiredNotebookDocument, - editor.document, - ); - - const desiredSelections = [ - desiredNotebookEditor.selection.with({ - start: desiredEditorIndex, - end: desiredEditorIndex + 1, - }), - ]; - desiredNotebookEditor.selections = desiredSelections; - desiredNotebookEditor.revealRange(desiredSelections[0]); - - // Issue a command to tell VSCode to focus the cell input editor - // NB: We don't issue the command if it's already focused, because it turns - // out that this command is actually a toggle, so that causes it to de-focus! - if (getActiveTextEditor() !== editor) { - await commands.executeCommand("notebook.cell.edit"); - } -} diff --git a/src/util/targetUtils.ts b/src/util/targetUtils.ts index 48fe5e1a30..496a5ad6a7 100644 --- a/src/util/targetUtils.ts +++ b/src/util/targetUtils.ts @@ -1,10 +1,10 @@ +import { Range, Selection, TextEditor } from "@cursorless/common"; import { zip } from "lodash"; -import { Range, Selection, TextEditor } from "vscode"; import { Target } from "../typings/target.types"; import { SelectionWithEditor } from "../typings/Types"; import { groupBy } from "./itertools"; -export function ensureSingleEditor(targets: Target[]) { +export function ensureSingleEditor(targets: Target[]): TextEditor { if (targets.length === 0) { throw new Error("Require at least one target with this action"); } @@ -49,13 +49,13 @@ export function groupTargetsForEachEditor(targets: Target[]) { return groupForEachEditor(targets, (target) => target.editor); } -export function groupForEachEditor( +function groupForEachEditor( targets: T[], getEditor: (target: T) => TextEditor, ): [TextEditor, T[]][] { // Actually group by document and not editor. If the same document is open in multiple editors we want to perform all actions in one editor or an concurrency error will occur. - const getDocument = (target: T) => getEditor(target).document; - const editorMap = groupBy(targets, getDocument); + const getDocumentUri = (target: T) => getEditor(target).document.uri; + const editorMap = groupBy(targets, getDocumentUri); return Array.from(editorMap.values(), (editorTargets) => { // Just pick any editor with the given document open; doesn't matter which const editor = getEditor(editorTargets[0]); diff --git a/src/util/tryConstructTarget.ts b/src/util/tryConstructTarget.ts index 99eb8aeb84..c9ca286450 100644 --- a/src/util/tryConstructTarget.ts +++ b/src/util/tryConstructTarget.ts @@ -1,4 +1,4 @@ -import { Range, TextEditor } from "vscode"; +import { Range, TextEditor } from "@cursorless/common"; import { CommonTargetParameters, LineTarget, diff --git a/yarn.lock b/yarn.lock index 781dd757fe..92eb651052 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4,14 +4,14 @@ "@babel/runtime@^7.15.4": version "7.20.0" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.0.tgz#824a9ef325ffde6f78056059db3168c08785e24a" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.0.tgz" integrity sha512-NDYdls71fTXoU8TZHfbBWg7DiZfNzClcKui/+kyi6ppD2L1qnWW3VV6CjtaBXSUGGhiTWJ6ereOIkUvenif66Q== dependencies: regenerator-runtime "^0.13.10" "@eslint/eslintrc@^1.2.1": version "1.2.1" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.1.tgz#8b5e1c49f4077235516bc9ec7d41378c0f69b8c6" + resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz" integrity sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ== dependencies: ajv "^6.12.4" @@ -26,7 +26,7 @@ "@humanwhocodes/config-array@^0.9.2": version "0.9.5" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.5.tgz#2cbaf9a89460da24b5ca6531b8bbfc23e1df50c7" + resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz" integrity sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw== dependencies: "@humanwhocodes/object-schema" "^1.2.1" @@ -35,12 +35,12 @@ "@humanwhocodes/object-schema@^1.2.1": version "1.2.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== "@nodelib/fs.scandir@2.1.5": version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== dependencies: "@nodelib/fs.stat" "2.0.5" @@ -48,12 +48,12 @@ "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== "@nodelib/fs.walk@^1.2.3": version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== dependencies: "@nodelib/fs.scandir" "2.1.5" @@ -61,28 +61,21 @@ "@sinonjs/commons@^1.6.0", "@sinonjs/commons@^1.7.0", "@sinonjs/commons@^1.8.3": version "1.8.3" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" + resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz" integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== dependencies: type-detect "4.0.8" -"@sinonjs/fake-timers@>=5": - version "9.1.1" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.1.tgz#7b698e0b9d12d93611f06ee143c30ced848e2840" - integrity sha512-Wp5vwlZ0lOqpSYGKqr53INws9HLkt6JDc/pDZcPf7bchQnrXJMXPns8CXx0hFikMSGSWfvtvvpb2gtMVfkWagA== - dependencies: - "@sinonjs/commons" "^1.7.0" - -"@sinonjs/fake-timers@^7.1.2": +"@sinonjs/fake-timers@>=5", "@sinonjs/fake-timers@^7.1.2": version "7.1.2" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz#2524eae70c4910edccf99b2f4e6efc5894aff7b5" + resolved "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz" integrity sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg== dependencies: "@sinonjs/commons" "^1.7.0" "@sinonjs/samsam@^6.0.2": version "6.1.1" - resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-6.1.1.tgz#627f7f4cbdb56e6419fa2c1a3e4751ce4f6a00b1" + resolved "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.1.1.tgz" integrity sha512-cZ7rKJTLiE7u7Wi/v9Hc2fs3Ucc3jrWeMgPHbbTCeVAB2S0wOBbYlkJVeNSL04i7fdhT8wIbDq1zhC/PXTD2SA== dependencies: "@sinonjs/commons" "^1.6.0" @@ -91,22 +84,22 @@ "@sinonjs/text-encoding@^0.7.1": version "0.7.1" - resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5" + resolved "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz" integrity sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ== "@tootallnate/once@1": version "1.1.2" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + resolved "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz" integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== "@types/chai@^4.3.3": version "4.3.3" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.3.tgz#3c90752792660c4b562ad73b3fbd68bf3bc7ae07" + resolved "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz" integrity sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g== "@types/glob@^7.1.3": version "7.2.0" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" + resolved "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz" integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== dependencies: "@types/minimatch" "*" @@ -114,69 +107,69 @@ "@types/js-yaml@^4.0.2": version "4.0.5" - resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.5.tgz#738dd390a6ecc5442f35e7f03fa1431353f7e138" + resolved "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.5.tgz" integrity sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA== "@types/json-schema@^7.0.9": version "7.0.11" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" + resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== "@types/json5@^0.0.29": version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== "@types/lodash@^4.14.168": version "4.14.181" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.181.tgz#d1d3740c379fda17ab175165ba04e2d03389385d" + resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.181.tgz" integrity sha512-n3tyKthHJbkiWhDZs3DkhkCzt2MexYHXlX0td5iMplyfwketaOeKboEVBqzceH7juqvEg3q5oUoBFxSLu7zFag== "@types/minimatch@*": version "3.0.5" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" + resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz" integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== "@types/mocha@^8.0.4": version "8.2.3" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.2.3.tgz#bbeb55fbc73f28ea6de601fbfa4613f58d785323" + resolved "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz" integrity sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw== -"@types/node@*": - version "17.0.23" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.23.tgz#3b41a6e643589ac6442bdbd7a4a3ded62f33f7da" - integrity sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw== - -"@types/node@^16.11.3": +"@types/node@*", "@types/node@^16.11.3": version "16.11.26" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.26.tgz#63d204d136c9916fb4dcd1b50f9740fe86884e47" + resolved "https://registry.npmjs.org/@types/node/-/node-16.11.26.tgz" integrity sha512-GZ7bu5A6+4DtG7q9GsoHXy3ALcgeIHP4NnL0Vv2wu0uUB/yQex26v0tf6/na1mm0+bS9Uw+0DFex7aaKr2qawQ== "@types/semver@^7.3.9": version "7.3.9" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.9.tgz#152c6c20a7688c30b967ec1841d31ace569863fc" + resolved "https://registry.npmjs.org/@types/semver/-/semver-7.3.9.tgz" integrity sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ== "@types/sinon@^10.0.2": version "10.0.11" - resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-10.0.11.tgz#8245827b05d3fc57a6601bd35aee1f7ad330fc42" + resolved "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.11.tgz" integrity sha512-dmZsHlBsKUtBpHriNjlK0ndlvEh8dcb9uV9Afsbt89QIyydpC7NcR+nWlAhASfy3GHnxTl4FX/aKE7XZUt/B4g== dependencies: "@types/sinonjs__fake-timers" "*" "@types/sinonjs__fake-timers@*": version "8.1.2" - resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz#bf2e02a3dbd4aecaf95942ecd99b7402e03fad5e" + resolved "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz" integrity sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA== +"@types/uuid@^8.3.4": + version "8.3.4" + resolved "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz" + integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== + "@types/vscode@~1.61.0": version "1.61.0" - resolved "https://registry.yarnpkg.com/@types/vscode/-/vscode-1.61.0.tgz#c54335b6f84c19c69b1435b17cc0ce3b2cecfeec" + resolved "https://registry.npmjs.org/@types/vscode/-/vscode-1.61.0.tgz" integrity sha512-9k5Nwq45hkRwdfCFY+eKXeQQSbPoA114mF7U/4uJXRBJeGIO7MuJdhF1PnaDN+lllL9iKGQtd6FFXShBXMNaFg== "@typescript-eslint/eslint-plugin@^5.20.0": version "5.20.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.20.0.tgz#022531a639640ff3faafaf251d1ce00a2ef000a1" + resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.20.0.tgz" integrity sha512-fapGzoxilCn3sBtC6NtXZX6+P/Hef7VDbyfGqTTpzYydwhlkevB+0vE0EnmHPVTVSy68GUncyJ/2PcrFBeCo5Q== dependencies: "@typescript-eslint/scope-manager" "5.20.0" @@ -191,7 +184,7 @@ "@typescript-eslint/parser@^5.20.0": version "5.20.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.20.0.tgz#4991c4ee0344315c2afc2a62f156565f689c8d0b" + resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.20.0.tgz" integrity sha512-UWKibrCZQCYvobmu3/N8TWbEeo/EPQbS41Ux1F9XqPzGuV7pfg6n50ZrFo6hryynD8qOTTfLHtHjjdQtxJ0h/w== dependencies: "@typescript-eslint/scope-manager" "5.20.0" @@ -201,7 +194,7 @@ "@typescript-eslint/scope-manager@5.20.0": version "5.20.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.20.0.tgz#79c7fb8598d2942e45b3c881ced95319818c7980" + resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.20.0.tgz" integrity sha512-h9KtuPZ4D/JuX7rpp1iKg3zOH0WNEa+ZIXwpW/KWmEFDxlA/HSfCMhiyF1HS/drTICjIbpA6OqkAhrP/zkCStg== dependencies: "@typescript-eslint/types" "5.20.0" @@ -209,7 +202,7 @@ "@typescript-eslint/type-utils@5.20.0": version "5.20.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.20.0.tgz#151c21cbe9a378a34685735036e5ddfc00223be3" + resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.20.0.tgz" integrity sha512-WxNrCwYB3N/m8ceyoGCgbLmuZwupvzN0rE8NBuwnl7APgjv24ZJIjkNzoFBXPRCGzLNkoU/WfanW0exvp/+3Iw== dependencies: "@typescript-eslint/utils" "5.20.0" @@ -218,12 +211,12 @@ "@typescript-eslint/types@5.20.0": version "5.20.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.20.0.tgz#fa39c3c2aa786568302318f1cb51fcf64258c20c" + resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.20.0.tgz" integrity sha512-+d8wprF9GyvPwtoB4CxBAR/s0rpP25XKgnOvMf/gMXYDvlUC3rPFHupdTQ/ow9vn7UDe5rX02ovGYQbv/IUCbg== "@typescript-eslint/typescript-estree@5.20.0": version "5.20.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.20.0.tgz#ab73686ab18c8781bbf249c9459a55dc9417d6b0" + resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.20.0.tgz" integrity sha512-36xLjP/+bXusLMrT9fMMYy1KJAGgHhlER2TqpUVDYUQg4w0q/NW/sg4UGAgVwAqb8V4zYg43KMUpM8vV2lve6w== dependencies: "@typescript-eslint/types" "5.20.0" @@ -236,7 +229,7 @@ "@typescript-eslint/utils@5.20.0": version "5.20.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.20.0.tgz#b8e959ed11eca1b2d5414e12417fd94cae3517a5" + resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.20.0.tgz" integrity sha512-lHONGJL1LIO12Ujyx8L8xKbwWSkoUKFSO+0wDAqGXiudWB2EO7WEUT+YZLtVbmOmSllAjLb9tpoIPwpRe5Tn6w== dependencies: "@types/json-schema" "^7.0.9" @@ -248,7 +241,7 @@ "@typescript-eslint/visitor-keys@5.20.0": version "5.20.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.20.0.tgz#70236b5c6b67fbaf8b2f58bf3414b76c1e826c2a" + resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.20.0.tgz" integrity sha512-1flRpNF+0CAQkMNlTJ6L/Z5jiODG/e5+7mk6XwtPOUS3UrTz3UOiAg9jG2VtKsWI6rZQfy4C6a232QNRZTRGlg== dependencies: "@typescript-eslint/types" "5.20.0" @@ -256,12 +249,12 @@ "@ungap/promise-all-settled@1.1.2": version "1.1.2" - resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" + resolved "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz" integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== "@vscode/test-electron@^2.1.3": version "2.1.4" - resolved "https://registry.yarnpkg.com/@vscode/test-electron/-/test-electron-2.1.4.tgz#fa1b8915246d0102e81d4fd664bb6c337ca7092f" + resolved "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.1.4.tgz" integrity sha512-tHHAWNVwl8C7nyezHAHdNPWkksdXWvmae6bt4k1tJ9hvMm6QIIk95Mkutl82XHcD60mdP46EHDGU+xFsAvygOQ== dependencies: http-proxy-agent "^4.0.1" @@ -271,29 +264,29 @@ abbrev@1: version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== acorn-jsx@^5.3.1: version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn@^8.7.0: version "8.7.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz" integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== agent-base@6: version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== dependencies: debug "4" ajv@^6.10.0, ajv@^6.12.4: version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: fast-deep-equal "^3.1.1" @@ -303,46 +296,46 @@ ajv@^6.10.0, ajv@^6.12.4: ansi-colors@4.1.1: version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== ansi-regex@^0.2.0, ansi-regex@^0.2.1: version "0.2.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-0.2.1.tgz#0d8e946967a3d8143f93e24e298525fc1b2235f9" - integrity sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk= + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz" + integrity "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk= sha512-sGwIGMjhYdW26/IhwK2gkWWI8DRCVO6uj3hYgHT+zD+QL1pa37tM3ujhyfcJIYSbsxp7Gxhy7zrRW/1AHm4BmA==" ansi-regex@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz" integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw== ansi-regex@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-styles@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.1.0.tgz#eaecbf66cd706882760b2f4691582b8f55d7a7de" - integrity sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94= + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz" + integrity "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94= sha512-f2PKUkN5QngiSemowa6Mrk9MPCdtFiOSmibjZ+j1qhLGHHYsqZwmBMRF3IRMVXo8sybDqx2fJl2d/8OphBoWkA==" ansi-styles@^3.2.1: version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" anymatch@~3.1.1: version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz" integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== dependencies: normalize-path "^3.0.0" @@ -350,67 +343,67 @@ anymatch@~3.1.1: argparse@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== array-union@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== asap@^2.0.0: version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= + resolved "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz" + integrity "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" assertion-error@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + resolved "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz" integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== async@^2.6.1: version "2.6.3" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + resolved "https://registry.npmjs.org/async/-/async-2.6.3.tgz" integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== dependencies: lodash "^4.17.14" balanced-match@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== big-integer@^1.6.17: version "1.6.51" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" + resolved "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz" integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== binary-extensions@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== binary@~0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/binary/-/binary-0.3.0.tgz#9f60553bc5ce8c3386f3b553cff47462adecaa79" - integrity sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk= + resolved "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz" + integrity "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk= sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==" dependencies: buffers "~0.1.1" chainsaw "~0.1.0" bluebird@~3.4.1: version "3.4.7" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" - integrity sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM= + resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz" + integrity "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM= sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==" boolbase@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" - integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" + integrity "sha1-aN/1++YMUes3cl6p4+0xDcwed24= sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" brace-expansion@^1.1.7: version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== dependencies: balanced-match "^1.0.0" @@ -418,39 +411,39 @@ brace-expansion@^1.1.7: braces@^3.0.2, braces@~3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== dependencies: fill-range "^7.0.1" browser-stdout@1.3.1: version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + resolved "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== buffer-indexof-polyfill@~1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz#d2732135c5999c64b277fcf9b1abe3498254729c" + resolved "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz" integrity sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A== buffers@~0.1.1: version "0.1.1" - resolved "https://registry.yarnpkg.com/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb" - integrity sha1-skV5w77U1tOWru5tmorn9Ugqt7s= + resolved "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz" + integrity "sha1-skV5w77U1tOWru5tmorn9Ugqt7s= sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==" callsites@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== camelcase@^6.0.0: version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== chai@^4.3.6: version "4.3.6" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.6.tgz#ffe4ba2d9fa9d6680cc0b370adae709ec9011e9c" + resolved "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz" integrity sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q== dependencies: assertion-error "^1.1.0" @@ -463,14 +456,14 @@ chai@^4.3.6: chainsaw@~0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/chainsaw/-/chainsaw-0.1.0.tgz#5eab50b28afe58074d0d58291388828b5e5fbc98" - integrity sha1-XqtQsor+WAdNDVgpE4iCi15fvJg= + resolved "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz" + integrity "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg= sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==" dependencies: traverse ">=0.3.0 <0.4" chalk@^2.4.2: version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== dependencies: ansi-styles "^3.2.1" @@ -479,7 +472,7 @@ chalk@^2.4.2: chalk@^4.0.0: version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== dependencies: ansi-styles "^4.1.0" @@ -487,8 +480,8 @@ chalk@^4.0.0: chalk@~0.5.1: version "0.5.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.5.1.tgz#663b3a648b68b55d04690d49167aa837858f2174" - integrity sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ= + resolved "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz" + integrity "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ= sha512-bIKA54hP8iZhyDT81TOsJiQvR1gW+ZYSXFaZUAvoD4wCHdbHY2actmpTE4x344ZlFqHbvoxKOaESULTZN2gstg==" dependencies: ansi-styles "^1.1.0" escape-string-regexp "^1.0.0" @@ -498,12 +491,12 @@ chalk@~0.5.1: check-error@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" + resolved "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz" integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== chokidar@3.5.1: version "3.5.1" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz" integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== dependencies: anymatch "~3.1.1" @@ -518,7 +511,7 @@ chokidar@3.5.1: cliui@^7.0.2: version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== dependencies: string-width "^4.2.0" @@ -527,41 +520,41 @@ cliui@^7.0.2: color-convert@^1.9.0: version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== dependencies: color-name "1.1.3" color-convert@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== dependencies: color-name "~1.1.4" color-name@1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + integrity "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" color-name@~1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== concat-map@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + integrity "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" core-util-is@~1.0.0: version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== cross-spawn@^7.0.2: version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== dependencies: path-key "^3.1.0" @@ -570,7 +563,7 @@ cross-spawn@^7.0.2: css-select@^4.2.1: version "4.3.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b" + resolved "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz" integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ== dependencies: boolbase "^1.0.0" @@ -581,75 +574,75 @@ css-select@^4.2.1: css-what@^6.0.1: version "6.1.0" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + resolved "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz" integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== debug@4, debug@^4.1.1, debug@^4.3.2: version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" debug@4.3.1: version "4.3.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz" integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== dependencies: ms "2.1.2" debuglog@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" - integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= + resolved "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz" + integrity "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= sha512-syBZ+rnAK3EgMsH2aYEOLUW7mZSY9Gb+0wUMCFsZvcmiz+HigA0LOcq/HoQqVuGG+EKykunc7QG2bzrponfaSw==" decamelize@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + resolved "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz" integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== deep-eql@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" + resolved "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz" integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== dependencies: type-detect "^4.0.0" deep-is@^0.1.3: version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== dezalgo@^1.0.0: version "1.0.3" - resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456" - integrity sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY= + resolved "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz" + integrity "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY= sha512-K7i4zNfT2kgQz3GylDw40ot9GAE47sFZ9EXHFSPP6zONLgH6kWXE0KWJchkbQJLBkRazq4APwZ4OwiFFlT95OQ==" dependencies: asap "^2.0.0" wrappy "1" diff@5.0.0, diff@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + resolved "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz" integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== dir-glob@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== dependencies: path-type "^4.0.0" doctrine@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== dependencies: esutils "^2.0.2" dom-serializer@^1.0.1: version "1.4.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" + resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz" integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== dependencies: domelementtype "^2.0.1" @@ -658,19 +651,19 @@ dom-serializer@^1.0.1: domelementtype@^2.0.1, domelementtype@^2.2.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz" integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== domhandler@^4.2.0, domhandler@^4.3.1: version "4.3.1" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" + resolved "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz" integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== dependencies: domelementtype "^2.2.0" domutils@^2.8.0: version "2.8.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" + resolved "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz" integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== dependencies: dom-serializer "^1.0.1" @@ -679,49 +672,49 @@ domutils@^2.8.0: duplexer2@~0.1.4: version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" - integrity sha1-ixLauHjA1p4+eJEFFmKjL8a93ME= + resolved "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz" + integrity "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME= sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==" dependencies: readable-stream "^2.0.2" emoji-regex@^8.0.0: version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== entities@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + resolved "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== esbuild@^0.11.12: version "0.11.23" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.11.23.tgz#c42534f632e165120671d64db67883634333b4b8" + resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.11.23.tgz" integrity sha512-iaiZZ9vUF5wJV8ob1tl+5aJTrwDczlvGP0JoMmnpC2B0ppiMCu8n8gmy5ZTGl5bcG081XBVn+U+jP+mPFm5T5Q== escalade@^3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== escape-string-regexp@^1.0.0, escape-string-regexp@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + integrity "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" eslint-config-prettier@^8.5.0: version "8.5.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1" + resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz" integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q== eslint-scope@^5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== dependencies: esrecurse "^4.3.0" @@ -729,7 +722,7 @@ eslint-scope@^5.1.1: eslint-scope@^7.1.1: version "7.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz" integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== dependencies: esrecurse "^4.3.0" @@ -737,24 +730,24 @@ eslint-scope@^7.1.1: eslint-utils@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" + resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz" integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== dependencies: eslint-visitor-keys "^2.0.0" eslint-visitor-keys@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.3.0: version "3.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz" integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== eslint@^8.13.0: version "8.13.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.13.0.tgz#6fcea43b6811e655410f5626cfcf328016badcd7" + resolved "https://registry.npmjs.org/eslint/-/eslint-8.13.0.tgz" integrity sha512-D+Xei61eInqauAyTJ6C0q6x9mx7kTUC1KZ0m0LSEexR0V+e94K12LmWX076ZIsldwfQ2RONdaJe0re0TRGQbRQ== dependencies: "@eslint/eslintrc" "^1.2.1" @@ -795,7 +788,7 @@ eslint@^8.13.0: espree@^9.3.1: version "9.3.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.1.tgz#8793b4bc27ea4c778c19908e0719e7b8f4115bcd" + resolved "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz" integrity sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ== dependencies: acorn "^8.7.0" @@ -804,41 +797,41 @@ espree@^9.3.1: esquery@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + resolved "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz" integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== dependencies: estraverse "^5.1.0" esrecurse@^4.3.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: estraverse "^5.2.0" estraverse@^4.1.1: version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== estraverse@^5.1.0, estraverse@^5.2.0: version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== esutils@^2.0.2: version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-glob@^3.2.9: version "3.2.11" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" + resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz" integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== dependencies: "@nodelib/fs.stat" "^2.0.2" @@ -849,45 +842,45 @@ fast-glob@^3.2.9: fast-json-stable-stringify@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== fast-levenshtein@^2.0.6: version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" + integrity "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" fast-xml-parser@^3.20.0: version "3.21.1" - resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-3.21.1.tgz#152a1d51d445380f7046b304672dd55d15c9e736" + resolved "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-3.21.1.tgz" integrity sha512-FTFVjYoBOZTJekiUsawGsSYV9QL0A+zDYCRj7y34IO6Jg+2IMYEtQa+bbictpdpV8dHxXywqU7C0gRDEOFtBFg== dependencies: strnum "^1.0.4" fastq@^1.6.0: version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + resolved "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz" integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== dependencies: reusify "^1.0.4" file-entry-cache@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== dependencies: flat-cache "^3.0.4" fill-range@^7.0.1: version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== dependencies: to-regex-range "^5.0.1" find-up@5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== dependencies: locate-path "^6.0.0" @@ -895,7 +888,7 @@ find-up@5.0.0: flat-cache@^3.0.4: version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== dependencies: flatted "^3.1.0" @@ -903,18 +896,18 @@ flat-cache@^3.0.4: flat@^5.0.2: version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz" integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== flatted@^3.1.0: version "3.2.5" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" + resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz" integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== fs.realpath@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + integrity "sha1-FQStJSMVjKpA20onh8sBQRmU6k8= sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" fsevents@~2.3.1: version "2.3.2" @@ -923,7 +916,7 @@ fsevents@~2.3.1: fstream@^1.0.12: version "1.0.12" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" + resolved "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz" integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== dependencies: graceful-fs "^4.1.2" @@ -933,46 +926,46 @@ fstream@^1.0.12: functional-red-black-tree@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + resolved "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz" + integrity "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==" get-caller-file@^2.0.5: version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== get-func-name@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" + resolved "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz" integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig== github-url-from-git@^1.3.0: version "1.5.0" - resolved "https://registry.yarnpkg.com/github-url-from-git/-/github-url-from-git-1.5.0.tgz#f985fedcc0a9aa579dc88d7aff068d55cc6251a0" - integrity sha1-+YX+3MCpqledyI16/waNVcxiUaA= + resolved "https://registry.npmjs.org/github-url-from-git/-/github-url-from-git-1.5.0.tgz" + integrity "sha1-+YX+3MCpqledyI16/waNVcxiUaA= sha512-WWOec4aRI7YAykQ9+BHmzjyNlkfJFG8QLXnDTsLz/kZefq7qkzdfo4p6fkYYMIq1aj+gZcQs/1HQhQh3DPPxlQ==" github-url-from-username-repo@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/github-url-from-username-repo/-/github-url-from-username-repo-1.0.2.tgz#7dd79330d2abe69c10c2cef79714c97215791dfa" - integrity sha1-fdeTMNKr5pwQws73lxTJchV5Hfo= + resolved "https://registry.npmjs.org/github-url-from-username-repo/-/github-url-from-username-repo-1.0.2.tgz" + integrity "sha1-fdeTMNKr5pwQws73lxTJchV5Hfo= sha512-Tj8CQqRoFVTglGdQ8FQmfq8gOOoOYZX7tnOKP8jq8Hdz2OTDhxvtlkLAbrqMYZ7X/YdaYQoUG1IBWxISBfqZ+Q==" glob-parent@^5.1.2, glob-parent@~5.1.0: version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" glob-parent@^6.0.1: version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== dependencies: is-glob "^4.0.3" glob@7.1.6: version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== dependencies: fs.realpath "^1.0.0" @@ -984,8 +977,8 @@ glob@7.1.6: glob@^5.0.3: version "5.0.15" - resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" - integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= + resolved "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz" + integrity "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==" dependencies: inflight "^1.0.4" inherits "2" @@ -995,7 +988,7 @@ glob@^5.0.3: glob@^7.1.3, glob@^7.1.7: version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== dependencies: fs.realpath "^1.0.0" @@ -1007,14 +1000,14 @@ glob@^7.1.3, glob@^7.1.7: globals@^13.6.0, globals@^13.9.0: version "13.13.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.13.0.tgz#ac32261060d8070e2719dd6998406e27d2b5727b" + resolved "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz" integrity sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A== dependencies: type-fest "^0.20.2" globby@^11.0.4: version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== dependencies: array-union "^2.1.0" @@ -1026,46 +1019,46 @@ globby@^11.0.4: "graceful-fs@2 || 3": version "3.0.12" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-3.0.12.tgz#0034947ce9ed695ec8ab0b854bc919e82b1ffaef" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.12.tgz" integrity sha512-J55gaCS4iTTJfTXIxSVw3EMQckcqkpdRv3IR7gu6sq0+tbC363Zx6KH/SEwXASK9JRbhyZmVjJEVJIOxYsB3Qg== dependencies: natives "^1.1.3" graceful-fs@^4.1.2, graceful-fs@^4.2.2: version "4.2.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== growl@1.10.5: version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + resolved "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz" integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== has-ansi@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-0.1.0.tgz#84f265aae8c0e6a88a12d7022894b7568894c62e" - integrity sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4= + resolved "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz" + integrity "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4= sha512-1YsTg1fk2/6JToQhtZkArMkurq8UoWU1Qe0aR3VUHjgij4nOylSWLWAtBXoZ4/dXOmugfLGm1c+QhuD0JyedFA==" dependencies: ansi-regex "^0.2.0" has-flag@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" + integrity "sha1-tdRU3CGZriJWmfNGfloH87lVuv0= sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" has-flag@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== he@1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== http-proxy-agent@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz" integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== dependencies: "@tootallnate/once" "1" @@ -1074,7 +1067,7 @@ http-proxy-agent@^4.0.1: https-proxy-agent@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz" integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== dependencies: agent-base "6" @@ -1082,22 +1075,22 @@ https-proxy-agent@^5.0.0: ignore@^5.1.8, ignore@^5.2.0: version "5.2.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz" integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== immer@^9.0.15: version "9.0.15" - resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.15.tgz#0b9169e5b1d22137aba7d43f8a81a495dd1b62dc" + resolved "https://registry.npmjs.org/immer/-/immer-9.0.15.tgz" integrity sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ== immutability-helper@^3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/immutability-helper/-/immutability-helper-3.1.1.tgz#2b86b2286ed3b1241c9e23b7b21e0444f52f77b7" + resolved "https://registry.npmjs.org/immutability-helper/-/immutability-helper-3.1.1.tgz" integrity sha512-Q0QaXjPjwIju/28TsugCHNEASwoCcJSyJV3uO1sOIQGI0jKgm9f41Lvz0DZj3n46cNCyAZTsEYoY4C2bVRUzyQ== import-fresh@^3.0.0, import-fresh@^3.2.1: version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== dependencies: parent-module "^1.0.0" @@ -1105,139 +1098,139 @@ import-fresh@^3.0.0, import-fresh@^3.2.1: imurmurhash@^0.1.4: version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" + integrity "sha1-khi5srkoojixPcT7a21XbyMUU+o= sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==" inflight@^1.0.4: version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + integrity "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==" dependencies: once "^1.3.0" wrappy "1" inherits@2, inherits@~2.0.0, inherits@~2.0.3: version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== is-binary-path@~2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== dependencies: binary-extensions "^2.0.0" is-extglob@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" + integrity "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" is-fullwidth-code-point@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz" + integrity "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==" is-fullwidth-code-point@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== dependencies: is-extglob "^2.1.1" is-number@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== is-plain-obj@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz" integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== isarray@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + integrity "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" isarray@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + integrity "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" isexe@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + integrity "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" itertools@^1.7.1: version "1.7.1" - resolved "https://registry.yarnpkg.com/itertools/-/itertools-1.7.1.tgz#39fb110782b7f57b9c14782c25fe35bd3997d4fc" + resolved "https://registry.npmjs.org/itertools/-/itertools-1.7.1.tgz" integrity sha512-0sC8t0HYOH0wb/mU5eLmp2g19yfhqho12Q6kCX6MGkNEEJQz97LIXzZ2bbIDyzBnQGcMixmcAtByzKjiaFkw8Q== dependencies: "@babel/runtime" "^7.15.4" jju@^1.1.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/jju/-/jju-1.4.0.tgz#a3abe2718af241a2b2904f84a625970f389ae32a" - integrity sha1-o6vicYryQaKykE+EpiWXDzia4yo= + resolved "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz" + integrity "sha1-o6vicYryQaKykE+EpiWXDzia4yo= sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==" jquery-extend@~2.0.3: version "2.0.3" - resolved "https://registry.yarnpkg.com/jquery-extend/-/jquery-extend-2.0.3.tgz#6815cdb01a866ddba30e6f4d0fc5fb6679272735" - integrity sha1-aBXNsBqGbdujDm9ND8X7ZnknJzU= + resolved "https://registry.npmjs.org/jquery-extend/-/jquery-extend-2.0.3.tgz" + integrity "sha1-aBXNsBqGbdujDm9ND8X7ZnknJzU= sha512-ysLU6/m8VLckIjAudiE+s7YAoYwklZy5Ft9kqO7FPkqaQrd3wUMuZ134G3uniysW8VZME/pGa2LcynsM4TjP5Q==" js-yaml@4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.0.0.tgz#f426bc0ff4b4051926cd588c71113183409a121f" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz" integrity sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q== dependencies: argparse "^2.0.1" js-yaml@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== dependencies: argparse "^2.0.1" json-parse-helpfulerror@^1.0.2: version "1.0.3" - resolved "https://registry.yarnpkg.com/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz#13f14ce02eed4e981297b64eb9e3b932e2dd13dc" - integrity sha1-E/FM4C7tTpgSl7ZOueO5MuLdE9w= + resolved "https://registry.npmjs.org/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz" + integrity "sha1-E/FM4C7tTpgSl7ZOueO5MuLdE9w= sha512-XgP0FGR77+QhUxjXkwOMkC94k3WtqEBfcnjWqhRd82qTat4SWKRE+9kUnynz/shm3I4ea2+qISvTIeGTNU7kJg==" dependencies: jju "^1.1.0" json-schema-traverse@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" + integrity "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" json5@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + resolved "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz" integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== dependencies: minimist "^1.2.0" just-extend@^4.0.2: version "4.2.1" - resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.2.1.tgz#ef5e589afb61e5d66b24eca749409a8939a8c744" + resolved "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz" integrity sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg== levn@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== dependencies: prelude-ls "^1.2.1" @@ -1255,60 +1248,60 @@ levn@^0.4.1: listenercount@~1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/listenercount/-/listenercount-1.0.1.tgz#84c8a72ab59c4725321480c975e6508342e70937" - integrity sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc= + resolved "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz" + integrity "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc= sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==" locate-path@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== dependencies: p-locate "^5.0.0" lodash.get@^4.4.2: version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" - integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= + resolved "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz" + integrity "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==" lodash.merge@^4.6.2: version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== lodash@^4.17.14, lodash@^4.17.21: version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== log-symbols@4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.0.0.tgz#69b3cc46d20f448eccdb75ea1fa733d9e821c920" + resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz" integrity sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA== dependencies: chalk "^4.0.0" loupe@^2.3.1: version "2.3.4" - resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.4.tgz#7e0b9bffc76f148f9be769cb1321d3dcf3cb25f3" + resolved "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz" integrity sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ== dependencies: get-func-name "^2.0.0" lru-cache@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== dependencies: yallist "^4.0.0" merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== micromatch@^4.0.4: version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== dependencies: braces "^3.0.2" @@ -1316,38 +1309,38 @@ micromatch@^4.0.4: "minimatch@2 || 3", minimatch@^3.0.4: version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" minimatch@3.0.4: version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" minimist@^1.2.0, minimist@^1.2.6: version "1.2.6" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== "mkdirp@>=0.5 0", mkdirp@^0.5.1: version "0.5.6" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== dependencies: minimist "^1.2.6" mkdirp@^0.3.5: version "0.3.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.5.tgz#de3e5f8961c88c787ee1368df849ac4413eca8d7" - integrity sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc= + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz" + integrity "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc= sha512-8OCq0De/h9ZxseqzCH8Kw/Filf5pF/vMI6+BH7Lu0jXz2pqYCjTAQRolSxRIi+Ax+oCCjlxoJMP0YQ4XlrQNHg==" mocha@^8.1.3: version "8.4.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-8.4.0.tgz#677be88bf15980a3cae03a73e10a0fc3997f0cff" + resolved "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz" integrity sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ== dependencies: "@ungap/promise-all-settled" "1.1.2" @@ -1378,37 +1371,37 @@ mocha@^8.1.3: module-alias@^2.2.2: version "2.2.2" - resolved "https://registry.yarnpkg.com/module-alias/-/module-alias-2.2.2.tgz#151cdcecc24e25739ff0aa6e51e1c5716974c0e0" + resolved "https://registry.npmjs.org/module-alias/-/module-alias-2.2.2.tgz" integrity sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q== ms@2.1.2: version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== ms@2.1.3: version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== nanoid@3.1.20: version "3.1.20" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788" + resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz" integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw== natives@^1.1.3: version "1.1.6" - resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.6.tgz#a603b4a498ab77173612b9ea1acdec4d980f00bb" + resolved "https://registry.npmjs.org/natives/-/natives-1.1.6.tgz" integrity sha512-6+TDFewD4yxY14ptjKaS63GVdtKiES1pTPyxn9Jb0rBqPMZ7VcCiooEhPNsr+mqHtMGxa/5c/HhcC4uPEUw/nA== natural-compare@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" + integrity "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" nise@^5.1.0: version "5.1.1" - resolved "https://registry.yarnpkg.com/nise/-/nise-5.1.1.tgz#ac4237e0d785ecfcb83e20f389185975da5c31f3" + resolved "https://registry.npmjs.org/nise/-/nise-5.1.1.tgz" integrity sha512-yr5kW2THW1AkxVmCnKEh4nbYkJdB3I7LUkiUgOvEkOp414mc2UMaHMA7pjq1nYowhdoJZGwEKGaQVbxfpWj10A== dependencies: "@sinonjs/commons" "^1.8.3" @@ -1419,7 +1412,7 @@ nise@^5.1.0: node-html-parser@^5.3.3: version "5.3.3" - resolved "https://registry.yarnpkg.com/node-html-parser/-/node-html-parser-5.3.3.tgz#2845704f3a7331a610e0e551bf5fa02b266341b6" + resolved "https://registry.npmjs.org/node-html-parser/-/node-html-parser-5.3.3.tgz" integrity sha512-ncg1033CaX9UexbyA7e1N0aAoAYRDiV8jkTvzEnfd1GDvzFdrsXLzR4p4ik8mwLgnaKP/jyUFWDy9q3jvRT2Jw== dependencies: css-select "^4.2.1" @@ -1427,32 +1420,32 @@ node-html-parser@^5.3.3: nopt-defaults@^0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/nopt-defaults/-/nopt-defaults-0.0.1.tgz#f150fcc8882309cbfb76187e12e9bcb20694558b" - integrity sha1-8VD8yIgjCcv7dhh+Eum8sgaUVYs= + resolved "https://registry.npmjs.org/nopt-defaults/-/nopt-defaults-0.0.1.tgz" + integrity "sha1-8VD8yIgjCcv7dhh+Eum8sgaUVYs= sha512-Ri0fmpCibbSQQX4LoYIvt/MmiA/ivo30tDT1ifdN7/Vh4frHHd/SspJHmlDmrpXflVvoFAPMw4u64eW44Ez0lA==" nopt-usage@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/nopt-usage/-/nopt-usage-0.1.0.tgz#b18b8c183e181047ca9e63b7cde7cfc702cca579" - integrity sha1-sYuMGD4YEEfKnmO3zefPxwLMpXk= + resolved "https://registry.npmjs.org/nopt-usage/-/nopt-usage-0.1.0.tgz" + integrity "sha1-sYuMGD4YEEfKnmO3zefPxwLMpXk= sha512-Tg2sISrWBbSsCRqpEMmdxn3KZfacrd0N2NYpZQIq0MHxGHMjwzYlxeB9pVIom/g7CBK28atDUQsTlOfG0wOsNA==" nopt@^2.2.0: version "2.2.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-2.2.1.tgz#2aa09b7d1768487b3b89a9c5aa52335bff0baea7" - integrity sha1-KqCbfRdoSHs7ianFqlIzW/8Lrqc= + resolved "https://registry.npmjs.org/nopt/-/nopt-2.2.1.tgz" + integrity "sha1-KqCbfRdoSHs7ianFqlIzW/8Lrqc= sha512-gIOTA/uJuhPwFqp+spY7VQ1satbnGlD+iQVZxI18K6hs8Evq4sX81Ml7BB5byP/LsbR2yBVtmvdEmhi7evJ6Aw==" dependencies: abbrev "1" nopt@^3.0.6: version "3.0.6" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" - integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= + resolved "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz" + integrity "sha1-xkZdvwirzU2zWTF/eaxopkayj/k= sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==" dependencies: abbrev "1" normalize-package-data@^1.0.0: version "1.0.3" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-1.0.3.tgz#8be955b8907af975f1a4584ea8bb9b41492312f5" - integrity sha1-i+lVuJB6+XXxpFhOqLubQUkjEvU= + resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-1.0.3.tgz" + integrity "sha1-i+lVuJB6+XXxpFhOqLubQUkjEvU= sha512-pyPVJAzFiaioifPIsJBEoKJ9YcPHz7UhckZ7wqhBztLLCu6NozkIDrN+frzrCwjXtfunXfaMWIDtcDhnbO8fWA==" dependencies: github-url-from-git "^1.3.0" github-url-from-username-repo "^1.0.0" @@ -1460,12 +1453,12 @@ normalize-package-data@^1.0.0: normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== npm-license-crawler@^0.2.1: version "0.2.1" - resolved "https://registry.yarnpkg.com/npm-license-crawler/-/npm-license-crawler-0.2.1.tgz#a76a82e0a0407e2032c03dc5b1d518cf9eac9e1d" + resolved "https://registry.npmjs.org/npm-license-crawler/-/npm-license-crawler-0.2.1.tgz" integrity sha512-CRchloUjZk/ZSAkb5JbCKNFojLWtbjxwsB7w48kauHXK+5bjby2HXFvGvicVx7uNBY6HBWEPw20qKc/4jlL+1Q== dependencies: async "^2.6.1" @@ -1480,21 +1473,21 @@ npm-license-crawler@^0.2.1: nth-check@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2" + resolved "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz" integrity sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w== dependencies: boolbase "^1.0.0" once@^1.3.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + integrity "sha1-WDsap3WWHUsROsF9nFC6753Xa9E= sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==" dependencies: wrappy "1" optionator@^0.9.1: version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== dependencies: deep-is "^0.1.3" @@ -1506,98 +1499,98 @@ optionator@^0.9.1: p-limit@^3.0.2: version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: yocto-queue "^0.1.0" p-locate@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== dependencies: p-limit "^3.0.2" parent-module@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== dependencies: callsites "^3.0.0" path-exists@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== path-is-absolute@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + integrity "sha1-F0uSaHNVNP+8es5r9TpanhtcX18= sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" path-key@^3.1.0: version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== path-to-regexp@^1.7.0: version "1.8.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz" integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== dependencies: isarray "0.0.1" path-type@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== pathval@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" + resolved "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz" integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== prelude-ls@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== prettier@2.7.1: version "2.7.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64" + resolved "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz" integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g== process-nextick-args@~2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== punycode@^2.1.0: version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== queue-microtask@^1.2.2: version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== randombytes@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" read-installed@~3.1.3: version "3.1.5" - resolved "https://registry.yarnpkg.com/read-installed/-/read-installed-3.1.5.tgz#4ae36081afd3e2204dc2e279807aaa52c30c8c0c" - integrity sha1-SuNgga/T4iBNwuJ5gHqqUsMMjAw= + resolved "https://registry.npmjs.org/read-installed/-/read-installed-3.1.5.tgz" + integrity "sha1-SuNgga/T4iBNwuJ5gHqqUsMMjAw= sha512-XxD5VDz32T6rLCFfYElTif8/lkqcs9y51Gs2r30rAfT7LUGzJWaXLrwvn6fXkDsTzGcPr7Pj8CggOxwTxl/ozQ==" dependencies: debuglog "^1.0.1" read-package-json "1" @@ -1610,8 +1603,8 @@ read-installed@~3.1.3: read-package-json@1: version "1.3.3" - resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-1.3.3.tgz#ef79dfda46e165376ee8a57efbfedd4d1b029ba4" - integrity sha1-73nf2kbhZTdu6KV++/7dTRsCm6Q= + resolved "https://registry.npmjs.org/read-package-json/-/read-package-json-1.3.3.tgz" + integrity "sha1-73nf2kbhZTdu6KV++/7dTRsCm6Q= sha512-9bayCl9cbXy3AL0qXhLQ0vliEgpzUVeLegSOrde3ujTHy2W18UsJiMUXEWkjbBB4ZnJzZPVuo2vAW62j4gY7gg==" dependencies: glob "^5.0.3" json-parse-helpfulerror "^1.0.2" @@ -1621,7 +1614,7 @@ read-package-json@1: readable-stream@^2.0.2, readable-stream@~2.3.6: version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== dependencies: core-util-is "~1.0.0" @@ -1634,7 +1627,7 @@ readable-stream@^2.0.2, readable-stream@~2.3.6: readdir-scoped-modules@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz#8d45407b4f870a0dcaebc0e28670d18e74514309" + resolved "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz" integrity sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw== dependencies: debuglog "^1.0.1" @@ -1644,113 +1637,106 @@ readdir-scoped-modules@^1.0.0: readdirp@~3.5.0: version "3.5.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" + resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz" integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== dependencies: picomatch "^2.2.1" regenerator-runtime@^0.13.10: version "0.13.10" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz#ed07b19616bcbec5da6274ebc75ae95634bfc2ee" + resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz" integrity sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw== regexpp@^3.2.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== require-directory@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" + integrity "sha1-jGStX9MNqxyXbiNE/+f3kqam30I= sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" resolve-from@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== reusify@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== rimraf@2: version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== dependencies: glob "^7.1.3" rimraf@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" run-parallel@^1.1.9: version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== dependencies: queue-microtask "^1.2.2" safe-buffer@^5.1.0: version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== "semver@2 || 3 || 4": version "4.3.6" - resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" - integrity sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto= + resolved "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz" + integrity "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto= sha512-IrpJ+yoG4EOH8DFWuVg+8H1kW1Oaof0Wxe7cPcXW3x9BjkN/eVo54F15LyqemnDIUYskQWr9qvl/RihmSy6+xQ==" -semver@^7.3.5: - version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== - dependencies: - lru-cache "^6.0.0" - -semver@^7.3.7: +semver@^7.3.5, semver@^7.3.7: version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + resolved "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz" integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== dependencies: lru-cache "^6.0.0" serialize-javascript@5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" + resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz" integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== dependencies: randombytes "^2.1.0" setimmediate@~1.0.4: version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz" + integrity "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" shebang-command@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== dependencies: shebang-regex "^3.0.0" shebang-regex@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== sinon@^11.1.1: version "11.1.2" - resolved "https://registry.yarnpkg.com/sinon/-/sinon-11.1.2.tgz#9e78850c747241d5c59d1614d8f9cbe8840e8674" + resolved "https://registry.npmjs.org/sinon/-/sinon-11.1.2.tgz" integrity sha512-59237HChms4kg7/sXhiRcUzdSkKuydDeTiamT/jesUVHshBgL8XAmhgFo0GfK6RruMDM/iRSij1EybmMog9cJw== dependencies: "@sinonjs/commons" "^1.8.3" @@ -1762,17 +1748,17 @@ sinon@^11.1.1: slash@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== slide@~1.1.3: version "1.1.6" - resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" - integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= + resolved "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz" + integrity "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw==" "string-width@^1.0.2 || 2": version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== dependencies: is-fullwidth-code-point "^2.0.0" @@ -1780,7 +1766,7 @@ slide@~1.1.3: string-width@^4.1.0, string-width@^4.2.0: version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" @@ -1789,98 +1775,98 @@ string-width@^4.1.0, string-width@^4.2.0: string_decoder@~1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== dependencies: safe-buffer "~5.1.0" strip-ansi@^0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.3.0.tgz#25f48ea22ca79187f3174a4db8759347bb126220" - integrity sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA= + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz" + integrity "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA= sha512-DerhZL7j6i6/nEnVG0qViKXI0OKouvvpsAiaj7c+LfqZZZxdwZtv8+UiA/w4VUJpT8UzX0pR1dcHOii1GbmruQ==" dependencies: ansi-regex "^0.2.1" strip-ansi@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz" + integrity "sha1-qEeQIusaw2iocTibY1JixQXuNo8= sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==" dependencies: ansi-regex "^3.0.0" strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" strip-bom@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" + integrity "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==" strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== strnum@^1.0.4: version "1.0.5" - resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.5.tgz#5c4e829fe15ad4ff0d20c3db5ac97b73c9b072db" + resolved "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz" integrity sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA== supports-color@8.1.1: version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== dependencies: has-flag "^4.0.0" supports-color@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-0.2.0.tgz#d92de2694eb3f67323973d7ae3d8b55b4c22190a" - integrity sha1-2S3iaU6z9nMjlz1649i1W0wiGQo= + resolved "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz" + integrity "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo= sha512-tdCZ28MnM7k7cJDJc7Eq80A9CsRFAAOZUy41npOZCs++qSjfIy7o5Rh46CBk+Dk5FbKJ33X3Tqg4YrV07N5RaA==" supports-color@^5.3.0: version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" supports-color@^7.1.0, supports-color@^7.2.0: version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== dependencies: has-flag "^4.0.0" text-table@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" + integrity "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" to-regex-range@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== dependencies: is-number "^7.0.0" "traverse@>=0.3.0 <0.4": version "0.3.9" - resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9" - integrity sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk= + resolved "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz" + integrity "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk= sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==" treeify@^1.0.1, treeify@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/treeify/-/treeify-1.1.0.tgz#4e31c6a463accd0943879f30667c4fdaff411bb8" + resolved "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz" integrity sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A== ts-unused-exports@^8.0.0: version "8.0.0" - resolved "https://registry.yarnpkg.com/ts-unused-exports/-/ts-unused-exports-8.0.0.tgz#6dd15ff26286e0b7e5663cda3b98c77ea6f3ffe7" + resolved "https://registry.npmjs.org/ts-unused-exports/-/ts-unused-exports-8.0.0.tgz" integrity sha512-gylHFyJqC80PSb4zy35KTckykEW1vmKjnOHjBeX9iKBo4b/SzqQIcXXbYSuif4YMgNm6ewFF62VM1C9z0bGZPw== dependencies: chalk "^4.0.0" @@ -1888,7 +1874,7 @@ ts-unused-exports@^8.0.0: tsconfig-paths@^3.9.0: version "3.14.1" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" + resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz" integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ== dependencies: "@types/json5" "^0.0.29" @@ -1898,41 +1884,41 @@ tsconfig-paths@^3.9.0: tslib@^1.8.1: version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tsutils@^3.21.0: version "3.21.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== dependencies: tslib "^1.8.1" type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== dependencies: prelude-ls "^1.2.1" type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5, type-detect@^4.0.8: version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== type-fest@^0.20.2: version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== typescript@4.6.3: version "4.6.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.3.tgz#eefeafa6afdd31d725584c67a0eaba80f6fc6c6c" + resolved "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz" integrity sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw== unzipper@^0.10.11: version "0.10.11" - resolved "https://registry.yarnpkg.com/unzipper/-/unzipper-0.10.11.tgz#0b4991446472cbdb92ee7403909f26c2419c782e" + resolved "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz" integrity sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw== dependencies: big-integer "^1.6.17" @@ -1948,58 +1934,63 @@ unzipper@^0.10.11: uri-js@^4.2.2: version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" util-deprecate@~1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + integrity "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" util-extend@^1.0.1: version "1.0.3" - resolved "https://registry.yarnpkg.com/util-extend/-/util-extend-1.0.3.tgz#a7c216d267545169637b3b6edc6ca9119e2ff93f" - integrity sha1-p8IW0mdUUWljeztu3GypEZ4v+T8= + resolved "https://registry.npmjs.org/util-extend/-/util-extend-1.0.3.tgz" + integrity "sha1-p8IW0mdUUWljeztu3GypEZ4v+T8= sha512-mLs5zAK+ctllYBj+iAQvlDCwoxU/WDOUaJkcFudeiAX6OajC6BKXJUa9a+tbtkC11dz2Ufb7h0lyvIOVn4LADA==" + +uuid@^9.0.0: + version "9.0.0" + resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz" + integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== v8-compile-cache@^2.0.3: version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== vscode-uri@^3.0.6: version "3.0.6" - resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.6.tgz#5e6e2e1a4170543af30151b561a41f71db1d6f91" + resolved "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.6.tgz" integrity sha512-fmL7V1eiDBFRRnu+gfRWTzyPpNIHJTc4mWnFkwBUmO9U3KPgJAmTx7oxi2bl/Rh6HLdU7+4C9wlj0k2E4AdKFQ== which@2.0.2, which@^2.0.1: version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" wide-align@1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz" integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== dependencies: string-width "^1.0.2 || 2" word-wrap@^1.2.3: version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== workerpool@6.1.0: version "6.1.0" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.0.tgz#a8e038b4c94569596852de7a8ea4228eefdeb37b" + resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz" integrity sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg== wrap-ansi@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== dependencies: ansi-styles "^4.0.0" @@ -2008,32 +1999,27 @@ wrap-ansi@^7.0.0: wrappy@1: version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + integrity "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" y18n@^5.0.5: version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== yallist@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yargs-parser@20.2.4: +yargs-parser@20.2.4, yargs-parser@^20.2.2: version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz" integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - yargs-unparser@2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + resolved "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz" integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== dependencies: camelcase "^6.0.0" @@ -2043,7 +2029,7 @@ yargs-unparser@2.0.0: yargs@16.2.0: version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== dependencies: cliui "^7.0.2" @@ -2056,5 +2042,5 @@ yargs@16.2.0: yocto-queue@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==