diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..e868bcf3 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +*.pegjs diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 00000000..13b430ef --- /dev/null +++ b/.eslintrc @@ -0,0 +1,13 @@ +{ + "parserOptions": { + "sourceType": "module", + "ecmaVersion": 2022 + }, + "rules": { + "indent": ["error", 2], + "linebreak-style": ["error", "unix"], + "object-curly-spacing": ["error", "never"], + "space-before-function-paren": ["error", "always"], + "semi": ["error", "never"] + } +} diff --git a/.github/workflows/pulsar_test.yml b/.github/workflows/pulsar_test.yml index deb2404b..d3aa6cf0 100644 --- a/.github/workflows/pulsar_test.yml +++ b/.github/workflows/pulsar_test.yml @@ -14,11 +14,17 @@ jobs: - name: Checkout the Latest Package Code uses: actions/checkout@v3 - name: Setup Pulsar Editor - uses: pulsar-edit/action-pulsar-dependency@v2.1 - with: - package-to-test: "snippets" + uses: pulsar-edit/action-pulsar-dependency@v3.2 + - name: Install dependencies (Windows) + if: ${{ runner.os == 'Windows' }} + # Currently the Pulsar process starts, but unlike *nix doesn't wait for ppm to finish, probably because pulsar.cmd needs updated + # So we'll fallback to ppm (still named apm) instead + run: apm install + - name: Install dependencies (*nix) + if: ${{ runner.os != 'Windows' }} + run: pulsar --package install - name: Run the headless Pulsar Tests - uses: GabrielBB/xvfb-action@v1 + uses: coactions/setup-xvfb@v1.0.1 with: - run: yarn start --test spec - working-directory: ./pulsar + run: pulsar --test spec + # working-directory: ./pulsar diff --git a/README.md b/README.md index 267f42cb..91836e7a 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ Snippets files are stored in a package's `snippets/` folder and also loaded from '.source.js': 'console.log': 'prefix': 'log' + 'command': 'insert-console-log' 'body': 'console.log(${1:"crash"});$2' ``` @@ -20,11 +21,11 @@ The outermost keys are the selectors where these snippets should be active, pref The next level of keys are the snippet names. -Under each snippet name is a `prefix` that should trigger the snippet and a `body` to insert when the snippet is triggered. +Under each snippet name is a `body` to insert when the snippet is triggered. -`$` followed by a number are the tabs stops which can be cycled between by pressing tab once a snippet has been triggered. +`$` followed by a number are the tabs stops which can be cycled between by pressing Tab once a snippet has been triggered. -The above example adds a `log` snippet to JavaScript files that would expand to. +The above example adds a `console.log` snippet to JavaScript files that would expand to: ```js console.log("crash"); @@ -32,7 +33,26 @@ console.log("crash"); The string `"crash"` would be initially selected and pressing tab again would place the cursor after the `;` +A snippet must define **at least one** of the following keys: + +### The ‘prefix’ key + +If a `prefix` is defined, it specifies a string that can trigger the snippet: type the string in the editor and press Tab. In this example, typing `log` (as its own word) and then pressing Tab would replace `log` with the string `console.log("crash")` as described above. + +Prefix completions can be suggested if partially typed thanks to the `autocomplete-snippets` package. + +### The ‘command’ key + +If a `command` is defined, it specifies a command name that can trigger the snippet. That command can be invoked from the command palette or mapped to a keyboard shortcut via your `keymap.cson`. + +If you defined the `console.log` snippet described above in your own `snippets.cson`, it would be available in the command palette as “Snippets: Insert Console Log”, or could be referenced in a keymap file as `snippets:insert-console-log`. + +If a package called `some-package` had defined that snippet, it would be available in the keymap as `some-package:insert-console-log`, or in the command palette as “Some Package: Insert Console Log”. + +Invoking the command would insert the snippet at the cursor, replacing any text that may be selected. + ### Optional parameters + These parameters are meant to provide extra information about your snippet to [autocomplete-plus](https://github.com/atom/autocomplete-plus/wiki/Provider-API). * `leftLabel` will add text to the left part of the autocomplete results box. diff --git a/lib/editor-store.js b/lib/editor-store.js index c57cb7ad..44678b78 100644 --- a/lib/editor-store.js +++ b/lib/editor-store.js @@ -27,7 +27,10 @@ class EditorStore { } observeHistory (delegates) { - if (this.existingHistoryProvider == null) { + let isObservingHistory = this.existingHistoryProvider != null + if (isObservingHistory) { + return + } else { this.existingHistoryProvider = this.buffer.historyProvider } diff --git a/lib/snippet-expansion.js b/lib/snippet-expansion.js index a1545cd4..b962d803 100644 --- a/lib/snippet-expansion.js +++ b/lib/snippet-expansion.js @@ -1,7 +1,7 @@ const {CompositeDisposable, Range, Point} = require('atom') module.exports = class SnippetExpansion { - constructor(snippet, editor, cursor, snippets) { + constructor (snippet, editor, cursor, snippets) { this.settingTabStop = false this.isIgnoringBufferChanges = false this.onUndoOrRedo = this.onUndoOrRedo.bind(this) @@ -175,7 +175,7 @@ module.exports = class SnippetExpansion { const marker = this.getMarkerLayer(this.editor).markBufferRange([ startPosition.traverse(start), startPosition.traverse(end) - ], { exclusive: !shouldBeInclusive }) + ], {exclusive: !shouldBeInclusive}) // Now that we've created these markers, we need to store them in a // data structure because they'll need to be deleted and re-created // when their exclusivity changes. @@ -364,7 +364,7 @@ module.exports = class SnippetExpansion { this.getMarkerLayer(this.editor).clear() this.insertionsByIndex = [] this.relatedInsertionsByIndex = new Map() - this.markersForInsertions = new Map(); + this.markersForInsertions = new Map() this.snippets.stopObservingEditor(this.editor) this.snippets.clearExpansions(this.editor) } diff --git a/lib/snippet.js b/lib/snippet.js index d3b1767d..b432fe83 100644 --- a/lib/snippet.js +++ b/lib/snippet.js @@ -12,17 +12,23 @@ function tabStopsReferencedWithinTabStopContent (segment) { } module.exports = class Snippet { - constructor({name, prefix, bodyText, description, descriptionMoreURL, rightLabelHTML, leftLabel, leftLabelHTML, bodyTree}) { + constructor ({name, prefix, command, bodyText, description, packageName, descriptionMoreURL, rightLabelHTML, leftLabel, leftLabelHTML, bodyTree, selector}) { this.name = name this.prefix = prefix + this.command = command + this.packageName = packageName this.bodyText = bodyText this.description = description this.descriptionMoreURL = descriptionMoreURL this.rightLabelHTML = rightLabelHTML this.leftLabel = leftLabel this.leftLabelHTML = leftLabelHTML + this.selector = selector this.tabStopList = new TabStopList(this) this.body = this.extractTabStops(bodyTree) + if (packageName && command) { + this.commandName = `${packageName}:${command}` + } } extractTabStops (bodyTree) { @@ -35,10 +41,14 @@ module.exports = class Snippet { for (const segment of bodyTree) { if (segment.index != null) { let {index, content, substitution} = segment - if (index === 0) { index = Infinity; } + // Ensure tabstop `$0` is always last. + if (index === 0) { index = Infinity } + const start = [row, column] extractTabStops(content) + const referencedTabStops = tabStopsReferencedWithinTabStopContent(content) + const range = new Range(start, [row, column]) const tabStop = this.tabStopList.findOrCreate({ index, diff --git a/lib/snippets.js b/lib/snippets.js index e544e720..b86427ec 100644 --- a/lib/snippets.js +++ b/lib/snippets.js @@ -11,6 +11,117 @@ const SnippetExpansion = require('./snippet-expansion') const EditorStore = require('./editor-store') const {getPackageRoot} = require('./helpers') +// TODO: Not sure about validity of numbers in here, but might as well be +// permissive. +const COMMAND_NAME_PATTERN = /^[a-z\d][a-z\d\-]*[a-z\d]$/ +function isValidCommandName (commandName) { + return COMMAND_NAME_PATTERN.test(commandName) +} + +function showCommandNameConflictNotification (name, commandName, packageName, snippetsPath) { + let remedy + if (packageName === 'builtin') { + // If somehow this happens with a builtin snippet, something crazy is + // happening. But we shouldn't show a notification because there's no + // action for the user to take. Just fail silently. + return + } + if (packageName === 'snippets') { + let extension = snippetsPath.substring(snippetsPath.length - 4) + remedy = `Edit your \`snippets.${extension}\` file to resolve this conflict.` + } else { + remedy = `Contact the maintainer of \`${packageName}\` so they can resolve this conflict.` + } + const message = `Cannot register command \`${commandName}\` for snippet “${name}” because that command name already exists.\n\n${remedy}` + atom.notifications.addError( + `Snippets conflict`, + { + description: message, + dismissable: true + } + ) +} + +function showInvalidCommandNameNotification (name, commandName) { + const message = `Cannot register \`${commandName}\` for snippet “${name}” because the command name isn’t valid. Command names must be all lowercase and use hyphens between words instead of spaces.` + atom.notifications.addError( + `Snippets error`, + { + description: message, + dismissable: true + } + ) +} + +// When we first run, checking `atom.commands.registeredCommands` is a good way +// of checking whether a command of a certain name already exists. But if we +// register a command and then unregister it (e.g., upon later disabling of a +// package's snippets), the relevant key won't get deleted from +// `registeredCommands`. So if the user re-enables the snippets, we'll +// incorrectly think that the command already exists. +// +// Hence, after the first check, we have to keep track ourselves. At least this +// gives us a place to keep track of individual command disposables. +// +const CommandMonitor = { + map: new Map, + disposables: new Map, + compositeDisposable: new CompositeDisposable, + exists (commandName) { + let {map} = this + if (!map.has(commandName)) { + // If it's missing altogether from the registry, we haven't asked yet. + let value = atom.commands.registeredCommands[commandName] + map.set(commandName, value) + return value + } else { + return map.get(commandName) + } + }, + + add (commandName, disposable) { + this.map.set(commandName, true) + this.disposables.set(commandName, disposable) + this.compositeDisposable.add(disposable) + }, + + remove (commandName) { + this.map.set(commandName, false) + let disposable = this.disposables.get(commandName) + if (disposable) { disposable.dispose() } + }, + + reset () { + this.map.clear() + this.disposables.clear() + this.compositeDisposable.dispose() + } +} + +// When we load snippets from packages, we're given a bunch of package paths +// instead of package names. This lets us match the former to the latter. +const PackageNameResolver = { + pathsToNames: new Map, + setup () { + this.pathsToNames.clear() + let meta = atom.packages.getLoadedPackages() || [] + for (let {name, path} of meta) { + this.pathsToNames.set(path, name) + } + if (!this._observing) { + atom.packages.onDidLoadPackage(() => this.setup()) + atom.packages.onDidUnloadPackage(() => this.setup()) + } + this._observing = true + }, + find (filePath) { + for (let [packagePath, name] of this.pathsToNames.entries()) { + if (filePath.startsWith(packagePath)) return name + } + return null + } +} + module.exports = { activate () { this.loaded = false @@ -36,19 +147,26 @@ module.exports = { } })) + PackageNameResolver.setup() + this.loadAll() this.watchUserSnippets(watchDisposable => { this.subscriptions.add(watchDisposable) }) - this.subscriptions.add(atom.config.onDidChange('core.packagesWithSnippetsDisabled', ({newValue, oldValue}) => { - this.handleDisabledPackagesDidChange(newValue, oldValue) - })) + this.subscriptions.add( + atom.config.onDidChange( + 'core.packagesWithSnippetsDisabled', + ({newValue, oldValue}) => { + this.handleDisabledPackagesDidChange(newValue, oldValue) + } + ) + ) const snippets = this this.subscriptions.add(atom.commands.add('atom-text-editor', { - 'snippets:expand'(event) { + 'snippets:expand' (event) { const editor = this.getModel() if (snippets.snippetToExpandUnderCursor(editor)) { snippets.clearExpansions(editor) @@ -58,20 +176,22 @@ module.exports = { } }, - 'snippets:next-tab-stop'(event) { + 'snippets:next-tab-stop' (event) { const editor = this.getModel() if (!snippets.goToNextTabStop(editor)) { event.abortKeyBinding() } }, - 'snippets:previous-tab-stop'(event) { + 'snippets:previous-tab-stop' (event) { const editor = this.getModel() if (!snippets.goToPreviousTabStop(editor)) { event.abortKeyBinding() } }, - 'snippets:available'(event) { + 'snippets:available' (event) { const editor = this.getModel() const SnippetsAvailable = require('./snippets-available') - if (snippets.availableSnippetsView == null) { snippets.availableSnippetsView = new SnippetsAvailable(snippets) } + if (snippets.availableSnippetsView == null) { + snippets.availableSnippetsView = new SnippetsAvailable(snippets) + } snippets.availableSnippetsView.toggle(editor) } })) @@ -84,6 +204,7 @@ module.exports = { this.emitter = null this.editorSnippetExpansions = null atom.config.transact(() => this.subscriptions.dispose()) + CommandMonitor.reset() }, getUserSnippetsPath () { @@ -99,11 +220,15 @@ module.exports = { this.loadPackageSnippets(packageSnippets => { this.loadUserSnippets(userSnippets => { atom.config.transact(() => { - for (const snippetSet of [bundledSnippets, packageSnippets, userSnippets]) { - for (const filepath in snippetSet) { - const snippetsBySelector = snippetSet[filepath] - this.add(filepath, snippetsBySelector) - } + for (const [filepath, snippetsBySelector] of Object.entries(bundledSnippets)) { + this.add(filepath, snippetsBySelector, 'builtin') + } + for (const [filepath, snippetsBySelector] of Object.entries(packageSnippets)) { + let packageName = PackageNameResolver.find(filepath) || 'snippets' + this.add(filepath, snippetsBySelector, packageName) + } + for (const [filepath, snippetsBySelector] of Object.entries(userSnippets)) { + this.add(filepath, snippetsBySelector, 'snippets') } }) this.doneLoading() @@ -168,11 +293,22 @@ module.exports = { // Called when a user's snippets file is changed, deleted, or moved so that we // can immediately re-process the snippets it contains. handleUserSnippetsDidChange () { + // TODO: There appear to be scenarios where this method gets invoked more + // than once with each change to the user's `snippets.cson`. To prevent + // more than one concurrent rescan of the snippets file, we block any + // additional calls to this method while the first call is still operating. const userSnippetsPath = this.getUserSnippetsPath() + + if (this.isHandlingUserSnippetsChange) { + return + } + + this.isHandlingUserSnippetsChange = true atom.config.transact(() => { this.clearSnippetsForPath(userSnippetsPath) this.loadSnippetsFile(userSnippetsPath, result => { - this.add(userSnippetsPath, result) + this.add(userSnippetsPath, result, 'snippets') + this.isHandlingUserSnippetsChange = false }) }) }, @@ -200,7 +336,7 @@ module.exports = { const snippetSet = this.snippetsByPackage.get(packageName) for (const filePath in snippetSet) { const snippetsBySelector = snippetSet[filePath] - this.add(filePath, snippetsBySelector) + this.add(filePath, snippetsBySelector, packageName) } }, @@ -218,7 +354,7 @@ module.exports = { loadPackageSnippets (callback) { const disabledPackageNames = atom.config.get('core.packagesWithSnippetsDisabled') || [] const packages = atom.packages.getLoadedPackages().sort((pack, _) => { - return /\/node_modules\//.test(pack.path) ? -1 : 1 + return pack.path.includes(`${path.sep}node_modules${path.sep}`) ? -1 : 1 }) const snippetsDirPaths = [] @@ -274,7 +410,7 @@ module.exports = { loadSnippetsDirectory (snippetsDirPath, callback) { fs.stat(snippetsDirPath, (error, stat) => { - if (error || !stat.isDirectory()) return callback(null, {}); + if (error || !stat.isDirectory()) return callback(null, {}) fs.readdir(snippetsDirPath, (error, entries) => { if (error) { @@ -294,7 +430,8 @@ module.exports = { snippetsByPath[filePath] = snippets } callback(null, snippetsByPath) - }) + } + ) }) }) }, @@ -310,30 +447,143 @@ module.exports = { }) }, - add (filePath, snippetsBySelector, isDisabled = false) { + add (filePath, snippetsBySelector, packageName = null, isDisabled = false) { + packageName ??= 'snippets' for (const selector in snippetsBySelector) { const snippetsByName = snippetsBySelector[selector] const unparsedSnippetsByPrefix = {} for (const name in snippetsByName) { const attributes = snippetsByName[name] - const {prefix, body} = attributes + const {prefix, command, body} = attributes + if (!prefix && !command) { + // A snippet must define either `prefix` or `command`, or both. + // TODO: Worth showing notification? + console.error(`Skipping snippet ${name}: no "prefix" or "command" property present`) + continue + } + attributes.selector = selector attributes.name = name attributes.id = this.snippetIdCounter++ - if (typeof body === 'string') { - unparsedSnippetsByPrefix[prefix] = attributes - } else if (body == null) { - unparsedSnippetsByPrefix[prefix] = null + attributes.packageName = packageName + // Snippets with "prefix"es will get indexed according to that prefix. + // Snippets without "prefix"es will be indexed by their ID below _if_ + // they have a "command" property. Snippets without "prefix" or + // "command" have already been filtered out. + if (prefix) { + if (typeof body === 'string') { + unparsedSnippetsByPrefix[prefix] = attributes + } else if (body == null) { + unparsedSnippetsByPrefix[prefix] = null + } + } + if (command) { + if (!isValidCommandName(command)) { + showInvalidCommandNameNotification(name, command) + continue + } + if (!prefix) { + // We need a key for these snippets that will not clash with any + // prefix key. Since prefixes aren't allowed to have spaces, we'll + // put a space in this key. + // + // We'll use the snippet ID as part of the key. If a snippet's + // `command` property clashes with another command, we'll catch + // that later. + let unparsedSnippetsKey = `command ${attributes.id}` + if (typeof body === 'string') { + unparsedSnippetsByPrefix[unparsedSnippetsKey] = attributes + } else { + unparsedSnippetsByPrefix[unparsedSnippetsKey] = null + } + } + if (!isDisabled) { + this.addCommandForSnippet(attributes, packageName, selector) + } } } - this.storeUnparsedSnippets(unparsedSnippetsByPrefix, filePath, selector, isDisabled) + this.storeUnparsedSnippets(unparsedSnippetsByPrefix, filePath, selector, packageName, isDisabled) } }, + addCommandForSnippet (attributes, packageName, selector) { + packageName = packageName || 'snippets' + let {name, command} = attributes + let commandName = `${packageName}:${command}` + console.trace() + if (CommandMonitor.exists(commandName)) { + console.error(`Skipping ${commandName} because it's already been registered!`) + showCommandNameConflictNotification( + name, + commandName, + packageName, + this.getUserSnippetsPath() + ) + // We won't remove the snippet because it might still be triggerable by + // prefix. But we will null out the `command` property to prevent any + // possible confusion. + attributes.command = null + return + } + + let commandHandler = (event) => { + let editor = event.target.closest('atom-text-editor').getModel() + + // We match the multi-cursor behavior that prefix-triggered snippets + // exhibit: only the last cursor determines which scoped set of snippets + // we pull, but we'll insert this snippet for each cursor, whether it + // happens to be valid for that cursor's scope or not. This could + // possibly be refined in the future. + let snippets = this.getSnippets(editor) + + let targetSnippet = null + for (let snippet of Object.values(snippets)) { + if (snippet.command === command && snippet.packageName === packageName) { + targetSnippet = snippet + break + } + } + + if (!targetSnippet) { + // We don't show an error notification here because it isn't + // necessarily a mistake. But we put a warning in the console just in + // case the user is confused. + console.warn(`Snippet “${name}” not invoked because its scope was not matched.`) + + // Because its scope was not matched, we abort the key binding; this + // signals to the key binding resolver that it can pick the next + // candidate for a key shortcut, if one exists. + return event.abortKeyBinding() + } + + this.getStore(editor).observeHistory({ + undo: event => { this.onUndoOrRedo(editor, event, true) }, + redo: event => { this.onUndoOrRedo(editor, event, false) } + }) + this.findOrCreateMarkerLayer(editor) + editor.transact(() => { + const cursors = editor.getCursors() + for (const cursor of cursors) { + this.insert(targetSnippet, editor, cursor) + } + }) + } + + let disposable = atom.commands.add( + 'atom-text-editor', + commandName, + commandHandler + ) + + this.subscriptions.add(disposable) + CommandMonitor.add(commandName, disposable) + }, + addSnippetsInDisabledPackage (bundle) { for (const filePath in bundle) { const snippetsBySelector = bundle[filePath] - this.add(filePath, snippetsBySelector, true) + const packageName = PackageNameResolver.find(filePath) + this.add(filePath, snippetsBySelector, packageName, true) } }, @@ -348,7 +598,7 @@ module.exports = { .join(' ') }, - storeUnparsedSnippets (value, path, selector, isDisabled = false) { + storeUnparsedSnippets (value, path, selector, packageName, isDisabled = false) { // The `isDisabled` flag determines which scoped property store we'll use. // Active snippets get put into one and inactive snippets get put into // another. Only the first one gets consulted when we look up a snippet @@ -362,9 +612,15 @@ module.exports = { clearSnippetsForPath (path) { for (const scopeSelector in this.scopedPropertyStore.propertiesForSource(path)) { - const object = this.scopedPropertyStore.propertiesForSourceAndSelector(path, scopeSelector) + let object = this.scopedPropertyStore.propertiesForSourceAndSelector(path, scopeSelector) + if (object.snippets) { object = object.snippets } for (const prefix in object) { const attributes = object[prefix] + if (!attributes) { continue } + let {command, packageName} = attributes + if (packageName && command) { + CommandMonitor.remove(`${packageName}:${command}`) + } this.parsedSnippetsById.delete(attributes.id) } @@ -416,9 +672,9 @@ module.exports = { getParsedSnippet (attributes) { let snippet = this.parsedSnippetsById.get(attributes.id) if (snippet == null) { - let {id, prefix, name, body, bodyTree, description, descriptionMoreURL, rightLabelHTML, leftLabel, leftLabelHTML} = attributes + let {id, prefix, command, name, body, bodyTree, description, packageName, descriptionMoreURL, rightLabelHTML, leftLabel, leftLabelHTML, selector} = attributes if (bodyTree == null) { bodyTree = this.getBodyParser().parse(body) } - snippet = new Snippet({id, name, prefix, bodyTree, description, descriptionMoreURL, rightLabelHTML, leftLabel, leftLabelHTML, bodyText: body}) + snippet = new Snippet({id, name, prefix, command, bodyTree, description, packageName, descriptionMoreURL, rightLabelHTML, leftLabel, leftLabelHTML, selector, bodyText: body}) this.parsedSnippetsById.set(attributes.id, snippet) } return snippet @@ -485,6 +741,10 @@ module.exports = { let longestPrefixMatch = null for (const snippetPrefix in snippets) { + // Any snippet without a prefix was keyed on its snippet ID, but with a + // space introduced to ensure it would never be a prefix match. But let's + // play it safe here anyway. + if (snippetPrefix.includes(' ')) { continue } const snippet = snippets[snippetPrefix] if (prefix.endsWith(snippetPrefix) && (wordPrefix.length <= snippetPrefix.length)) { if ((longestPrefixMatch == null) || (snippetPrefix.length > longestPrefixMatch.prefix.length)) { @@ -634,11 +894,11 @@ module.exports = { const iterate = sets => { for (const item of sets) { const newItem = _.deepClone(item) - // The atom-slick library has already parsed the `selector` property, so - // it's an AST here instead of a string. The object has a `toString` + // The atom-slick library has already parsed the `selector` property, + // so it's an AST here instead of a string. The object has a `toString` // method that turns it back into a string. That custom behavior won't - // be preserved in the deep clone of the object, so we have to handle it - // separately. + // be preserved in the deep clone of the object, so we have to handle + // it separately. newItem.selectorString = item.selector.toString() results.push(newItem) } @@ -659,7 +919,7 @@ module.exports = { } }, - onUndoOrRedo (editor, isUndo) { + onUndoOrRedo (editor, event, isUndo) { const activeExpansions = this.getExpansions(editor) activeExpansions.forEach(expansion => expansion.onUndoOrRedo(isUndo)) } diff --git a/package-lock.json b/package-lock.json index eaf0e7bc..d5bda9b6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,29 +19,203 @@ "underscore-plus": "^1.0.0" }, "devDependencies": { - "coffeelint": "^1.9.7" + "eslint": "^8.33.0" }, "engines": { "atom": "*" } }, + "node_modules/@eslint/eslintrc": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "5.2.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/eslintrc/node_modules/strip-json-comments": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.8", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/acorn": { + "version": "8.8.2", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/ansi-regex": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "dev": true, + "license": "Python-2.0" + }, "node_modules/async": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", - "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=" + "version": "0.2.10" }, "node_modules/atom-select-list": { "version": "0.7.2", - "resolved": "https://registry.npmjs.org/atom-select-list/-/atom-select-list-0.7.2.tgz", - "integrity": "sha512-a707OB1DhLGjzqtFrtMQKH7BBxFuCh8UBoUWxgFOrLrSwVh3g+/TlVPVDOz12+U0mDu3mIrnYLqQyhywQOTxhw==", + "license": "MIT", "dependencies": { "etch": "^0.12.6", "fuzzaldrin": "^2.1.0" @@ -49,38 +223,56 @@ }, "node_modules/atom-slick": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/atom-slick/-/atom-slick-2.0.0.tgz", - "integrity": "sha1-/w2+Fb4sTtomi50w124lF+C308o=", + "license": "MIT (http://mootools.net/license.txt)", "engines": { "node": "*" } }, "node_modules/balanced-match": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "license": "MIT" }, "node_modules/brace-expansion": { "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, + "node_modules/callsites": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/camelcase": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/cliui": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "license": "ISC", "dependencies": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1", @@ -89,17 +281,14 @@ }, "node_modules/code-point-at": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/coffee-script": { "version": "1.12.7", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz", - "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==", - "deprecated": "CoffeeScript on NPM has moved to \"coffeescript\" (no hyphen)", + "license": "MIT", "bin": { "cake": "bin/cake", "coffee": "bin/coffee" @@ -108,84 +297,94 @@ "node": ">=0.8.0" } }, - "node_modules/coffeelint": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/coffeelint/-/coffeelint-1.16.0.tgz", - "integrity": "sha1-g9jtHa/eOmd95E57ihi+YHdh5tg=", + "node_modules/color-convert": { + "version": "2.0.1", "dev": true, + "license": "MIT", "dependencies": { - "coffee-script": "~1.11.0", - "glob": "^7.0.6", - "ignore": "^3.0.9", - "optimist": "^0.6.1", - "resolve": "^0.6.3", - "strip-json-comments": "^1.0.2" - }, - "bin": { - "coffeelint": "bin/coffeelint" + "color-name": "~1.1.4" }, "engines": { - "node": ">=0.8.0", - "npm": ">=1.3.7" + "node": ">=7.0.0" } }, - "node_modules/coffeelint/node_modules/coffee-script": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.11.1.tgz", - "integrity": "sha1-vxxHrWREOg2V0S3ysUfMCk2q1uk=", - "deprecated": "CoffeeScript on NPM has moved to \"coffeescript\" (no hyphen)", + "node_modules/color-name": { + "version": "1.1.4", "dev": true, - "bin": { - "cake": "bin/cake", - "coffee": "bin/coffee" - }, - "engines": { - "node": ">=0.8.0" - } + "license": "MIT" }, - "node_modules/coffeelint/node_modules/optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "node_modules/concat-map": { + "version": "0.0.1", + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", "dev": true, + "license": "MIT", "dependencies": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, "node_modules/cson-parser": { "version": "1.3.5", - "resolved": "https://registry.npmjs.org/cson-parser/-/cson-parser-1.3.5.tgz", - "integrity": "sha1-fsZ14DkUVTO/KmqFYHPxWZ2cLSQ=", + "license": "BSD-3-Clause", "dependencies": { "coffee-script": "^1.10.0" } }, "node_modules/d": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/d/-/d-0.1.1.tgz", - "integrity": "sha1-2hhMU10Y2O57oqoim5FACfrhEwk=", + "license": "MIT", "dependencies": { "es5-ext": "~0.10.2" } }, + "node_modules/debug": { + "version": "4.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/decamelize": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/deep-is": { + "version": "0.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/doctrine": { + "version": "3.0.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/emissary": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/emissary/-/emissary-1.3.3.tgz", - "integrity": "sha1-phjZLWgrIy0xER3DYlpd9mF5lgY=", "dependencies": { "es6-weak-map": "^0.1.2", "mixto": "1.x", @@ -195,8 +394,7 @@ }, "node_modules/es5-ext": { "version": "0.10.30", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz", - "integrity": "sha1-cUGhaDZpfbq/qq7uQUlc4p9SyTk=", + "license": "MIT", "dependencies": { "es6-iterator": "2", "es6-symbol": "~3.1" @@ -204,16 +402,14 @@ }, "node_modules/es5-ext/node_modules/d": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "license": "MIT", "dependencies": { "es5-ext": "^0.10.9" } }, "node_modules/es5-ext/node_modules/es6-iterator": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", - "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=", + "license": "MIT", "dependencies": { "d": "1", "es5-ext": "^0.10.14", @@ -222,8 +418,7 @@ }, "node_modules/es5-ext/node_modules/es6-symbol": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "license": "MIT", "dependencies": { "d": "1", "es5-ext": "~0.10.14" @@ -231,8 +426,7 @@ }, "node_modules/es6-iterator": { "version": "0.1.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-0.1.3.tgz", - "integrity": "sha1-1vWLjE/EE8JJtLqhl2j45NfIlE4=", + "license": "MIT", "dependencies": { "d": "~0.1.1", "es5-ext": "~0.10.5", @@ -241,8 +435,7 @@ }, "node_modules/es6-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-2.0.1.tgz", - "integrity": "sha1-dhtcZ8/U8dGK+yNPaR1nhoLLO/M=", + "license": "MIT", "dependencies": { "d": "~0.1.1", "es5-ext": "~0.10.5" @@ -250,8 +443,7 @@ }, "node_modules/es6-weak-map": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-0.1.4.tgz", - "integrity": "sha1-cGzvnpmqI2undmwjnIueKG6n0ig=", + "license": "MIT", "dependencies": { "d": "~0.1.1", "es5-ext": "~0.10.6", @@ -259,23 +451,343 @@ "es6-symbol": "~2.0.1" } }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.33.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint/eslintrc": "^1.4.1", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "7.1.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/ignore": { + "version": "5.2.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/strip-json-comments": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "9.4.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/etch": { "version": "0.12.8", - "resolved": "https://registry.npmjs.org/etch/-/etch-0.12.8.tgz", - "integrity": "sha512-dFLRe4wLroVtwzyy1vGlE3BSDZHiL0kZME5XgNGzZIULcYTvVno8vbiIleAesoKJmwWaxDTzG+4eppg2zk14JQ==" + "license": "MIT" }, "node_modules/event-kit": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/event-kit/-/event-kit-1.5.0.tgz", - "integrity": "sha1-Ek72qtgyjcsmtxxHWQtbjmPrxIc=", "dependencies": { "grim": "^1.2.1" } }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.15.0", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flat-cache/node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flat-cache/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "dev": true, + "license": "ISC" + }, "node_modules/fs-plus": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fs-plus/-/fs-plus-3.0.1.tgz", - "integrity": "sha1-VMFpxA4ohKZtNSeA0Y3TH5HToQ0=", + "license": "MIT", "dependencies": { "async": "^1.5.2", "mkdirp": "^0.5.1", @@ -285,23 +797,18 @@ }, "node_modules/fs-plus/node_modules/async": { "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + "license": "MIT" }, "node_modules/fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "license": "ISC" }, "node_modules/fuzzaldrin": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fuzzaldrin/-/fuzzaldrin-2.1.0.tgz", - "integrity": "sha1-kCBMPi/appQbso0WZF1BgGOpDps=" + "version": "2.1.0" }, "node_modules/glob": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -314,24 +821,76 @@ "node": "*" } }, + "node_modules/glob-parent": { + "version": "6.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.20.0", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "dev": true, + "license": "MIT" + }, "node_modules/grim": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/grim/-/grim-1.5.0.tgz", - "integrity": "sha1-sysI71Z88YUvgXWe2caLDXE5ajI=", "dependencies": { "emissary": "^1.2.0" } }, - "node_modules/ignore": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz", - "integrity": "sha1-xOcVRV9gc6jX5drnLS/J1xZj26Y=", - "dev": true + "node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } }, "node_modules/inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -339,53 +898,138 @@ }, "node_modules/inherits": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "license": "ISC" }, "node_modules/invert-kv": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/js-sdsl": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/key-path-helpers": { + "version": "0.1.0" + }, + "node_modules/lcid": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "invert-kv": "^1.0.0" + }, "engines": { "node": ">=0.10.0" } }, - "node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "node_modules/levn": { + "version": "0.4.1", + "dev": true, + "license": "MIT", "dependencies": { - "number-is-nan": "^1.0.0" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8.0" } }, - "node_modules/key-path-helpers": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/key-path-helpers/-/key-path-helpers-0.1.0.tgz", - "integrity": "sha1-zYFJULeZzHRaNGqlIfkilK9du6Q=" - }, - "node_modules/lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "node_modules/locate-path": { + "version": "6.0.0", + "dev": true, + "license": "MIT", "dependencies": { - "invert-kv": "^1.0.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "dev": true, + "license": "MIT" + }, "node_modules/loophole": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/loophole/-/loophole-1.1.0.tgz", - "integrity": "sha1-N5Sf6kU7YlasxyXDIM4MWn9wor0=" + "license": "MIT" }, "node_modules/minimatch": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -395,19 +1039,14 @@ }, "node_modules/minimist": { "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + "license": "MIT" }, "node_modules/mixto": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mixto/-/mixto-1.0.0.tgz", - "integrity": "sha1-wyDvYbUvKJj1IuF9i7xtUG2EJbY=" + "version": "1.0.0" }, "node_modules/mkdirp": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "license": "MIT", "dependencies": { "minimist": "0.0.8" }, @@ -415,26 +1054,49 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/ms": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, "node_modules/number-is-nan": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "license": "ISC", "dependencies": { "wrappy": "1" } }, + "node_modules/optionator": { + "version": "0.9.1", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/os-locale": { "version": "1.4.0", - "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "license": "MIT", "dependencies": { "lcid": "^1.0.0" }, @@ -444,24 +1106,75 @@ }, "node_modules/os-tmpdir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/p-limit": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/pegjs": { "version": "0.8.0", - "resolved": "https://registry.npmjs.org/pegjs/-/pegjs-0.8.0.tgz", - "integrity": "sha1-l28GfaE+XFsVAcAXklZoolOBFWE=", "bin": { "pegjs": "bin/pegjs" }, @@ -469,25 +1182,79 @@ "node": ">= 0.8" } }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/property-accessors": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/property-accessors/-/property-accessors-1.1.3.tgz", - "integrity": "sha1-Hd6EAkYxhlkJ7zBwM2VoDF+SixU=", "dependencies": { "es6-weak-map": "^0.1.2", "mixto": "1.x" } }, - "node_modules/resolve": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-0.6.3.tgz", - "integrity": "sha1-3ZV5gufnNt699TtYpN2RdUV13UY=", - "dev": true + "node_modules/punycode": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/regexpp": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } }, "node_modules/rimraf": { "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha1-LtgVDSShbqhlHm1u8PR8QVjOejY=", + "license": "ISC", "dependencies": { "glob": "^7.0.5" }, @@ -495,10 +1262,30 @@ "rimraf": "bin.js" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/scoped-property-store": { "version": "0.17.0", - "resolved": "https://registry.npmjs.org/scoped-property-store/-/scoped-property-store-0.17.0.tgz", - "integrity": "sha1-raAsANYC/SBQlh4nF92dArozGDE=", "dependencies": { "atom-slick": "^2", "event-kit": "^1.0.0", @@ -509,8 +1296,6 @@ }, "node_modules/season": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/season/-/season-6.0.2.tgz", - "integrity": "sha1-naWPsd3SSCTXYhstxjpxI7UCF7Y=", "dependencies": { "cson-parser": "^1.3.0", "fs-plus": "^3.0.0", @@ -520,10 +1305,28 @@ "csonc": "bin/csonc" } }, + "node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/string-width": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "license": "MIT", "dependencies": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -535,8 +1338,7 @@ }, "node_modules/strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "license": "MIT", "dependencies": { "ansi-regex": "^2.0.0" }, @@ -544,25 +1346,23 @@ "node": ">=0.10.0" } }, - "node_modules/strip-json-comments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", - "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", + "node_modules/supports-color": { + "version": "7.2.0", "dev": true, - "bin": { - "strip-json-comments": "cli.js" + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" }, "engines": { - "node": ">=0.8.0" + "node": ">=8" } }, "node_modules/temp": { "version": "0.8.3", - "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", - "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=", "engines": [ "node >=0.8.0" ], + "license": "MIT", "dependencies": { "os-tmpdir": "^1.0.0", "rimraf": "~2.2.6" @@ -570,29 +1370,72 @@ }, "node_modules/temp/node_modules/rimraf": { "version": "2.2.8", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", - "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", + "license": "MIT", "bin": { "rimraf": "bin.js" } }, + "node_modules/text-table": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/type-check": { + "version": "0.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/underscore": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", - "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=" + "version": "1.6.0" }, "node_modules/underscore-plus": { "version": "1.6.6", - "resolved": "https://registry.npmjs.org/underscore-plus/-/underscore-plus-1.6.6.tgz", - "integrity": "sha1-ZezeG9xEGjXYnmUP1w3PE65Dmn0=", "dependencies": { "underscore": "~1.6.0" } }, + "node_modules/uri-js": { + "version": "4.4.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/window-size": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", - "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=", + "license": "MIT", "bin": { "window-size": "cli.js" }, @@ -600,19 +1443,17 @@ "node": ">= 0.10.0" } }, - "node_modules/wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "node_modules/word-wrap": { + "version": "1.2.3", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.4.0" + "node": ">=0.10.0" } }, "node_modules/wrap-ansi": { "version": "2.1.0", - "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "license": "MIT", "dependencies": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1" @@ -623,18 +1464,15 @@ }, "node_modules/wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "license": "ISC" }, "node_modules/y18n": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + "license": "ISC" }, "node_modules/yargs": { "version": "3.32.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", - "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", + "license": "MIT", "dependencies": { "camelcase": "^2.0.1", "cliui": "^3.0.3", @@ -644,56 +1482,171 @@ "window-size": "^0.1.4", "y18n": "^3.2.0" } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } }, "dependencies": { + "@eslint/eslintrc": { + "version": "1.4.1", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "ignore": { + "version": "5.2.4", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "dev": true + } + } + }, + "@humanwhocodes/config-array": { + "version": "0.11.8", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "dependencies": { + "minimatch": { + "version": "3.1.2", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "dev": true + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "dev": true + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "acorn": { + "version": "8.8.2", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "dev": true, + "requires": {} + }, + "ajv": { + "version": "6.12.6", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + "version": "2.1.1" + }, + "ansi-styles": { + "version": "4.3.0", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "argparse": { + "version": "2.0.1", + "dev": true }, "async": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", - "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=" + "version": "0.2.10" }, "atom-select-list": { "version": "0.7.2", - "resolved": "https://registry.npmjs.org/atom-select-list/-/atom-select-list-0.7.2.tgz", - "integrity": "sha512-a707OB1DhLGjzqtFrtMQKH7BBxFuCh8UBoUWxgFOrLrSwVh3g+/TlVPVDOz12+U0mDu3mIrnYLqQyhywQOTxhw==", "requires": { "etch": "^0.12.6", "fuzzaldrin": "^2.1.0" } }, "atom-slick": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/atom-slick/-/atom-slick-2.0.0.tgz", - "integrity": "sha1-/w2+Fb4sTtomi50w124lF+C308o=" + "version": "2.0.0" }, "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "version": "1.0.0" }, "brace-expansion": { "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, + "callsites": { + "version": "3.1.0", + "dev": true + }, "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" + "version": "2.1.1" + }, + "chalk": { + "version": "4.1.2", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } }, "cliui": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "requires": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1", @@ -701,77 +1654,69 @@ } }, "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + "version": "1.1.0" }, "coffee-script": { - "version": "1.12.7", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz", - "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==" + "version": "1.12.7" }, - "coffeelint": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/coffeelint/-/coffeelint-1.16.0.tgz", - "integrity": "sha1-g9jtHa/eOmd95E57ihi+YHdh5tg=", + "color-convert": { + "version": "2.0.1", "dev": true, "requires": { - "coffee-script": "~1.11.0", - "glob": "^7.0.6", - "ignore": "^3.0.9", - "optimist": "^0.6.1", - "resolve": "^0.6.3", - "strip-json-comments": "^1.0.2" - }, - "dependencies": { - "coffee-script": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.11.1.tgz", - "integrity": "sha1-vxxHrWREOg2V0S3ysUfMCk2q1uk=", - "dev": true - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - } + "color-name": "~1.1.4" } }, + "color-name": { + "version": "1.1.4", + "dev": true + }, "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "version": "0.0.1" + }, + "cross-spawn": { + "version": "7.0.3", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } }, "cson-parser": { "version": "1.3.5", - "resolved": "https://registry.npmjs.org/cson-parser/-/cson-parser-1.3.5.tgz", - "integrity": "sha1-fsZ14DkUVTO/KmqFYHPxWZ2cLSQ=", "requires": { "coffee-script": "^1.10.0" } }, "d": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/d/-/d-0.1.1.tgz", - "integrity": "sha1-2hhMU10Y2O57oqoim5FACfrhEwk=", "requires": { "es5-ext": "~0.10.2" } }, + "debug": { + "version": "4.3.4", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + "version": "1.2.0" + }, + "deep-is": { + "version": "0.1.4", + "dev": true + }, + "doctrine": { + "version": "3.0.0", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } }, "emissary": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/emissary/-/emissary-1.3.3.tgz", - "integrity": "sha1-phjZLWgrIy0xER3DYlpd9mF5lgY=", "requires": { "es6-weak-map": "^0.1.2", "mixto": "1.x", @@ -781,8 +1726,6 @@ }, "es5-ext": { "version": "0.10.30", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz", - "integrity": "sha1-cUGhaDZpfbq/qq7uQUlc4p9SyTk=", "requires": { "es6-iterator": "2", "es6-symbol": "~3.1" @@ -790,16 +1733,12 @@ "dependencies": { "d": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "requires": { "es5-ext": "^0.10.9" } }, "es6-iterator": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", - "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=", "requires": { "d": "1", "es5-ext": "^0.10.14", @@ -808,8 +1747,6 @@ }, "es6-symbol": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", "requires": { "d": "1", "es5-ext": "~0.10.14" @@ -819,8 +1756,6 @@ }, "es6-iterator": { "version": "0.1.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-0.1.3.tgz", - "integrity": "sha1-1vWLjE/EE8JJtLqhl2j45NfIlE4=", "requires": { "d": "~0.1.1", "es5-ext": "~0.10.5", @@ -829,8 +1764,6 @@ }, "es6-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-2.0.1.tgz", - "integrity": "sha1-dhtcZ8/U8dGK+yNPaR1nhoLLO/M=", "requires": { "d": "~0.1.1", "es5-ext": "~0.10.5" @@ -838,8 +1771,6 @@ }, "es6-weak-map": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-0.1.4.tgz", - "integrity": "sha1-cGzvnpmqI2undmwjnIueKG6n0ig=", "requires": { "d": "~0.1.1", "es5-ext": "~0.10.6", @@ -847,23 +1778,224 @@ "es6-symbol": "~2.0.1" } }, + "escape-string-regexp": { + "version": "4.0.0", + "dev": true + }, + "eslint": { + "version": "8.33.0", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.4.1", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "dev": true + }, + "ignore": { + "version": "5.2.4", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "strip-ansi": { + "version": "6.0.1", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "dev": true + } + } + }, + "eslint-scope": { + "version": "7.1.1", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-utils": { + "version": "3.0.0", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "3.3.0", + "dev": true + }, + "espree": { + "version": "9.4.1", + "dev": true, + "requires": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + } + }, + "esquery": { + "version": "1.4.0", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "dev": true + }, "etch": { - "version": "0.12.8", - "resolved": "https://registry.npmjs.org/etch/-/etch-0.12.8.tgz", - "integrity": "sha512-dFLRe4wLroVtwzyy1vGlE3BSDZHiL0kZME5XgNGzZIULcYTvVno8vbiIleAesoKJmwWaxDTzG+4eppg2zk14JQ==" + "version": "0.12.8" }, "event-kit": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/event-kit/-/event-kit-1.5.0.tgz", - "integrity": "sha1-Ek72qtgyjcsmtxxHWQtbjmPrxIc=", "requires": { "grim": "^1.2.1" } }, + "fast-deep-equal": { + "version": "3.1.3", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "dev": true + }, + "fastq": { + "version": "1.15.0", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "find-up": { + "version": "5.0.0", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "3.0.4", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "rimraf": { + "version": "3.0.2", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flatted": { + "version": "3.2.7", + "dev": true + }, "fs-plus": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fs-plus/-/fs-plus-3.0.1.tgz", - "integrity": "sha1-VMFpxA4ohKZtNSeA0Y3TH5HToQ0=", "requires": { "async": "^1.5.2", "mkdirp": "^0.5.1", @@ -872,26 +2004,18 @@ }, "dependencies": { "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + "version": "1.5.2" } } }, "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "version": "1.0.0" }, "fuzzaldrin": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fuzzaldrin/-/fuzzaldrin-2.1.0.tgz", - "integrity": "sha1-kCBMPi/appQbso0WZF1BgGOpDps=" + "version": "2.1.0" }, "glob": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -901,154 +2025,271 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "6.0.2", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "globals": { + "version": "13.20.0", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "grapheme-splitter": { + "version": "1.0.4", + "dev": true + }, "grim": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/grim/-/grim-1.5.0.tgz", - "integrity": "sha1-sysI71Z88YUvgXWe2caLDXE5ajI=", "requires": { "emissary": "^1.2.0" } }, - "ignore": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz", - "integrity": "sha1-xOcVRV9gc6jX5drnLS/J1xZj26Y=", + "has-flag": { + "version": "4.0.0", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", "dev": true }, "inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "requires": { "once": "^1.3.0", "wrappy": "1" } }, "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "version": "2.0.3" }, "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" + "version": "1.0.0" + }, + "is-extglob": { + "version": "2.1.1", + "dev": true }, "is-fullwidth-code-point": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "requires": { "number-is-nan": "^1.0.0" } }, + "is-glob": { + "version": "4.0.3", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-path-inside": { + "version": "3.0.3", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "dev": true + }, + "js-sdsl": { + "version": "4.3.0", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "dev": true + }, "key-path-helpers": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/key-path-helpers/-/key-path-helpers-0.1.0.tgz", - "integrity": "sha1-zYFJULeZzHRaNGqlIfkilK9du6Q=" + "version": "0.1.0" }, "lcid": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", "requires": { "invert-kv": "^1.0.0" } }, + "levn": { + "version": "0.4.1", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "locate-path": { + "version": "6.0.0", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "lodash.merge": { + "version": "4.6.2", + "dev": true + }, "loophole": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/loophole/-/loophole-1.1.0.tgz", - "integrity": "sha1-N5Sf6kU7YlasxyXDIM4MWn9wor0=" + "version": "1.1.0" }, "minimatch": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + "version": "0.0.8" }, "mixto": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mixto/-/mixto-1.0.0.tgz", - "integrity": "sha1-wyDvYbUvKJj1IuF9i7xtUG2EJbY=" + "version": "1.0.0" }, "mkdirp": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "requires": { "minimist": "0.0.8" } }, + "ms": { + "version": "2.1.2", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "dev": true + }, "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + "version": "1.0.1" }, "once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { "wrappy": "1" } }, + "optionator": { + "version": "0.9.1", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, "os-locale": { "version": "1.4.0", - "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", "requires": { "lcid": "^1.0.0" } }, "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + "version": "1.0.2" }, - "path-is-absolute": { + "p-limit": { + "version": "3.1.0", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "parent-module": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "path-exists": { + "version": "4.0.0", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1" + }, + "path-key": { + "version": "3.1.1", + "dev": true }, "pegjs": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/pegjs/-/pegjs-0.8.0.tgz", - "integrity": "sha1-l28GfaE+XFsVAcAXklZoolOBFWE=" + "version": "0.8.0" + }, + "prelude-ls": { + "version": "1.2.1", + "dev": true }, "property-accessors": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/property-accessors/-/property-accessors-1.1.3.tgz", - "integrity": "sha1-Hd6EAkYxhlkJ7zBwM2VoDF+SixU=", "requires": { "es6-weak-map": "^0.1.2", "mixto": "1.x" } }, - "resolve": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-0.6.3.tgz", - "integrity": "sha1-3ZV5gufnNt699TtYpN2RdUV13UY=", + "punycode": { + "version": "2.3.0", + "dev": true + }, + "queue-microtask": { + "version": "1.2.3", + "dev": true + }, + "regexpp": { + "version": "3.2.0", + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "dev": true + }, + "reusify": { + "version": "1.0.4", "dev": true }, "rimraf": { "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha1-LtgVDSShbqhlHm1u8PR8QVjOejY=", "requires": { "glob": "^7.0.5" } }, + "run-parallel": { + "version": "1.2.0", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, "scoped-property-store": { "version": "0.17.0", - "resolved": "https://registry.npmjs.org/scoped-property-store/-/scoped-property-store-0.17.0.tgz", - "integrity": "sha1-raAsANYC/SBQlh4nF92dArozGDE=", "requires": { "atom-slick": "^2", "event-kit": "^1.0.0", @@ -1059,18 +2300,25 @@ }, "season": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/season/-/season-6.0.2.tgz", - "integrity": "sha1-naWPsd3SSCTXYhstxjpxI7UCF7Y=", "requires": { "cson-parser": "^1.3.0", "fs-plus": "^3.0.0", "yargs": "^3.23.0" } }, + "shebang-command": { + "version": "2.0.0", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "dev": true + }, "string-width": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -1079,81 +2327,89 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" } }, - "strip-json-comments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", - "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", - "dev": true + "supports-color": { + "version": "7.2.0", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } }, "temp": { "version": "0.8.3", - "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", - "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=", "requires": { "os-tmpdir": "^1.0.0", "rimraf": "~2.2.6" }, "dependencies": { "rimraf": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", - "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=" + "version": "2.2.8" } } }, + "text-table": { + "version": "0.2.0", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.20.2", + "dev": true + }, "underscore": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", - "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=" + "version": "1.6.0" }, "underscore-plus": { "version": "1.6.6", - "resolved": "https://registry.npmjs.org/underscore-plus/-/underscore-plus-1.6.6.tgz", - "integrity": "sha1-ZezeG9xEGjXYnmUP1w3PE65Dmn0=", "requires": { "underscore": "~1.6.0" } }, + "uri-js": { + "version": "4.4.1", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "which": { + "version": "2.0.2", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, "window-size": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", - "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=" + "version": "0.1.4" }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "word-wrap": { + "version": "1.2.3", "dev": true }, "wrap-ansi": { "version": "2.1.0", - "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "requires": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1" } }, "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "version": "1.0.2" }, "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + "version": "3.2.1" }, "yargs": { "version": "3.32.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", - "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", "requires": { "camelcase": "^2.0.1", "cliui": "^3.0.3", @@ -1163,6 +2419,10 @@ "window-size": "^0.1.4", "y18n": "^3.2.0" } + }, + "yocto-queue": { + "version": "0.1.0", + "dev": true } } } diff --git a/package.json b/package.json index d70b5c75..cbd9d429 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,6 @@ } }, "devDependencies": { - "coffeelint": "^1.9.7" + "eslint": "^8.33.0" } } diff --git a/spec/.eslintrc b/spec/.eslintrc new file mode 100644 index 00000000..65bf2aac --- /dev/null +++ b/spec/.eslintrc @@ -0,0 +1,5 @@ +{ + "rules": { + "semi": ["error", "always"] + } +} diff --git a/spec/fixtures/package-with-snippets/snippets/test.cson b/spec/fixtures/package-with-snippets/snippets/test.cson index 1fe2e0ae..cb28534a 100644 --- a/spec/fixtures/package-with-snippets/snippets/test.cson +++ b/spec/fixtures/package-with-snippets/snippets/test.cson @@ -20,9 +20,12 @@ ".package-with-snippets-unique-scope": "Test Snippet": prefix: "test" - body: "testing 123" + body: "testing 123" ".source.js": "Overrides a core package's snippet": prefix: "log" body: "from-a-community-package" + "Maps to a command": + body: 'lorem ipsum $0 dolor sit amet' + command: 'test-command-name' diff --git a/spec/snippet-loading-spec.js b/spec/snippet-loading-spec.js index 05544e94..c04d5358 100644 --- a/spec/snippet-loading-spec.js +++ b/spec/snippet-loading-spec.js @@ -81,6 +81,24 @@ describe("Snippet Loading", () => { }); }); + it("registers a command if a package snippet defines one", () => { + waitsForPromise(() => { + return atom.packages.activatePackage("snippets").then( + ({mainModule}) => { + return new Promise((resolve) => { + mainModule.onDidLoadSnippets(resolve); + }); + } + ); + }); + + runs(() => { + expect( + 'package-with-snippets:test-command-name' in atom.commands.registeredCommands + ).toBe(true); + }); + }); + it("logs a warning if package snippets files cannot be parsed", () => { activateSnippetsPackage(); @@ -93,10 +111,10 @@ describe("Snippet Loading", () => { describe("::loadPackageSnippets(callback)", () => { beforeEach(() => { // simulate a list of packages where the javascript core package is returned at the end - atom.packages.getLoadedPackages.andReturn([ + atom.packages.getLoadedPackages.andReturn([ atom.packages.loadPackage(path.join(__dirname, 'fixtures', 'package-with-snippets')), atom.packages.loadPackage('language-javascript') - ]) + ]); }); it("allows other packages to override core packages' snippets", () => { @@ -126,7 +144,7 @@ describe("Snippet Loading", () => { describe("when ~/.atom/snippets.json exists", () => { beforeEach(() => { - fs.mkdirSync(configDirPath, { recursive: true }); + fs.mkdirSync(configDirPath, {recursive: true}); fs.writeFileSync(path.join(configDirPath, 'snippets.json'), `\ { ".foo": { @@ -155,7 +173,7 @@ describe("Snippet Loading", () => { describe("when that file changes", () => { it("reloads the snippets", () => { - fs.mkdirSync(configDirPath, { recursive: true }); + fs.mkdirSync(configDirPath, {recursive: true}); fs.writeFileSync(path.join(configDirPath, 'snippets.json'), `\ { ".foo": { @@ -174,7 +192,7 @@ describe("Snippet Loading", () => { }); runs(() => { - fs.mkdirSync(configDirPath, { recursive: true }); + fs.mkdirSync(configDirPath, {recursive: true}); fs.writeFileSync(path.join(configDirPath, 'snippets.json'), ""); }); @@ -185,7 +203,7 @@ describe("Snippet Loading", () => { describe("when ~/.atom/snippets.cson exists", () => { beforeEach(() => { - fs.mkdirSync(configDirPath, { recursive: true }); + fs.mkdirSync(configDirPath, {recursive: true}); fs.writeFileSync(path.join(configDirPath, 'snippets.cson'), `\ ".foo": "foo snippet": @@ -210,7 +228,7 @@ describe("Snippet Loading", () => { describe("when that file changes", () => { it("reloads the snippets", () => { - fs.mkdirSync(configDirPath, { recursive: true }); + fs.mkdirSync(configDirPath, {recursive: true}); fs.writeFileSync(path.join(configDirPath, 'snippets.cson'), `\ ".foo": "foo snippet": @@ -225,7 +243,7 @@ describe("Snippet Loading", () => { }); runs(() => { - fs.mkdirSync(configDirPath, { recursive: true }); + fs.mkdirSync(configDirPath, {recursive: true}); fs.writeFileSync(path.join(configDirPath, 'snippets.cson'), ""); }); diff --git a/spec/snippets-spec.js b/spec/snippets-spec.js index ba9f8d32..d72f9af8 100644 --- a/spec/snippets-spec.js +++ b/spec/snippets-spec.js @@ -16,11 +16,13 @@ describe("Snippets extension", () => { }; beforeEach(() => { + if (atom.notifications != null) { spyOn(atom.notifications, 'addError'); } spyOn(Snippets, 'loadAll'); spyOn(Snippets, 'getUserSnippetsPath').andReturn(''); waitsForPromise(() => atom.workspace.open('sample.js')); waitsForPromise(() => atom.packages.activatePackage('language-javascript')); + waitsForPromise(() => atom.packages.activatePackage('language-html')); waitsForPromise(() => atom.packages.activatePackage('snippets')); runs(() => { @@ -1183,13 +1185,13 @@ foo\ }); }); - describe("when atom://.atom/snippets is opened", () => { - it("opens ~/.atom/snippets.cson", () => { + describe("when atom://.pulsar/snippets is opened", () => { + it("opens ~/.pulsar/snippets.cson", () => { jasmine.unspy(Snippets, 'getUserSnippetsPath'); atom.workspace.destroyActivePaneItem(); const configDirPath = temp.mkdirSync('atom-config-dir-'); spyOn(atom, 'getConfigDirPath').andReturn(configDirPath); - atom.workspace.open('atom://.atom/snippets'); + atom.workspace.open('atom://.pulsar/snippets'); waitsFor(() => atom.workspace.getActiveTextEditor() != null); @@ -1209,10 +1211,128 @@ foo\ }); }); + describe("when a user snippet maps to a command", () => { + beforeEach(() => { + editor.setText(''); + Snippets.add( + __filename, { + ".source.js": { + "some command snippet": { + body: "lorem ipsum dolor $1 sit ${2:amet}$0", + command: "some-command-snippet" + }, + "another command snippet with a prefix": { + prefix: 'prfx', + command: 'command-with-prefix', + body: 'this had $0 a prefix' + }, + "another snippet with neither command nor prefix": { + body: 'useless' + }, + "another snippet with a malformed command name": { + command: 'i flout the RULES', + body: 'inconsiderate' + } + }, + ".source.python": { + "some python command snippet": { + body: "consecuetur $0 adipiscing", + command: "some-python-command-snippet" + } + }, + ".text.html": { + "wrap in tag": { + "command": "wrap-in-html-tag", + "body": "<${1:div}>$0" + } + } + }, + 'snippets' + ); + }); + + afterEach(() => { + Snippets.clearSnippetsForPath(__filename); + }); + + it("registers the command", () => { + expect( + "snippets:some-command-snippet" in atom.commands.registeredCommands + ).toBe(true); + }); + + it("complains about a malformed command name", () => { + const expectedMessage = `Cannot register \`i flout the RULES\` for snippet “another snippet with a malformed command name” because the command name isn’t valid. Command names must be all lowercase and use hyphens between words instead of spaces.`; + expect(atom.notifications.addError).toHaveBeenCalledWith( + `Snippets error`, + { + description: expectedMessage, + dismissable: true + } + ); + }); + + describe("and the command is invoked", () => { + beforeEach(() => { + editor.setText(''); + }); + + it("expands the snippet when the scope matches", () => { + atom.commands.dispatch(editor.element, 'snippets:some-command-snippet'); + let cursor = editor.getLastCursor(); + let pos = cursor.getBufferPosition(); + expect(cursor.getBufferPosition()).toEqual([0, 18]); + + expect(editor.getText()).toBe('lorem ipsum dolor sit amet'); + editor.insertText("virus"); + expect(editor.getText()).toBe('lorem ipsum dolor virus sit amet'); + + simulateTabKeyEvent(); + expect(editor.getSelectedBufferRange()).toEqual([[0, 28], [0, 32]]); + }); + + it("expands the snippet even when a prefix is defined", () => { + atom.commands.dispatch(editor.element, 'snippets:command-with-prefix'); + let cursor = editor.getLastCursor(); + let pos = cursor.getBufferPosition(); + expect(pos.toArray().join(',')).toBe('0,9'); + expect(editor.getText()).toBe('this had a prefix'); + }); + + it("does nothing when the scope does not match", () => { + atom.commands.dispatch(editor.element, 'snippets:some-python-command-snippet'); + expect(editor.getText()).toBe(""); + }); + + }); + + describe("and the command is invoked in an HTML document", () => { + beforeEach(() => { + atom.grammars.assignLanguageMode(editor, 'text.html.basic'); + editor.setText(''); + }); + + it("expands tab stops correctly", () => { + atom.commands.dispatch(editor.element, 'snippets:wrap-in-html-tag'); + let cursor = editor.getLastCursor(); + expect(cursor.getBufferPosition()).toEqual([0, 4]); + expect(editor.getSelectedText()).toEqual('div'); + + editor.insertText("aside class=\"wat\""); + + expect(editor.getText()).toBe(""); + + simulateTabKeyEvent(); + expect(cursor.getBufferPosition()).toEqual([0, 19]); + }); + }); + }); + describe("when the 'snippets:available' command is triggered", () => { let availableSnippetsView = null; beforeEach(() => { + atom.grammars.assignLanguageMode(editor, 'source.js'); Snippets.add(__filename, { ".source.js": { "test": { @@ -1225,8 +1345,7 @@ foo\ body: "$1: ${2:To pass this challenge}" } } - } - ); + }); delete Snippets.availableSnippetsView;