diff --git a/main.ts b/main.ts
index 2fe7693..f544fd4 100644
--- a/main.ts
+++ b/main.ts
@@ -1,26 +1,19 @@
-import { App, Editor, Plugin, PluginSettingTab, Setting } from "obsidian";
-
-interface AutoCloseTagsSettings {
- excludedTags: string;
- cursorPosition: "between" | "after";
- ignoreInCodeBlocks: boolean;
- ignoreInlineCode: boolean;
-}
-
-const DEFAULT_SETTINGS: AutoCloseTagsSettings = {
- excludedTags: "",
- cursorPosition: "between",
- ignoreInCodeBlocks: false,
- ignoreInlineCode: true,
-};
+import { Editor, Plugin } from "obsidian";
+import { AutoCloseTagsSettings } from "./src/types";
+import { SettingsManager } from "./src/settings";
+import { TagProcessor } from "./src/tag-processor";
+import { AutoCloseTagsSettingTab } from "./src/settings-tab";
export default class AutoCloseTags extends Plugin {
private allowAutoClose: boolean = false;
- settings: AutoCloseTagsSettings;
- private lastProcessedPosition: { line: number; ch: number } | null = null;
+ private settingsManager: SettingsManager;
+ private tagProcessor: TagProcessor;
async onload() {
- await this.loadSettings();
+ this.settingsManager = new SettingsManager(this);
+ await this.settingsManager.loadSettings();
+
+ this.tagProcessor = new TagProcessor(this.settingsManager.settings);
this.registerDomEvent(document, "paste", () => {
this.allowAutoClose = true;
@@ -54,12 +47,12 @@ export default class AutoCloseTags extends Plugin {
handleTyping(editor: Editor) {
const cursor = editor.getCursor();
- const line = editor.getLine(cursor.line);
+ const lastPos = this.tagProcessor.getLastProcessedPosition();
if (
- this.lastProcessedPosition &&
- this.lastProcessedPosition.line === cursor.line &&
- this.lastProcessedPosition.ch === cursor.ch
+ lastPos &&
+ lastPos.line === cursor.line &&
+ lastPos.ch === cursor.ch
) {
return;
}
@@ -67,305 +60,32 @@ export default class AutoCloseTags extends Plugin {
if (!this.allowAutoClose) return;
this.allowAutoClose = false;
- if (cursor.ch === 0 || line[cursor.ch - 1] !== ">") {
- return;
- }
-
- const beforeCursor = line.slice(0, cursor.ch);
-
- const tagMatch = beforeCursor.match(/<([a-zA-Z][\w\-]*)\s*([^>]*)>$/);
-
- if (
- !tagMatch ||
- beforeCursor.endsWith("/>") ||
- beforeCursor.endsWith("")
- ) {
- return;
- }
-
- const tag = tagMatch[1];
- const fullTag = tagMatch[0];
-
- if (this.isSelfClosing(fullTag)) return;
-
- const excluded = this.settings.excludedTags
- .split(",")
- .map((t) => t.trim().toLowerCase())
- .filter((t) => t.length > 0);
-
- if (excluded.includes(tag.toLowerCase())) return;
-
- if (
- (this.settings.ignoreInCodeBlocks &&
- this.isInCodeBlock(editor, cursor.line)) ||
- (this.settings.ignoreInlineCode &&
- this.isInInlineCode(line, cursor.ch))
- ) {
- return;
- }
-
- const closingTag = `${tag}>`;
- const insertPos = { line: cursor.line, ch: cursor.ch };
-
- this.lastProcessedPosition = { line: cursor.line, ch: cursor.ch };
-
- editor.replaceRange(closingTag, insertPos);
-
- if (this.settings.cursorPosition === "between") {
- editor.setCursor({ line: cursor.line, ch: cursor.ch });
- } else {
- editor.setCursor({
- line: cursor.line,
- ch: cursor.ch + closingTag.length,
- });
- }
-
- setTimeout(() => {
- this.lastProcessedPosition = null;
- }, 100);
- }
-
- hasMatchingClosingTag(
- editor: Editor,
- tagName: string,
- fromLine: number,
- fromCh: number
- ): boolean {
- const content = editor.getValue();
- const lines = content.split("\n");
-
- let openCount = 1;
-
- for (let i = fromLine; i < lines.length; i++) {
- const line = lines[i];
- const searchFrom = i === fromLine ? fromCh : 0;
- const searchLine = line.slice(searchFrom);
-
- const openMatches = [
- ...searchLine.matchAll(
- new RegExp(`<${tagName}(?:\\s[^>]*)?>`, "gi")
- ),
- ];
- openCount += openMatches.length;
-
- const closeMatches = [
- ...searchLine.matchAll(new RegExp(`${tagName}>`, "gi")),
- ];
- openCount -= closeMatches.length;
-
- if (openCount <= 0) {
- return true;
- }
- }
-
- return false;
- }
-
- insertClosingTag(editor: Editor) {
- const content = editor.getValue();
- const lines = content.split("\n");
-
- const excluded = this.settings.excludedTags
- .split(",")
- .map((t) => t.trim().toLowerCase())
- .filter((t) => t.length > 0);
-
- const openTags: { tag: string; line: number }[] = [];
- const closeTags: string[] = [];
-
- let insideCodeBlock = false;
-
- for (let i = 0; i < lines.length; i++) {
- const line = lines[i];
-
- if (line.trim().startsWith("```")) {
- insideCodeBlock = !insideCodeBlock;
- continue;
- }
-
- if (this.settings.ignoreInCodeBlocks && insideCodeBlock) continue;
-
- const openMatches = [
- ...line.matchAll(/<([a-zA-Z][\w\-]*)\s*([^>]*?)>/g),
- ];
- for (const match of openMatches) {
- const raw = match[0];
- const tag = match[1].toLowerCase();
- const matchIndex = match.index ?? 0;
-
- if (excluded.includes(tag)) continue;
- if (this.isSelfClosing(raw)) continue;
- if (
- this.settings.ignoreInlineCode &&
- this.isInInlineCode(line, matchIndex)
- )
- continue;
-
- openTags.push({ tag, line: i });
- }
-
- const closeMatches = [...line.matchAll(/<\/([a-zA-Z][\w\-]*)>/g)];
- for (const match of closeMatches) {
- const matchIndex = match.index ?? 0;
- if (
- this.settings.ignoreInlineCode &&
- this.isInInlineCode(line, matchIndex)
- )
- continue;
- closeTags.push(match[1].toLowerCase());
- }
- }
-
- for (const closeTag of closeTags) {
- const openIndex = openTags.findLastIndex(
- (openTag) => openTag.tag === closeTag
- );
- if (openIndex !== -1) {
- openTags.splice(openIndex, 1);
- }
- }
-
- if (openTags.length === 0) {
- return;
- }
-
- const tagToClose = openTags[openTags.length - 1].tag;
- const closingTag = `${tagToClose}>`;
- const cursor = editor.getCursor();
-
- editor.replaceRange(closingTag, cursor);
-
- if (this.settings.cursorPosition === "after") {
- editor.setCursor({
- line: cursor.line,
- ch: cursor.ch + closingTag.length,
- });
- } else {
- editor.setCursor(cursor);
- }
- }
-
- isSelfClosing(tag: string): boolean {
- if (/\/\s*>$/.test(tag)) return true;
-
- const voidElements = [
- "area",
- "base",
- "br",
- "col",
- "embed",
- "hr",
- "img",
- "input",
- "link",
- "meta",
- "source",
- "track",
- "wbr",
- ];
-
- const tagName = tag.match(/<([a-zA-Z][\w\-]*)/)?.[1]?.toLowerCase();
- return tagName ? voidElements.includes(tagName) : false;
- }
-
- isInCodeBlock(editor: Editor, line: number): boolean {
- let inCodeBlock = false;
- for (let i = 0; i <= line; i++) {
- const currentLine = editor.getLine(i);
- if (currentLine && currentLine.trim().startsWith("```")) {
- inCodeBlock = !inCodeBlock;
- }
- }
- return inCodeBlock;
- }
-
- isInInlineCode(line: string, index: number): boolean {
- const before = line.slice(0, index);
- const backticks = (before.match(/`/g) || []).length;
- return backticks % 2 === 1;
- }
-
- async loadSettings() {
- this.settings = Object.assign(
- {},
- DEFAULT_SETTINGS,
- await this.loadData()
+ this.tagProcessor.autoCloseTag(
+ editor,
+ this.settingsManager.getExcludedTags()
);
}
- async saveSettings() {
- await this.saveData(this.settings);
- }
-}
-
-/* ---------------------------- Settings Tab ---------------------------- */
-class AutoCloseTagsSettingTab extends PluginSettingTab {
- plugin: AutoCloseTags;
-
- constructor(app: App, plugin: AutoCloseTags) {
- super(app, plugin);
- this.plugin = plugin;
- }
-
- display(): void {
- const { containerEl } = this;
- containerEl.empty();
-
- new Setting(containerEl)
- .setName("Excluded tags")
- .setDesc(
- "Comma-separated list of tags that should not be auto-closed (e.g., div, span, i)."
- )
- .addText((text) =>
- text
- .setPlaceholder("e.g., div, span, i")
- .setValue(this.plugin.settings.excludedTags)
- .onChange(async (value) => {
- this.plugin.settings.excludedTags = value;
- await this.plugin.saveSettings();
- })
- );
-
- new Setting(containerEl)
- .setName("Cursor position after auto-close")
- .setDesc("Where to place the cursor after auto-closing a tag.")
- .addDropdown((dropdown) =>
- dropdown
- .addOption("between", "Between tags")
- .addOption("after", "After closing tag")
- .setValue(this.plugin.settings.cursorPosition)
- .onChange(async (value: "between" | "after") => {
- this.plugin.settings.cursorPosition = value;
- await this.plugin.saveSettings();
- })
- );
-
- new Setting(containerEl)
- .setName("Ignore fenced code blocks")
- .setDesc(
- "Avoid auto-closing tags inside Markdown code blocks (``` blocks)."
- )
- .addToggle((toggle) =>
- toggle
- .setValue(this.plugin.settings.ignoreInCodeBlocks)
- .onChange(async (value) => {
- this.plugin.settings.ignoreInCodeBlocks = value;
- await this.plugin.saveSettings();
- })
- );
-
- new Setting(containerEl)
- .setName("Ignore inline code")
- .setDesc(
- "Avoid auto-closing tags inside inline code spans (e.g., `
`)."
- )
- .addToggle((toggle) =>
- toggle
- .setValue(this.plugin.settings.ignoreInlineCode)
- .onChange(async (value) => {
- this.plugin.settings.ignoreInlineCode = value;
- await this.plugin.saveSettings();
- })
- );
+ insertClosingTag(editor: Editor) {
+ this.tagProcessor.insertClosingTag(
+ editor,
+ this.settingsManager.getExcludedTags()
+ );
+ }
+
+ getSettings(): AutoCloseTagsSettings {
+ return this.settingsManager.settings;
+ }
+
+ updateSetting
(
+ key: K,
+ value: AutoCloseTagsSettings[K]
+ ): void {
+ this.settingsManager.settings[key] = value;
+ this.tagProcessor.updateSettings(this.settingsManager.settings);
+ }
+
+ async saveSettings(): Promise {
+ await this.settingsManager.saveSettings();
}
}
diff --git a/package-lock.json b/package-lock.json
index bb3f2dc..729a461 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
- "name": "obsidian-sample-plugin",
- "version": "1.0.0",
+ "name": "auto-close-tags",
+ "version": "1.1.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
- "name": "obsidian-sample-plugin",
- "version": "1.0.0",
+ "name": "auto-close-tags",
+ "version": "1.1.2",
"license": "MIT",
"devDependencies": {
"@types/node": "^16.11.6",
@@ -24,16 +24,18 @@
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.2.tgz",
"integrity": "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"@marijn/find-cluster-break": "^1.0.0"
}
},
"node_modules/@codemirror/view": {
- "version": "6.37.2",
- "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.37.2.tgz",
- "integrity": "sha512-XD3LdgQpxQs5jhOOZ2HRVT+Rj59O4Suc7g2ULvZ+Yi8eCkickrkZ5JFuoDhs2ST1mNI5zSsNYgR3NGa4OUrbnw==",
+ "version": "6.38.1",
+ "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.38.1.tgz",
+ "integrity": "sha512-RmTOkE7hRU3OVREqFVITWHz6ocgBjv08GoePscAakgVQfciA3SGCEk7mb9IzwW61cKKmlTpHXG6DUE5Ubx+MGQ==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"@codemirror/state": "^6.5.0",
@@ -50,6 +52,7 @@
"arm"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"android"
@@ -66,6 +69,7 @@
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"android"
@@ -82,6 +86,7 @@
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"android"
@@ -98,6 +103,7 @@
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"darwin"
@@ -114,6 +120,7 @@
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"darwin"
@@ -130,6 +137,7 @@
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"freebsd"
@@ -146,6 +154,7 @@
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"freebsd"
@@ -162,6 +171,7 @@
"arm"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -178,6 +188,7 @@
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -194,6 +205,7 @@
"ia32"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -210,6 +222,7 @@
"loong64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -226,6 +239,7 @@
"mips64el"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -242,6 +256,7 @@
"ppc64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -258,6 +273,7 @@
"riscv64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -274,6 +290,7 @@
"s390x"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -290,6 +307,7 @@
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -306,6 +324,7 @@
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"netbsd"
@@ -322,6 +341,7 @@
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"openbsd"
@@ -338,6 +358,7 @@
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"sunos"
@@ -354,6 +375,7 @@
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"win32"
@@ -370,6 +392,7 @@
"ia32"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"win32"
@@ -386,6 +409,7 @@
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"win32"
@@ -399,6 +423,7 @@
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz",
"integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"eslint-visitor-keys": "^3.4.3"
@@ -418,6 +443,7 @@
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
"integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
@@ -428,6 +454,7 @@
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
"integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"ajv": "^6.12.4",
@@ -452,6 +479,7 @@
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz",
"integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -463,6 +491,7 @@
"integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==",
"deprecated": "Use @eslint/config-array instead",
"dev": true,
+ "license": "Apache-2.0",
"peer": true,
"dependencies": {
"@humanwhocodes/object-schema": "^2.0.3",
@@ -478,6 +507,7 @@
"resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
"integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
"dev": true,
+ "license": "Apache-2.0",
"peer": true,
"engines": {
"node": ">=12.22"
@@ -493,6 +523,7 @@
"integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
"deprecated": "Use @eslint/object-schema instead",
"dev": true,
+ "license": "BSD-3-Clause",
"peer": true
},
"node_modules/@marijn/find-cluster-break": {
@@ -500,6 +531,7 @@
"resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz",
"integrity": "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/@nodelib/fs.scandir": {
@@ -507,6 +539,7 @@
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@nodelib/fs.stat": "2.0.5",
"run-parallel": "^1.1.9"
@@ -520,6 +553,7 @@
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 8"
}
@@ -529,6 +563,7 @@
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@nodelib/fs.scandir": "2.1.5",
"fastq": "^1.6.0"
@@ -542,6 +577,7 @@
"resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.8.tgz",
"integrity": "sha512-VjFgDF/eB+Aklcy15TtOTLQeMjTo07k7KAjql8OK5Dirr7a6sJY4T1uVBDuTVG9VEmn1uUsohOpYnVfgC6/jyw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/tern": "*"
}
@@ -550,25 +586,29 @@
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/node": {
"version": "16.18.126",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.126.tgz",
"integrity": "sha512-OTcgaiwfGFBKacvfwuHzzn1KLxH/er8mluiy8/uM3sGXHaRe73RrSIj01jow9t4kJEW633Ov+cOexXeiApTyAw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/tern": {
"version": "0.23.9",
"resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.9.tgz",
"integrity": "sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/estree": "*"
}
@@ -578,6 +618,7 @@
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.29.0.tgz",
"integrity": "sha512-kgTsISt9pM53yRFQmLZ4npj99yGl3x3Pl7z4eA66OuTzAGC4bQB5H5fuLwPnqTKU3yyrrg4MIhjF17UYnL4c0w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@typescript-eslint/scope-manager": "5.29.0",
"@typescript-eslint/type-utils": "5.29.0",
@@ -611,6 +652,7 @@
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.29.0.tgz",
"integrity": "sha512-ruKWTv+x0OOxbzIw9nW5oWlUopvP/IQDjB5ZqmTglLIoDTctLlAJpAQFpNPJP/ZI7hTT9sARBosEfaKbcFuECw==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"@typescript-eslint/scope-manager": "5.29.0",
"@typescript-eslint/types": "5.29.0",
@@ -638,6 +680,7 @@
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.29.0.tgz",
"integrity": "sha512-etbXUT0FygFi2ihcxDZjz21LtC+Eps9V2xVx09zFoN44RRHPrkMflidGMI+2dUs821zR1tDS6Oc9IXxIjOUZwA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@typescript-eslint/types": "5.29.0",
"@typescript-eslint/visitor-keys": "5.29.0"
@@ -655,6 +698,7 @@
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.29.0.tgz",
"integrity": "sha512-JK6bAaaiJozbox3K220VRfCzLa9n0ib/J+FHIwnaV3Enw/TO267qe0pM1b1QrrEuy6xun374XEAsRlA86JJnyg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@typescript-eslint/utils": "5.29.0",
"debug": "^4.3.4",
@@ -681,6 +725,7 @@
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.29.0.tgz",
"integrity": "sha512-X99VbqvAXOMdVyfFmksMy3u8p8yoRGITgU1joBJPzeYa0rhdf5ok9S56/itRoUSh99fiDoMtarSIJXo7H/SnOg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
@@ -694,6 +739,7 @@
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.29.0.tgz",
"integrity": "sha512-mQvSUJ/JjGBdvo+1LwC+GY2XmSYjK1nAaVw2emp/E61wEVYEyibRHCqm1I1vEKbXCpUKuW4G7u9ZCaZhJbLoNQ==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"@typescript-eslint/types": "5.29.0",
"@typescript-eslint/visitor-keys": "5.29.0",
@@ -721,6 +767,7 @@
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.29.0.tgz",
"integrity": "sha512-3Eos6uP1nyLOBayc/VUdKZikV90HahXE5Dx9L5YlSd/7ylQPXhLk1BYb29SDgnBnTp+jmSZUU0QxUiyHgW4p7A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/json-schema": "^7.0.9",
"@typescript-eslint/scope-manager": "5.29.0",
@@ -745,6 +792,7 @@
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.29.0.tgz",
"integrity": "sha512-Hpb/mCWsjILvikMQoZIE3voc9wtQcS0A9FUw3h8bhr9UxBdtI/tw1ZDZUOXHXLOVMedKCH5NxyzATwnU78bWCQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@typescript-eslint/types": "5.29.0",
"eslint-visitor-keys": "^3.3.0"
@@ -762,6 +810,7 @@
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
"integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
"dev": true,
+ "license": "ISC",
"peer": true
},
"node_modules/acorn": {
@@ -769,6 +818,7 @@
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
+ "license": "MIT",
"peer": true,
"bin": {
"acorn": "bin/acorn"
@@ -782,6 +832,7 @@
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
"dev": true,
+ "license": "MIT",
"peer": true,
"peerDependencies": {
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
@@ -792,6 +843,7 @@
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
@@ -809,6 +861,7 @@
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=8"
@@ -819,6 +872,7 @@
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"color-convert": "^2.0.1"
@@ -835,6 +889,7 @@
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true,
+ "license": "Python-2.0",
"peer": true
},
"node_modules/array-union": {
@@ -842,6 +897,7 @@
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -851,6 +907,7 @@
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/brace-expansion": {
@@ -858,6 +915,7 @@
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"balanced-match": "^1.0.0",
@@ -869,6 +927,7 @@
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"fill-range": "^7.1.1"
},
@@ -881,6 +940,7 @@
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz",
"integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
},
@@ -893,6 +953,7 @@
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=6"
@@ -903,6 +964,7 @@
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"ansi-styles": "^4.1.0",
@@ -920,6 +982,7 @@
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"color-name": "~1.1.4"
@@ -933,6 +996,7 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/concat-map": {
@@ -940,6 +1004,7 @@
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/crelt": {
@@ -947,6 +1012,7 @@
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
"integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/cross-spawn": {
@@ -954,6 +1020,7 @@
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"path-key": "^3.1.0",
@@ -969,6 +1036,7 @@
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
"integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"ms": "^2.1.3"
},
@@ -986,6 +1054,7 @@
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/dir-glob": {
@@ -993,6 +1062,7 @@
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
"integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"path-type": "^4.0.0"
},
@@ -1005,6 +1075,7 @@
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
"integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
"dev": true,
+ "license": "Apache-2.0",
"peer": true,
"dependencies": {
"esutils": "^2.0.2"
@@ -1019,6 +1090,7 @@
"integrity": "sha512-9n3AsBRe6sIyOc6kmoXg2ypCLgf3eZSraWFRpnkto+svt8cZNuKTkb1bhQcitBcvIqjNiK7K0J3KPmwGSfkA8g==",
"dev": true,
"hasInstallScript": true,
+ "license": "MIT",
"bin": {
"esbuild": "bin/esbuild"
},
@@ -1055,6 +1127,7 @@
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=10"
@@ -1069,6 +1142,7 @@
"integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
@@ -1125,6 +1199,7 @@
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"esrecurse": "^4.3.0",
"estraverse": "^4.1.1"
@@ -1138,6 +1213,7 @@
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
"integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"eslint-visitor-keys": "^2.0.0"
},
@@ -1156,6 +1232,7 @@
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
"dev": true,
+ "license": "Apache-2.0",
"engines": {
"node": ">=10"
}
@@ -1165,6 +1242,7 @@
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
"dev": true,
+ "license": "Apache-2.0",
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
@@ -1177,6 +1255,7 @@
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
"integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
"dev": true,
+ "license": "BSD-2-Clause",
"peer": true,
"dependencies": {
"esrecurse": "^4.3.0",
@@ -1194,6 +1273,7 @@
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"dev": true,
+ "license": "BSD-2-Clause",
"peer": true,
"engines": {
"node": ">=4.0"
@@ -1204,6 +1284,7 @@
"resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
"integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
"dev": true,
+ "license": "BSD-2-Clause",
"peer": true,
"dependencies": {
"acorn": "^8.9.0",
@@ -1222,6 +1303,7 @@
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
"integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
"dev": true,
+ "license": "BSD-3-Clause",
"peer": true,
"dependencies": {
"estraverse": "^5.1.0"
@@ -1235,6 +1317,7 @@
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"dev": true,
+ "license": "BSD-2-Clause",
"peer": true,
"engines": {
"node": ">=4.0"
@@ -1245,6 +1328,7 @@
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"estraverse": "^5.2.0"
},
@@ -1257,6 +1341,7 @@
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"dev": true,
+ "license": "BSD-2-Clause",
"engines": {
"node": ">=4.0"
}
@@ -1266,6 +1351,7 @@
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
"dev": true,
+ "license": "BSD-2-Clause",
"engines": {
"node": ">=4.0"
}
@@ -1275,6 +1361,7 @@
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": true,
+ "license": "BSD-2-Clause",
"peer": true,
"engines": {
"node": ">=0.10.0"
@@ -1285,6 +1372,7 @@
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/fast-glob": {
@@ -1292,6 +1380,7 @@
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
"integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@nodelib/fs.stat": "^2.0.2",
"@nodelib/fs.walk": "^1.2.3",
@@ -1308,6 +1397,7 @@
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"is-glob": "^4.0.1"
},
@@ -1320,6 +1410,7 @@
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/fast-levenshtein": {
@@ -1327,6 +1418,7 @@
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/fastq": {
@@ -1334,6 +1426,7 @@
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
"integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"reusify": "^1.0.4"
}
@@ -1343,6 +1436,7 @@
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
"integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"flat-cache": "^3.0.4"
@@ -1356,6 +1450,7 @@
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"to-regex-range": "^5.0.1"
},
@@ -1368,6 +1463,7 @@
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
"integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"locate-path": "^6.0.0",
@@ -1385,6 +1481,7 @@
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
"integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"flatted": "^3.2.9",
@@ -1400,6 +1497,7 @@
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
"integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
"dev": true,
+ "license": "ISC",
"peer": true
},
"node_modules/fs.realpath": {
@@ -1407,13 +1505,15 @@
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
"dev": true,
+ "license": "ISC",
"peer": true
},
"node_modules/functional-red-black-tree": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
"integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/glob": {
"version": "7.2.3",
@@ -1421,6 +1521,7 @@
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"deprecated": "Glob versions prior to v9 are no longer supported",
"dev": true,
+ "license": "ISC",
"peer": true,
"dependencies": {
"fs.realpath": "^1.0.0",
@@ -1442,6 +1543,7 @@
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
"dev": true,
+ "license": "ISC",
"peer": true,
"dependencies": {
"is-glob": "^4.0.3"
@@ -1455,6 +1557,7 @@
"resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
"integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"type-fest": "^0.20.2"
@@ -1471,6 +1574,7 @@
"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
"integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"array-union": "^2.1.0",
"dir-glob": "^3.0.1",
@@ -1491,6 +1595,7 @@
"resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
"integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/has-flag": {
@@ -1498,6 +1603,7 @@
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=8"
@@ -1508,6 +1614,7 @@
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
"integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 4"
}
@@ -1517,6 +1624,7 @@
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
"integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"parent-module": "^1.0.0",
@@ -1534,6 +1642,7 @@
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
"integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=0.8.19"
@@ -1545,6 +1654,7 @@
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
"dev": true,
+ "license": "ISC",
"peer": true,
"dependencies": {
"once": "^1.3.0",
@@ -1556,6 +1666,7 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true,
+ "license": "ISC",
"peer": true
},
"node_modules/is-extglob": {
@@ -1563,6 +1674,7 @@
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -1572,6 +1684,7 @@
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"is-extglob": "^2.1.1"
},
@@ -1584,6 +1697,7 @@
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.12.0"
}
@@ -1593,6 +1707,7 @@
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
"integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=8"
@@ -1603,6 +1718,7 @@
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"dev": true,
+ "license": "ISC",
"peer": true
},
"node_modules/js-yaml": {
@@ -1610,6 +1726,7 @@
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"argparse": "^2.0.1"
@@ -1623,6 +1740,7 @@
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/json-schema-traverse": {
@@ -1630,6 +1748,7 @@
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/json-stable-stringify-without-jsonify": {
@@ -1637,6 +1756,7 @@
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/keyv": {
@@ -1644,6 +1764,7 @@
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
"integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"json-buffer": "3.0.1"
@@ -1654,6 +1775,7 @@
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
"integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"prelude-ls": "^1.2.1",
@@ -1668,6 +1790,7 @@
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"p-locate": "^5.0.0"
@@ -1684,6 +1807,7 @@
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/merge2": {
@@ -1691,6 +1815,7 @@
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 8"
}
@@ -1700,6 +1825,7 @@
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"braces": "^3.0.3",
"picomatch": "^2.3.1"
@@ -1713,6 +1839,7 @@
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
+ "license": "ISC",
"peer": true,
"dependencies": {
"brace-expansion": "^1.1.7"
@@ -1726,6 +1853,7 @@
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": "*"
}
@@ -1734,13 +1862,15 @@
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/obsidian": {
@@ -1748,6 +1878,7 @@
"resolved": "https://registry.npmjs.org/obsidian/-/obsidian-1.8.7.tgz",
"integrity": "sha512-h4bWwNFAGRXlMlMAzdEiIM2ppTGlrh7uGOJS6w4gClrsjc+ei/3YAtU2VdFUlCiPuTHpY4aBpFJJW75S1Tl/JA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/codemirror": "5.60.8",
"moment": "2.29.4"
@@ -1762,6 +1893,7 @@
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dev": true,
+ "license": "ISC",
"peer": true,
"dependencies": {
"wrappy": "1"
@@ -1772,6 +1904,7 @@
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
"integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"deep-is": "^0.1.3",
@@ -1790,6 +1923,7 @@
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"yocto-queue": "^0.1.0"
@@ -1806,6 +1940,7 @@
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"p-limit": "^3.0.2"
@@ -1822,6 +1957,7 @@
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"callsites": "^3.0.0"
@@ -1835,6 +1971,7 @@
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=8"
@@ -1845,6 +1982,7 @@
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=0.10.0"
@@ -1855,6 +1993,7 @@
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=8"
@@ -1865,6 +2004,7 @@
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -1874,6 +2014,7 @@
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8.6"
},
@@ -1886,6 +2027,7 @@
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">= 0.8.0"
@@ -1896,6 +2038,7 @@
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=6"
@@ -1919,13 +2062,15 @@
"type": "consulting",
"url": "https://feross.org/support"
}
- ]
+ ],
+ "license": "MIT"
},
"node_modules/regexpp": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
"integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
},
@@ -1938,6 +2083,7 @@
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=4"
@@ -1948,6 +2094,7 @@
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
"integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
"dev": true,
+ "license": "MIT",
"engines": {
"iojs": ">=1.0.0",
"node": ">=0.10.0"
@@ -1959,6 +2106,7 @@
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"deprecated": "Rimraf versions prior to v4 are no longer supported",
"dev": true,
+ "license": "ISC",
"peer": true,
"dependencies": {
"glob": "^7.1.3"
@@ -1989,6 +2137,7 @@
"url": "https://feross.org/support"
}
],
+ "license": "MIT",
"dependencies": {
"queue-microtask": "^1.2.2"
}
@@ -1998,6 +2147,7 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"dev": true,
+ "license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
@@ -2010,6 +2160,7 @@
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"shebang-regex": "^3.0.0"
@@ -2023,6 +2174,7 @@
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=8"
@@ -2033,6 +2185,7 @@
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -2042,6 +2195,7 @@
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"ansi-regex": "^5.0.1"
@@ -2055,6 +2209,7 @@
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=8"
@@ -2068,6 +2223,7 @@
"resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz",
"integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/supports-color": {
@@ -2075,6 +2231,7 @@
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"has-flag": "^4.0.0"
@@ -2088,6 +2245,7 @@
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/to-regex-range": {
@@ -2095,6 +2253,7 @@
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"is-number": "^7.0.0"
},
@@ -2106,13 +2265,15 @@
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
- "dev": true
+ "dev": true,
+ "license": "0BSD"
},
"node_modules/tsutils": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
"integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"tslib": "^1.8.1"
},
@@ -2127,13 +2288,15 @@
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
- "dev": true
+ "dev": true,
+ "license": "0BSD"
},
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
"integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"prelude-ls": "^1.2.1"
@@ -2147,6 +2310,7 @@
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
"dev": true,
+ "license": "(MIT OR CC0-1.0)",
"peer": true,
"engines": {
"node": ">=10"
@@ -2160,6 +2324,7 @@
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
"integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
"dev": true,
+ "license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -2173,6 +2338,7 @@
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"dev": true,
+ "license": "BSD-2-Clause",
"peer": true,
"dependencies": {
"punycode": "^2.1.0"
@@ -2183,6 +2349,7 @@
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
"integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/which": {
@@ -2190,6 +2357,7 @@
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
+ "license": "ISC",
"peer": true,
"dependencies": {
"isexe": "^2.0.0"
@@ -2206,6 +2374,7 @@
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
"integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=0.10.0"
@@ -2216,6 +2385,7 @@
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true,
+ "license": "ISC",
"peer": true
},
"node_modules/yocto-queue": {
@@ -2223,6 +2393,7 @@
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=10"
diff --git a/src/settings-tab.ts b/src/settings-tab.ts
new file mode 100644
index 0000000..330bb15
--- /dev/null
+++ b/src/settings-tab.ts
@@ -0,0 +1,73 @@
+import { App, PluginSettingTab, Setting } from "obsidian";
+import AutoCloseTags from "../main";
+
+export class AutoCloseTagsSettingTab extends PluginSettingTab {
+ plugin: AutoCloseTags;
+
+ constructor(app: App, plugin: AutoCloseTags) {
+ super(app, plugin);
+ this.plugin = plugin;
+ }
+
+ display(): void {
+ const { containerEl } = this;
+ containerEl.empty();
+
+ new Setting(containerEl)
+ .setName("Excluded tags")
+ .setDesc(
+ "Comma-separated list of tags that should not be auto-closed (e.g., div, span, i)."
+ )
+ .addText((text) =>
+ text
+ .setPlaceholder("e.g., div, span, i")
+ .setValue(this.plugin.getSettings().excludedTags)
+ .onChange(async (value) => {
+ this.plugin.updateSetting("excludedTags", value);
+ await this.plugin.saveSettings();
+ })
+ );
+
+ new Setting(containerEl)
+ .setName("Cursor position after auto-close")
+ .setDesc("Where to place the cursor after auto-closing a tag.")
+ .addDropdown((dropdown) =>
+ dropdown
+ .addOption("between", "Between tags")
+ .addOption("after", "After closing tag")
+ .setValue(this.plugin.getSettings().cursorPosition)
+ .onChange(async (value: "between" | "after") => {
+ this.plugin.updateSetting("cursorPosition", value);
+ await this.plugin.saveSettings();
+ })
+ );
+
+ new Setting(containerEl)
+ .setName("Ignore fenced code blocks")
+ .setDesc(
+ "Avoid auto-closing tags inside Markdown code blocks (``` blocks)."
+ )
+ .addToggle((toggle) =>
+ toggle
+ .setValue(this.plugin.getSettings().ignoreInCodeBlocks)
+ .onChange(async (value) => {
+ this.plugin.updateSetting("ignoreInCodeBlocks", value);
+ await this.plugin.saveSettings();
+ })
+ );
+
+ new Setting(containerEl)
+ .setName("Ignore inline code")
+ .setDesc(
+ "Avoid auto-closing tags inside inline code spans (e.g., ``)."
+ )
+ .addToggle((toggle) =>
+ toggle
+ .setValue(this.plugin.getSettings().ignoreInlineCode)
+ .onChange(async (value) => {
+ this.plugin.updateSetting("ignoreInlineCode", value);
+ await this.plugin.saveSettings();
+ })
+ );
+ }
+}
diff --git a/src/settings.ts b/src/settings.ts
new file mode 100644
index 0000000..b6073b6
--- /dev/null
+++ b/src/settings.ts
@@ -0,0 +1,31 @@
+import { Plugin } from "obsidian";
+import { AutoCloseTagsSettings, DEFAULT_SETTINGS } from "./types";
+
+export class SettingsManager {
+ private plugin: Plugin;
+ public settings: AutoCloseTagsSettings;
+
+ constructor(plugin: Plugin) {
+ this.plugin = plugin;
+ this.settings = { ...DEFAULT_SETTINGS };
+ }
+
+ async loadSettings(): Promise {
+ this.settings = Object.assign(
+ {},
+ DEFAULT_SETTINGS,
+ await this.plugin.loadData()
+ );
+ }
+
+ async saveSettings(): Promise {
+ await this.plugin.saveData(this.settings);
+ }
+
+ getExcludedTags(): string[] {
+ return this.settings.excludedTags
+ .split(",")
+ .map((t) => t.trim().toLowerCase())
+ .filter((t) => t.length > 0);
+ }
+}
diff --git a/src/tag-detector.ts b/src/tag-detector.ts
new file mode 100644
index 0000000..630e76f
--- /dev/null
+++ b/src/tag-detector.ts
@@ -0,0 +1,102 @@
+import { Editor } from "obsidian";
+import { AutoCloseTagsSettings } from "./types";
+
+export class TagDetector {
+ private settings: AutoCloseTagsSettings;
+
+ constructor(settings: AutoCloseTagsSettings) {
+ this.settings = settings;
+ }
+
+ updateSettings(settings: AutoCloseTagsSettings): void {
+ this.settings = settings;
+ }
+
+ isSelfClosing(tag: string): boolean {
+ if (/\/\s*>$/.test(tag)) return true;
+
+ const voidElements = [
+ "area",
+ "base",
+ "br",
+ "col",
+ "embed",
+ "hr",
+ "img",
+ "input",
+ "link",
+ "meta",
+ "source",
+ "track",
+ "wbr",
+ ];
+
+ const tagName = tag.match(/<([a-zA-Z][\w\-]*)/)?.[1]?.toLowerCase();
+ return tagName ? voidElements.includes(tagName) : false;
+ }
+
+ isInCodeBlock(editor: Editor, line: number): boolean {
+ let inCodeBlock = false;
+ for (let i = 0; i <= line; i++) {
+ const currentLine = editor.getLine(i);
+ if (currentLine && currentLine.trim().startsWith("```")) {
+ inCodeBlock = !inCodeBlock;
+ }
+ }
+ return inCodeBlock;
+ }
+
+ isInInlineCode(line: string, index: number): boolean {
+ const before = line.slice(0, index);
+ const backticks = (before.match(/`/g) || []).length;
+ return backticks % 2 === 1;
+ }
+
+ isTagExcluded(tag: string, excludedTags: string[]): boolean {
+ return excludedTags.includes(tag.toLowerCase());
+ }
+
+ shouldIgnorePosition(
+ editor: Editor,
+ line: string,
+ lineNumber: number,
+ position: number
+ ): boolean {
+ if (
+ this.settings.ignoreInCodeBlocks &&
+ this.isInCodeBlock(editor, lineNumber)
+ ) {
+ return true;
+ }
+
+ if (
+ this.settings.ignoreInlineCode &&
+ this.isInInlineCode(line, position)
+ ) {
+ return true;
+ }
+
+ return false;
+ }
+
+ extractTagFromLine(
+ line: string,
+ cursorPosition: number
+ ): { tag: string; fullTag: string } | null {
+ const beforeCursor = line.slice(0, cursorPosition);
+ const tagMatch = beforeCursor.match(/<([a-zA-Z][\w\-]*)\s*([^>]*)>$/);
+
+ if (
+ !tagMatch ||
+ beforeCursor.endsWith("/>") ||
+ beforeCursor.endsWith("")
+ ) {
+ return null;
+ }
+
+ return {
+ tag: tagMatch[1],
+ fullTag: tagMatch[0],
+ };
+ }
+}
diff --git a/src/tag-processor.ts b/src/tag-processor.ts
new file mode 100644
index 0000000..1fff3db
--- /dev/null
+++ b/src/tag-processor.ts
@@ -0,0 +1,201 @@
+import { Editor } from "obsidian";
+import { AutoCloseTagsSettings } from "./types";
+import { TagDetector } from "./tag-detector";
+
+export class TagProcessor {
+ private settings: AutoCloseTagsSettings;
+ private tagDetector: TagDetector;
+ private lastProcessedPosition: { line: number; ch: number } | null = null;
+
+ constructor(settings: AutoCloseTagsSettings) {
+ this.settings = settings;
+ this.tagDetector = new TagDetector(settings);
+ }
+
+ updateSettings(settings: AutoCloseTagsSettings): void {
+ this.settings = settings;
+ this.tagDetector.updateSettings(settings);
+ }
+
+ setLastProcessedPosition(
+ position: { line: number; ch: number } | null
+ ): void {
+ this.lastProcessedPosition = position;
+ }
+
+ getLastProcessedPosition(): { line: number; ch: number } | null {
+ return this.lastProcessedPosition;
+ }
+
+ autoCloseTag(editor: Editor, excludedTags: string[]): boolean {
+ const cursor = editor.getCursor();
+ const line = editor.getLine(cursor.line);
+
+ if (cursor.ch === 0 || line[cursor.ch - 1] !== ">") {
+ return false;
+ }
+
+ const tagInfo = this.tagDetector.extractTagFromLine(line, cursor.ch);
+ if (!tagInfo) {
+ return false;
+ }
+
+ const { tag, fullTag } = tagInfo;
+
+ if (this.tagDetector.isSelfClosing(fullTag)) {
+ return false;
+ }
+
+ if (this.tagDetector.isTagExcluded(tag, excludedTags)) {
+ return false;
+ }
+
+ if (
+ this.tagDetector.shouldIgnorePosition(
+ editor,
+ line,
+ cursor.line,
+ cursor.ch
+ )
+ ) {
+ return false;
+ }
+
+ const closingTag = `${tag}>`;
+ const insertPos = { line: cursor.line, ch: cursor.ch };
+
+ this.lastProcessedPosition = { line: cursor.line, ch: cursor.ch };
+
+ editor.replaceRange(closingTag, insertPos);
+
+ if (this.settings.cursorPosition === "between") {
+ editor.setCursor({ line: cursor.line, ch: cursor.ch });
+ } else {
+ editor.setCursor({
+ line: cursor.line,
+ ch: cursor.ch + closingTag.length,
+ });
+ }
+
+ setTimeout(() => {
+ this.lastProcessedPosition = null;
+ }, 100);
+
+ return true;
+ }
+
+ hasMatchingClosingTag(
+ editor: Editor,
+ tagName: string,
+ fromLine: number,
+ fromCh: number
+ ): boolean {
+ const content = editor.getValue();
+ const lines = content.split("\n");
+
+ let openCount = 1;
+
+ for (let i = fromLine; i < lines.length; i++) {
+ const line = lines[i];
+ const searchFrom = i === fromLine ? fromCh : 0;
+ const searchLine = line.slice(searchFrom);
+
+ const openMatches = [
+ ...searchLine.matchAll(
+ new RegExp(`<${tagName}(?:\\s[^>]*)?>`, "gi")
+ ),
+ ];
+ openCount += openMatches.length;
+
+ const closeMatches = [
+ ...searchLine.matchAll(new RegExp(`${tagName}>`, "gi")),
+ ];
+ openCount -= closeMatches.length;
+
+ if (openCount <= 0) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ insertClosingTag(editor: Editor, excludedTags: string[]): void {
+ const content = editor.getValue();
+ const lines = content.split("\n");
+
+ const openTags: { tag: string; line: number }[] = [];
+ const closeTags: string[] = [];
+
+ let insideCodeBlock = false;
+
+ for (let i = 0; i < lines.length; i++) {
+ const line = lines[i];
+
+ if (line.trim().startsWith("```")) {
+ insideCodeBlock = !insideCodeBlock;
+ continue;
+ }
+
+ if (this.settings.ignoreInCodeBlocks && insideCodeBlock) continue;
+
+ const openMatches = [
+ ...line.matchAll(/<([a-zA-Z][\w\-]*)\s*([^>]*?)>/g),
+ ];
+ for (const match of openMatches) {
+ const raw = match[0];
+ const tag = match[1].toLowerCase();
+ const matchIndex = match.index ?? 0;
+
+ if (excludedTags.includes(tag)) continue;
+ if (this.tagDetector.isSelfClosing(raw)) continue;
+ if (
+ this.settings.ignoreInlineCode &&
+ this.tagDetector.isInInlineCode(line, matchIndex)
+ )
+ continue;
+
+ openTags.push({ tag, line: i });
+ }
+
+ const closeMatches = [...line.matchAll(/<\/([a-zA-Z][\w\-]*)>/g)];
+ for (const match of closeMatches) {
+ const matchIndex = match.index ?? 0;
+ if (
+ this.settings.ignoreInlineCode &&
+ this.tagDetector.isInInlineCode(line, matchIndex)
+ )
+ continue;
+ closeTags.push(match[1].toLowerCase());
+ }
+ }
+
+ for (const closeTag of closeTags) {
+ const openIndex = openTags.findLastIndex(
+ (openTag) => openTag.tag === closeTag
+ );
+ if (openIndex !== -1) {
+ openTags.splice(openIndex, 1);
+ }
+ }
+
+ if (openTags.length === 0) {
+ return;
+ }
+
+ const tagToClose = openTags[openTags.length - 1].tag;
+ const closingTag = `${tagToClose}>`;
+ const cursor = editor.getCursor();
+
+ editor.replaceRange(closingTag, cursor);
+
+ if (this.settings.cursorPosition === "after") {
+ editor.setCursor({
+ line: cursor.line,
+ ch: cursor.ch + closingTag.length,
+ });
+ } else {
+ editor.setCursor(cursor);
+ }
+ }
+}
diff --git a/src/types.ts b/src/types.ts
new file mode 100644
index 0000000..02b0596
--- /dev/null
+++ b/src/types.ts
@@ -0,0 +1,13 @@
+export interface AutoCloseTagsSettings {
+ excludedTags: string;
+ cursorPosition: "between" | "after";
+ ignoreInCodeBlocks: boolean;
+ ignoreInlineCode: boolean;
+}
+
+export const DEFAULT_SETTINGS: AutoCloseTagsSettings = {
+ excludedTags: "",
+ cursorPosition: "between",
+ ignoreInCodeBlocks: false,
+ ignoreInlineCode: true,
+};