/* THIS IS A GENERATED/BUNDLED FILE BY ESBUILD if you want to view the source, please visit the github repository of this plugin */ var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // node_modules/sprintf-js/src/sprintf.js var require_sprintf = __commonJS({ "node_modules/sprintf-js/src/sprintf.js"(exports) { !function() { "use strict"; var re = { not_string: /[^s]/, not_bool: /[^t]/, not_type: /[^T]/, not_primitive: /[^v]/, number: /[diefg]/, numeric_arg: /[bcdiefguxX]/, json: /[j]/, not_json: /[^j]/, text: /^[^\x25]+/, modulo: /^\x25{2}/, placeholder: /^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/, key: /^([a-z_][a-z_\d]*)/i, key_access: /^\.([a-z_][a-z_\d]*)/i, index_access: /^\[(\d+)\]/, sign: /^[+-]/ }; function sprintf2(key) { return sprintf_format(sprintf_parse(key), arguments); } function vsprintf(fmt, argv) { return sprintf2.apply(null, [fmt].concat(argv || [])); } function sprintf_format(parse_tree, argv) { var cursor = 1, tree_length = parse_tree.length, arg, output = "", i, k, ph, pad, pad_character, pad_length, is_positive, sign; for (i = 0; i < tree_length; i++) { if (typeof parse_tree[i] === "string") { output += parse_tree[i]; } else if (typeof parse_tree[i] === "object") { ph = parse_tree[i]; if (ph.keys) { arg = argv[cursor]; for (k = 0; k < ph.keys.length; k++) { if (arg == void 0) { throw new Error(sprintf2('[sprintf] Cannot access property "%s" of undefined value "%s"', ph.keys[k], ph.keys[k - 1])); } arg = arg[ph.keys[k]]; } } else if (ph.param_no) { arg = argv[ph.param_no]; } else { arg = argv[cursor++]; } if (re.not_type.test(ph.type) && re.not_primitive.test(ph.type) && arg instanceof Function) { arg = arg(); } if (re.numeric_arg.test(ph.type) && (typeof arg !== "number" && isNaN(arg))) { throw new TypeError(sprintf2("[sprintf] expecting number but found %T", arg)); } if (re.number.test(ph.type)) { is_positive = arg >= 0; } switch (ph.type) { case "b": arg = parseInt(arg, 10).toString(2); break; case "c": arg = String.fromCharCode(parseInt(arg, 10)); break; case "d": case "i": arg = parseInt(arg, 10); break; case "j": arg = JSON.stringify(arg, null, ph.width ? parseInt(ph.width) : 0); break; case "e": arg = ph.precision ? parseFloat(arg).toExponential(ph.precision) : parseFloat(arg).toExponential(); break; case "f": arg = ph.precision ? parseFloat(arg).toFixed(ph.precision) : parseFloat(arg); break; case "g": arg = ph.precision ? String(Number(arg.toPrecision(ph.precision))) : parseFloat(arg); break; case "o": arg = (parseInt(arg, 10) >>> 0).toString(8); break; case "s": arg = String(arg); arg = ph.precision ? arg.substring(0, ph.precision) : arg; break; case "t": arg = String(!!arg); arg = ph.precision ? arg.substring(0, ph.precision) : arg; break; case "T": arg = Object.prototype.toString.call(arg).slice(8, -1).toLowerCase(); arg = ph.precision ? arg.substring(0, ph.precision) : arg; break; case "u": arg = parseInt(arg, 10) >>> 0; break; case "v": arg = arg.valueOf(); arg = ph.precision ? arg.substring(0, ph.precision) : arg; break; case "x": arg = (parseInt(arg, 10) >>> 0).toString(16); break; case "X": arg = (parseInt(arg, 10) >>> 0).toString(16).toUpperCase(); break; } if (re.json.test(ph.type)) { output += arg; } else { if (re.number.test(ph.type) && (!is_positive || ph.sign)) { sign = is_positive ? "+" : "-"; arg = arg.toString().replace(re.sign, ""); } else { sign = ""; } pad_character = ph.pad_char ? ph.pad_char === "0" ? "0" : ph.pad_char.charAt(1) : " "; pad_length = ph.width - (sign + arg).length; pad = ph.width ? pad_length > 0 ? pad_character.repeat(pad_length) : "" : ""; output += ph.align ? sign + arg + pad : pad_character === "0" ? sign + pad + arg : pad + sign + arg; } } } return output; } var sprintf_cache = /* @__PURE__ */ Object.create(null); function sprintf_parse(fmt) { if (sprintf_cache[fmt]) { return sprintf_cache[fmt]; } var _fmt = fmt, match, parse_tree = [], arg_names = 0; while (_fmt) { if ((match = re.text.exec(_fmt)) !== null) { parse_tree.push(match[0]); } else if ((match = re.modulo.exec(_fmt)) !== null) { parse_tree.push("%"); } else if ((match = re.placeholder.exec(_fmt)) !== null) { if (match[2]) { arg_names |= 1; var field_list = [], replacement_field = match[2], field_match = []; if ((field_match = re.key.exec(replacement_field)) !== null) { field_list.push(field_match[1]); while ((replacement_field = replacement_field.substring(field_match[0].length)) !== "") { if ((field_match = re.key_access.exec(replacement_field)) !== null) { field_list.push(field_match[1]); } else if ((field_match = re.index_access.exec(replacement_field)) !== null) { field_list.push(field_match[1]); } else { throw new SyntaxError("[sprintf] failed to parse named argument key"); } } } else { throw new SyntaxError("[sprintf] failed to parse named argument key"); } match[2] = field_list; } else { arg_names |= 2; } if (arg_names === 3) { throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported"); } parse_tree.push({ placeholder: match[0], param_no: match[1], keys: match[2], sign: match[3], pad_char: match[4], align: match[5], width: match[6], precision: match[7], type: match[8] }); } else { throw new SyntaxError("[sprintf] unexpected placeholder"); } _fmt = _fmt.substring(match[0].length); } return sprintf_cache[fmt] = parse_tree; } if (typeof exports !== "undefined") { exports["sprintf"] = sprintf2; exports["vsprintf"] = vsprintf; } if (typeof window !== "undefined") { window["sprintf"] = sprintf2; window["vsprintf"] = vsprintf; if (typeof define === "function" && define["amd"]) { define(function() { return { "sprintf": sprintf2, "vsprintf": vsprintf }; }); } } }(); } }); // src/main.ts var main_exports = {}; __export(main_exports, { default: () => EasyTypingPlugin }); module.exports = __toCommonJS(main_exports); var import_obsidian9 = require("obsidian"); var import_state6 = require("@codemirror/state"); // src/core.ts var import_obsidian = require("obsidian"); // src/utils.ts var import_state = require("@codemirror/state"); var DEBUG = false; var print = (message, ...optionalParams) => { if (DEBUG) { console.log(message, ...optionalParams); } }; function setDebug(value) { DEBUG = value; } function offsetToPos(doc, offset) { let line = doc.lineAt(offset); return { line: line.number - 1, ch: offset - line.from }; } function getTypeStrOfTransac(tr) { const event = tr.annotation(import_state.Transaction.userEvent); return event != null ? event : "unknown"; } function string2pairstring(s) { let cursorIdx = findFirstPipeNotPrecededByBackslash(s); let left = s.substring(0, cursorIdx); let _left = isRegexp(left) ? left : convertEscapeChar(left); let right = s.substring(cursorIdx + 1); let _right = isRegexp(right) ? right : convertEscapeChar(right); return { left: _left, right: _right }; } function isRegexp(s) { return s.startsWith("r/") && s.endsWith("/"); } function convertEscapeChar(s) { return s.replace(/\\\|/g, "|").replace(/\\n/g, "\n").replace(/\\r/g, "\r").replace(/\\t/g, " ").replace(/\\\n/g, "\\n").replace(/\\\r/g, "\\r").replace(/\\\t/g, "\\t").replace(/\\\\/g, "\\"); } function findFirstPipeNotPrecededByBackslash(s) { let regex = /^r\/[^]*?\/\|/; let regMatch = s.match(regex); if (regMatch) return regMatch[0].length - 1; const match = s.match(/((^|[^\\])(\\\\)*)\|/); return match ? s.indexOf(match[0]) + match[1].length : -1; } function stringDeleteAt(str, index) { return str.substring(0, index) + str.substring(index + 1); } function stringInsertAt(str, index, s) { return str.substring(0, index) + s + str.substring(index); } function isParamDefined(param) { return typeof param !== "undefined"; } function taboutCursorInPairedString(input, cursorPosition, symbolPairs) { const sortedPairs = [...symbolPairs].sort((a, b) => b.left.length - a.left.length); let stack = []; let fail = { isSuccess: false, newPosition: 0 }; for (let i = 0; i < cursorPosition; i++) { for (const { left: open, right: close } of sortedPairs) { if (input.startsWith(open, i) && (open !== close || stack.lastIndexOf(open) === -1)) { stack.push(open); i += open.length - 1; break; } else if (input.startsWith(close, i) && stack.length > 0) { const lastOpenIndex = stack.lastIndexOf(open); if (lastOpenIndex !== -1) { stack = stack.slice(0, lastOpenIndex); i += close.length - 1; break; } } } } if (stack.length === 0) { return fail; } let tempStack = []; for (let i = cursorPosition; i < input.length; i++) { for (const { left: open, right: close } of sortedPairs) { if (input.startsWith(open, i) && (open !== close || stack.lastIndexOf(open) === -1 && tempStack.lastIndexOf(open) === -1)) { tempStack.push(open); i += open.length - 1; break; } else if (input.startsWith(close, i)) { const lastOpenIndex = tempStack.lastIndexOf(open); if (lastOpenIndex === -1 && stack.lastIndexOf(open) !== -1) { return { isSuccess: true, newPosition: cursorPosition === i ? i + close.length : i }; } else if (lastOpenIndex !== -1) { tempStack = tempStack.slice(0, lastOpenIndex); i += close.length - 1; break; } } } } return fail; } // src/core.ts var import_language = require("@codemirror/language"); // src/formatting/script_category.ts var SCRIPT_CHAR_CLASSES = { ["chinese" /* Chinese */]: "\\u4e00-\\u9fff\\u3400-\\u4dbf", ["japanese" /* Japanese */]: "\\u3040-\\u309f\\u30a0-\\u30ff\\u31f0-\\u31ff", ["korean" /* Korean */]: "\\uac00-\\ud7af\\u1100-\\u11ff\\u3130-\\u318f", ["cjk" /* CJK */]: "\\u4e00-\\u9fff\\u3400-\\u4dbf\\u3040-\\u309f\\u30a0-\\u30ff\\u31f0-\\u31ff\\uac00-\\ud7af\\u1100-\\u11ff\\u3130-\\u318f", ["english" /* English */]: "A-Za-z", ["digit" /* Digit */]: "0-9", ["russian" /* Russian */]: "\\u0400-\\u04ff", ["unknown" /* Unknown */]: "" }; function classifyChar(ch) { if (!ch || ch.length === 0) return "unknown" /* Unknown */; const code = ch.charCodeAt(0); if (code >= 19968 && code <= 40959 || code >= 13312 && code <= 19903) { return "chinese" /* Chinese */; } if (code >= 12352 && code <= 12447 || code >= 12448 && code <= 12543 || code >= 12784 && code <= 12799) { return "japanese" /* Japanese */; } if (code >= 44032 && code <= 55215 || code >= 4352 && code <= 4607 || code >= 12592 && code <= 12687) { return "korean" /* Korean */; } if (code >= 65 && code <= 90 || code >= 97 && code <= 122) { return "english" /* English */; } if (code >= 48 && code <= 57) { return "digit" /* Digit */; } if (code >= 1024 && code <= 1279) { return "russian" /* Russian */; } return "unknown" /* Unknown */; } function resolveCharClass(cat, customCategories) { if (cat in SCRIPT_CHAR_CLASSES) { return SCRIPT_CHAR_CLASSES[cat]; } if (customCategories) { const custom = customCategories.find((c) => c.name === cat); if (custom) return custom.pattern; } return ""; } function buildPairRegexps(a, b, customCategories) { const classA = resolveCharClass(a, customCategories); const classB = resolveCharClass(b, customCategories); if (!classA || !classB) return []; const regAB = new RegExp(`([${classA}])([${classB}])`, "g"); const regBA = new RegExp(`([${classB}])([${classA}])`, "g"); return [regAB, regBA]; } // src/formatting/text_formatter.ts function capitalizeFirstLetter(ctx, isFirstPart, isCursorInPart) { if (!isFirstPart) return ctx; const { content, prevCh, curCh } = ctx; const regFirstSentence = /^\s*(?:\- (?:\[[x ]\] )?)?"?(?:\*{1,3}|_{1,3}|==|~~)?[a-z\u0401\u0451\u0410-\u044f]/g; const regHeaderSentence = /^(?:#+ |>+ ?|")(?:\*{1,3}|_{1,3}|==|~~)?[a-z\u0401\u0451\u0410-\u044f]/g; let textcopy = content; let match = regFirstSentence.exec(textcopy); let matchHeader = regHeaderSentence.exec(textcopy); let dstCharIndex = -1; if (match) { dstCharIndex = regFirstSentence.lastIndex - 1; } else if (matchHeader) { dstCharIndex = regHeaderSentence.lastIndex - 1; } if (isParamDefined(prevCh) && !isCursorInPart) { return ctx; } if (!(isParamDefined(prevCh) && dstCharIndex >= prevCh && dstCharIndex < curCh)) { dstCharIndex = -1; } if (dstCharIndex !== -1) { const newContent = textcopy.substring(0, dstCharIndex) + textcopy.charAt(dstCharIndex).toUpperCase() + textcopy.substring(dstCharIndex + 1); return { ...ctx, content: newContent }; } return ctx; } function capitalizeMidSentence(ctx) { let { content, curCh, prevCh, offset } = ctx; const reg = /(?:[.?!]\s+|[。!?]\s*)(?:\*{1,3}|_{1,3}|==|~~)?[a-z\u0401\u0451\u0410-\u044f]/g; while (true) { const match = reg.exec(content); if (!match) break; const tempIndex = reg.lastIndex - 1; const isSpaceDot = tempIndex - 2 < 0 || content.substring(tempIndex - 2, tempIndex) === " ."; if (isParamDefined(prevCh) && tempIndex >= prevCh - offset && tempIndex < curCh - offset && !isSpaceDot) { content = content.substring(0, tempIndex) + content.charAt(tempIndex).toUpperCase() + content.substring(reg.lastIndex); } } return { ...ctx, content }; } function isCJKContext(ch) { const cat = classifyChar(ch); if (cat === "chinese" /* Chinese */ || cat === "japanese" /* Japanese */ || cat === "korean" /* Korean */) { return true; } if (ch.length > 0) { const code = ch.charCodeAt(0); if (code >= 12288 && code <= 12351 || code >= 65281 && code <= 65295 || code >= 65306 && code <= 65312 || code >= 65339 && code <= 65344 || code >= 65371 && code <= 65376 || code >= 65504 && code <= 65510 || code >= 65072 && code <= 65103) { return true; } } return false; } function findTokenBounds(content, pos) { pos = Math.max(0, Math.min(pos, content.length)); let refIdx = pos > 0 ? pos - 1 : 0; if (refIdx >= content.length) refIdx = content.length - 1; if (refIdx < 0) return [0, 0]; const refIsCJK = isCJKContext(content.charAt(refIdx)); let left = pos; while (left > 0 && !/[\s\0]/.test(content.charAt(left - 1))) { const ch = content.charAt(left - 1); const isCJK = isCJKContext(ch); if (!isCJK && !/\w/.test(ch)) break; if (isCJK !== refIsCJK) break; left--; } let right = pos; while (right < content.length && !/[\s\0]/.test(content.charAt(right))) { const ch = content.charAt(right); const isCJK = isCJKContext(ch); if (!isCJK && !/\w/.test(ch)) break; if (isCJK !== refIsCJK) break; right++; } return [left, right]; } function extractToken(content, left, right) { return content.substring(left, right).replace(/\0/g, ""); } function extendCursorTokenForDict(content, seedL, seedR, prefixDict, usePrefix) { const seedToken = extractToken(content, seedL, seedR); let runL = seedL; while (runL > 0) { const ch = content.charAt(runL - 1); if (/[\s\0]/.test(ch) || !/\w/.test(ch) && !isCJKContext(ch)) break; runL--; } let runR = seedR; while (runR < content.length) { const ch = content.charAt(runR); if (/[\s\0]/.test(ch) || !/\w/.test(ch) && !isCJKContext(ch)) break; runR++; } let bestL = seedL, bestR = seedR, bestToken = seedToken; let bestMatched = prefixDict.shouldSuppressSpace(seedToken, usePrefix); let bestSpan = bestMatched ? seedR - seedL : -1; for (let l = seedL; l >= runL; l--) { for (let r = seedR; r <= runR; r++) { if (l === seedL && r === seedR) continue; const token = extractToken(content, l, r); if (prefixDict.shouldSuppressSpace(token, usePrefix)) { const span = r - l; if (span > bestSpan) { bestL = l; bestR = r; bestToken = token; bestMatched = true; bestSpan = span; } } } } if (!bestMatched) { return { left: seedL, right: seedR, token: seedToken }; } return { left: bestL, right: bestR, token: bestToken }; } function collectAllBoundaries(content, languagePairs, customCategories) { const positions = /* @__PURE__ */ new Set(); for (const pair of languagePairs) { const regexps = buildPairRegexps(pair.a, pair.b, customCategories); for (const reg of regexps) { reg.lastIndex = 0; while (true) { const match = reg.exec(content); if (!match) break; positions.add(reg.lastIndex - 1); } } } return positions; } var FORMATTING_CHARS_RE = /[*_~`^]/; function isFormattingChar(ch) { return FORMATTING_CHARS_RE.test(ch); } function collectFormattingSeparatedBoundaries(content, languagePairs, customCategories) { const positions = /* @__PURE__ */ new Set(); if (!FORMATTING_CHARS_RE.test(content)) return positions; const pairTests = []; for (const pair of languagePairs) { const classA = resolveCharClass(pair.a, customCategories); const classB = resolveCharClass(pair.b, customCategories); if (!classA || !classB) continue; const regA = new RegExp(`^[${classA}]$`); const regB = new RegExp(`^[${classB}]$`); pairTests.push({ test(a, b) { return regA.test(a) && regB.test(b) || regA.test(b) && regB.test(a); } }); } if (pairTests.length === 0) return positions; const len = content.length; let i = 0; while (i < len) { if (!isFormattingChar(content[i])) { i++; continue; } let blockStart = i; while (blockStart > 0 && isFormattingChar(content[blockStart - 1])) { blockStart--; } let blockEnd = i; while (blockEnd < len - 1 && isFormattingChar(content[blockEnd + 1])) { blockEnd++; } i = blockEnd + 1; let leftIdx = blockStart - 1; while (leftIdx >= 0 && (isFormattingChar(content[leftIdx]) || content[leftIdx] === "\0")) { leftIdx--; } if (leftIdx < 0) continue; let rightIdx = blockEnd + 1; while (rightIdx < len && (isFormattingChar(content[rightIdx]) || content[rightIdx] === "\0")) { rightIdx++; } if (rightIdx >= len) continue; const leftChar = content[leftIdx]; const rightChar = content[rightIdx]; let pairMatched = false; for (const pt of pairTests) { if (pt.test(leftChar, rightChar)) { pairMatched = true; break; } } if (!pairMatched) continue; const fmtChar = content[blockStart]; let matchedLeftDist = -1; let matchedRightDist = -1; for (let j = blockStart - 1; j >= 0; j--) { if (content[j] === fmtChar) { matchedLeftDist = blockStart - j; break; } if (/[\s\0]/.test(content[j])) break; } for (let j = blockEnd + 1; j < len; j++) { if (content[j] === fmtChar) { matchedRightDist = j - blockEnd; break; } if (/[\s\0]/.test(content[j])) break; } if (matchedLeftDist >= 0 && (matchedRightDist < 0 || matchedLeftDist <= matchedRightDist)) { positions.add(blockEnd + 1); } else if (matchedRightDist >= 0) { positions.add(blockStart); } else { if (isCJKContext(leftChar)) positions.add(blockStart); if (isCJKContext(rightChar)) positions.add(blockEnd + 1); } } return positions; } function applyLanguagePairSpacing(ctx, languagePairs, prefixDict, customCategories, debug) { let { content, curCh, prevCh, offset } = ctx; if (!isParamDefined(prevCh)) return ctx; const cursorInContent = curCh - offset; const allBoundaries = collectAllBoundaries(content, languagePairs, customCategories); const fmtBoundaries = collectFormattingSeparatedBoundaries(content, languagePairs, customCategories); for (const pos of fmtBoundaries) { allBoundaries.add(pos); } if (allBoundaries.size === 0) return ctx; let [tokLeft, tokRight] = findTokenBounds(content, cursorInContent); let cursorToken = extractToken(content, tokLeft, tokRight); let tokenIsFinalized = false; if (cursorToken.length === 0 && cursorInContent > 0) { let searchPos = cursorInContent - 1; while (searchPos >= 0 && /[\s\0]/.test(content.charAt(searchPos))) { searchPos--; } if (searchPos >= 0) { [tokLeft, tokRight] = findTokenBounds(content, searchPos); cursorToken = extractToken(content, tokLeft, tokRight); tokenIsFinalized = true; } } const isActivelyTyping = curCh !== prevCh; const usePrefix = isActivelyTyping && !tokenIsFinalized; const extended = extendCursorTokenForDict(content, tokLeft, tokRight, prefixDict, usePrefix); let tokLeftExt = extended.left; let tokRightExt = extended.right; let cursorTokenExt = extended.token; const cursorTokenSuppressed = prefixDict.shouldSuppressSpace(cursorTokenExt, usePrefix); let protectedUpTo = -1; if (cursorTokenSuppressed) { protectedUpTo = cursorTokenExt.length; } else { const matchLen = prefixDict.findLongestMatchFromStart(cursorTokenExt); if (matchLen > 0 && matchLen < cursorTokenExt.length) { const lastCharOfMatch = cursorTokenExt.charAt(matchLen - 1); const firstCharAfterMatch = cursorTokenExt.charAt(matchLen); if (classifyChar(lastCharOfMatch) !== classifyChar(firstCharAfterMatch)) { protectedUpTo = matchLen; } } } if (debug) { console.log("[LangPairSpacing] content:", JSON.stringify(content), "curCh:", curCh, "prevCh:", prevCh, "offset:", offset, "cursorInContent:", cursorInContent, "boundaries:", Array.from(allBoundaries), "tokenBounds:", [tokLeft, tokRight], "cursorToken:", JSON.stringify(cursorToken), "tokenBoundsExt:", [tokLeftExt, tokRightExt], "cursorTokenExt:", JSON.stringify(cursorTokenExt), "suppressed:", cursorTokenSuppressed, "protectedUpTo:", protectedUpTo); } const toInsert = []; const prevChInContent = prevCh - offset; let prefixDictExpired = false; if (!cursorTokenSuppressed) { if (isActivelyTyping && prevChInContent > tokLeftExt) { const prevToken = cursorTokenExt.substring(0, prevChInContent - tokLeftExt); prefixDictExpired = prefixDict.shouldSuppressSpace(prevToken, true); } else if (!isActivelyTyping || tokenIsFinalized) { prefixDictExpired = prefixDict.shouldSuppressSpace(cursorTokenExt, true); } } for (const pos of allBoundaries) { const inCursorToken = pos >= tokLeftExt && pos < tokRightExt; if (inCursorToken) { const posInToken = pos - tokLeftExt; if (posInToken > 0 && posInToken < protectedUpTo) { continue; } if (pos >= prevChInContent && pos < cursorInContent || prefixDictExpired) { toInsert.push(pos); } } else { if (pos >= prevChInContent && pos < cursorInContent) { const [seedL, seedR] = findTokenBounds(content, pos); const ext = extendCursorTokenForDict(content, seedL, seedR, prefixDict, false); if (!prefixDict.shouldSuppressSpace(ext.token, false)) { toInsert.push(pos); } } } } if (toInsert.length === 0) return ctx; toInsert.sort((a, b) => a - b); for (let i = toInsert.length - 1; i >= 0; i--) { content = content.substring(0, toInsert[i]) + " " + content.substring(toInsert[i]); } let shift = 0; for (const pos of toInsert) { if (pos < cursorInContent) shift++; } curCh += shift; return { ...ctx, content, curCh }; } function detectBoundarySpaceState(content, leftSymbols, rightSymbols) { const builtInBothSymbols = `"'`; const builtInLeftSoftSymbols = `\u3010\u3011\uFF08\uFF09\u300A\u300B\uFF0C\u3002\u3001\uFF1F\uFF1A\uFF1B\u2018\u2019\u201C\u201D\u300C\u300E\u300F\u300D\uFF01${builtInBothSymbols}[({`; const builtInRightSoftSymbols = `\u3010\u3011\uFF08\uFF09\u300A\u300B\uFF0C\u3002\u3001\uFF1F\uFF1A\uFF1B\u2018\u2019\u201C\u201D\u300C\u300E\u300F\u300D\uFF01${builtInBothSymbols},.?!:;])}`; const escapedStart = escapeForCharClass(rightSymbols + builtInRightSoftSymbols); const escapedEnd = escapeForCharClass(leftSymbols + builtInLeftSoftSymbols); const regStrictSpaceStart = /^\0?\s/; const regStrictSpaceEnd = /\s\0?$/; const regStartWithSpace = new RegExp(`^\\0?[\\s${escapedStart}]`); const regEndWithSpace = new RegExp(`[\\s${escapedEnd}]\\0?$`); let start = 0 /* none */; let end = 0 /* none */; if (regStartWithSpace.test(content) || content.startsWith("
")) { start = regStrictSpaceStart.test(content) ? 2 /* strict */ : 1 /* soft */; } if (regEndWithSpace.test(content) || content.endsWith("
")) { end = regStrictSpaceEnd.test(content) ? 2 /* strict */ : 1 /* soft */; } return { start, end }; } function escapeForCharClass(symbols) { return symbols.replace(/[\\\]^-]/g, "\\$&"); } // src/formatting/inline_spacing.ts function shouldInsertSpaceBetweenParts(prevType, curType, prevTextEndSpaceState, prevPartRightSpaceRequire, curPartLeftSpaceRequire, settings) { if (prevType === "none" /* none */) return false; const modeOf = (type) => { switch (type) { case "code" /* code */: return settings.InlineCodeSpaceMode; case "formula" /* formula */: return settings.InlineFormulaSpaceMode; case "wikilink" /* wikilink */: case "mdlink" /* mdlink */: return settings.InlineLinkSpaceMode; default: return 0 /* none */; } }; if (prevType === "text" /* text */) { if (curType === "user-defined" /* user */) { return curPartLeftSpaceRequire > prevTextEndSpaceState; } const curMode2 = modeOf(curType); return curMode2 > prevTextEndSpaceState; } if (prevType === "user-defined" /* user */) { if (curType === "text" /* text */) { return prevPartRightSpaceRequire > 0 /* none */; } if (curType === "user-defined" /* user */) { return curPartLeftSpaceRequire > 0 /* none */ && prevPartRightSpaceRequire > 0 /* none */; } const curMode2 = modeOf(curType); return curMode2 > 0 /* none */ && prevPartRightSpaceRequire > 0 /* none */; } const prevMode = modeOf(prevType); const curMode = modeOf(curType); if (curType === "user-defined" /* user */) { return prevMode > 0 /* none */ && curPartLeftSpaceRequire > 0 /* none */; } return prevMode > 0 /* none */ || curMode > 0 /* none */; } function shouldPrependSpaceToText(prevType, txtStartSpaceState, prevPartRightSpaceRequire, settings) { switch (prevType) { case "none" /* none */: return false; case "code" /* code */: return settings.InlineCodeSpaceMode > txtStartSpaceState; case "formula" /* formula */: return settings.InlineFormulaSpaceMode > txtStartSpaceState; case "wikilink" /* wikilink */: case "mdlink" /* mdlink */: if (!settings.InlineLinkSmartSpace) { return settings.InlineLinkSpaceMode > txtStartSpaceState; } return false; case "user-defined" /* user */: return prevPartRightSpaceRequire > txtStartSpaceState; default: return false; } } // src/formatting/prefix_dictionary.ts var PrefixDictionary = class { constructor(raw) { this.literalWords = []; this.regexEntries = []; if (!raw || raw.trim() === "") return; const tokenPattern = /\/(?:[^/\\]|\\.)+\/[gimsuy]*|[^\s,]+/g; let match; while ((match = tokenPattern.exec(raw)) !== null) { const token = match[0]; const regexMatch = /^\/(.+)\/([gimsuy]*)$/.exec(token); if (regexMatch) { try { this.regexEntries.push(new RegExp(regexMatch[1], regexMatch[2])); } catch (e) { console.warn("PrefixDictionary: invalid regex:", token, e); } } else { this.literalWords.push(token); } } } isExactMatch(token) { for (const word of this.literalWords) { if (word === token) return true; } for (const re of this.regexEntries) { re.lastIndex = 0; const anchored = new RegExp(`^(?:${re.source})$`, re.flags); if (anchored.test(token)) return true; } return false; } isPrefixOfWord(token) { if (token.length === 0) return false; for (const word of this.literalWords) { if (word.length > token.length && word.startsWith(token)) { return true; } } return false; } shouldSuppressSpace(token, isAtCursor) { if (this.isExactMatch(token)) return true; if (isAtCursor && this.isPrefixOfWord(token)) return true; return false; } findLongestMatchFromStart(token) { let maxLen = -1; for (const word of this.literalWords) { if (token.startsWith(word) && word.length > maxLen) { maxLen = word.length; } } for (const re of this.regexEntries) { const anchored = new RegExp(`^(?:${re.source})`, re.flags.replace("g", "")); const match = anchored.exec(token); if (match && match[0].length > maxLen) { maxLen = match[0].length; } } return maxLen; } }; // src/core.ts var LineFormater = class { constructor() { } syntaxTreeNodeNameType(name) { if (name.contains("code") && !name.contains("link")) { return "code" /* code */; } else if (name.contains("math")) { return "formula" /* formula */; } else { return "text" /* text */; } } parseLineWithSyntaxTree(state, lineNum, regRegExp) { let linePartsOfTxtCodeFormula = []; let line = state.doc.line(lineNum); const tree = (0, import_language.syntaxTree)(state); let pos = line.from; let prevNodeType = "none" /* none */; let prevBeginIdx = 0; while (pos < line.to) { let node = tree.resolve(pos, 1); let curNodeType = this.syntaxTreeNodeNameType(node.name); if (prevNodeType == "none" /* none */) { prevNodeType = curNodeType; prevBeginIdx = 0; } else if (prevNodeType == curNodeType) { } else { linePartsOfTxtCodeFormula.push({ content: line.text.substring(prevBeginIdx, pos - line.from), type: prevNodeType, begin: prevBeginIdx, end: pos - line.from, leftSpaceRequire: 0 /* none */, rightSpaceRequire: 0 /* none */ }); prevNodeType = curNodeType; prevBeginIdx = pos - line.from; } if (curNodeType == "text" /* text */) { pos++; } else { pos = node.to; } if (pos == line.to) { linePartsOfTxtCodeFormula.push({ content: line.text.substring(prevBeginIdx, pos - line.from), type: prevNodeType, begin: prevBeginIdx, end: pos - line.from, leftSpaceRequire: 0 /* none */, rightSpaceRequire: 0 /* none */ }); } } let retArray = []; for (let i = 0; i < linePartsOfTxtCodeFormula.length; i++) { if (linePartsOfTxtCodeFormula[i].type != "text" /* text */) { retArray.push(linePartsOfTxtCodeFormula[i]); } else { let tempArray; if (isParamDefined(regRegExp)) tempArray = splitTextWithLinkAndUserDefined(linePartsOfTxtCodeFormula[i].content, regRegExp); else tempArray = splitTextWithLinkAndUserDefined(linePartsOfTxtCodeFormula[i].content); tempArray.forEach((item) => { item.begin += linePartsOfTxtCodeFormula[i].begin; item.end += linePartsOfTxtCodeFormula[i].begin; retArray.push(item); }); } } return retArray; } formatLineOfDoc(state, settings, fromB, toB, insertedStr) { let doc = state.doc; let line = doc.lineAt(fromB).text; let res = null; if (insertedStr.contains("\n")) { res = this.formatLine(state, doc.lineAt(fromB).number, settings, offsetToPos(doc, fromB).ch, offsetToPos(doc, fromB).ch); } else { res = this.formatLine(state, doc.lineAt(fromB).number, settings, offsetToPos(doc, toB).ch, offsetToPos(doc, fromB).ch); } if (res === null || res[2].length == 0) return null; let newline = stringInsertAt(res[0], res[1], "|"); let changes = []; let offset = doc.lineAt(fromB).from; for (let changeItem of res[2]) { changes.push({ changes: { from: offset + changeItem.begin, to: offset + changeItem.end, insert: changeItem.text }, userEvent: "EasyTyping.change" }); } if (insertedStr.contains("\n")) { print("insertStr", insertedStr); res[1] += insertedStr.length; } return [changes, { selection: { anchor: offset + res[1] }, userEvent: "EasyTyping.change" }]; } formatLine(state, lineNum, settings, curCh, prevCh) { let line = state.doc.line(lineNum).text; let regNull = /^\s*$/g; if (regNull.test(line)) return [line, curCh, []]; let lineParts = settings.UserDefinedRegSwitch ? this.parseLineWithSyntaxTree(state, lineNum, settings.UserDefinedRegExp) : this.parseLineWithSyntaxTree(state, lineNum); if (settings.debug) console.log("line parts\n", lineParts); let linePartsOrigin = JSON.parse(JSON.stringify(lineParts)); let inlineChangeList = []; let cursorLinePartIndex = -1; let cursorRelativeIndex = -1; let resultCursorCh = 0; for (let i = 0; i < lineParts.length; i++) { if (curCh > lineParts[i].begin && curCh <= lineParts[i].end) { cursorLinePartIndex = i; cursorRelativeIndex = curCh - lineParts[i].begin; if (lineParts[i].type === "text" /* text */) { lineParts[i].content = stringInsertAt(lineParts[i].content, cursorRelativeIndex, "\0"); } break; } } const prefixDict = new PrefixDictionary(settings.PrefixDictionary); let resultLine = ""; let offset = 0; let prevPartType = "none" /* none */; let prevTextEndSpaceState = 0 /* none */; for (let i = 0; i < lineParts.length; i++) { if (lineParts[i].type === "text" /* text */) { let content = lineParts[i].content; let ctx = { content, curCh, prevCh, offset }; if (settings.AutoCapital) { if (i === 0) { ctx = capitalizeFirstLetter(ctx, true, cursorLinePartIndex === 0); } ctx = capitalizeMidSentence(ctx); content = ctx.content; curCh = ctx.curCh; } if (settings.languagePairs && settings.languagePairs.length > 0) { ctx = { ...ctx, content, curCh }; ctx = applyLanguagePairSpacing(ctx, settings.languagePairs, prefixDict, settings.customScriptCategories, settings.debug); content = ctx.content; curCh = ctx.curCh; } lineParts[i].content = content; const boundary = detectBoundarySpaceState(content, settings.SoftSpaceLeftSymbols || "", settings.SoftSpaceRightSymbols || ""); if (prevPartType !== "none" /* none */) { if (prevPartType === "wikilink" /* wikilink */ || prevPartType === "mdlink" /* mdlink */) { if (!settings.InlineLinkSmartSpace && settings.InlineLinkSpaceMode > boundary.start) { lineParts[i].content = " " + lineParts[i].content; content = lineParts[i].content; } else if (settings.InlineLinkSmartSpace && boundary.start === 0 /* none */) { const charAtTextBegin = content.charAt(0) === "\0" ? content.charAt(1) : content.charAt(0); const regMdLinkEnd = /\]/; const charAtLinkEndIndex = lineParts[i - 1].content.search(regMdLinkEnd) - 1; const charAtLinkEnd = lineParts[i - 1].content.charAt(charAtLinkEndIndex); if (charAtLinkEnd !== "[") { const twoNeighborChars = charAtLinkEnd + charAtTextBegin; const regNotNeedSpace = /[\u4e00-\u9fa5,。?:;""''\-)}][\u4e00-\u9fa5]/g; if (!regNotNeedSpace.test(twoNeighborChars)) { lineParts[i].content = " " + lineParts[i].content; content = lineParts[i].content; } } } } else if (shouldPrependSpaceToText(prevPartType, boundary.start, i > 0 ? lineParts[i - 1].rightSpaceRequire : 0 /* none */, settings)) { lineParts[i].content = " " + lineParts[i].content; content = lineParts[i].content; } } if (i === cursorLinePartIndex) { const n = content.search("\0"); resultCursorCh = offset + n; lineParts[i].content = stringDeleteAt(content, n); } resultLine += lineParts[i].content; offset += lineParts[i].content.length; prevPartType = "text" /* text */; prevTextEndSpaceState = boundary.end; } else { if (lineParts[i].type === "formula" /* formula */ && lineParts[i].content === "$\\qquad$") { prevPartType = "text" /* text */; prevTextEndSpaceState = 2 /* strict */; resultLine += lineParts[i].content; offset += lineParts[i].content.length; continue; } if ((lineParts[i].type === "wikilink" /* wikilink */ || lineParts[i].type === "mdlink" /* mdlink */) && prevPartType === "text" /* text */) { const prevEnd = prevTextEndSpaceState; if (prevEnd >= settings.InlineLinkSpaceMode && !settings.InlineLinkSmartSpace) { } else if (prevEnd === 2 /* strict */ && settings.InlineLinkSpaceMode === 2 /* strict */) { } else if (settings.InlineLinkSpaceMode === 2 /* strict */ && prevEnd < 2 /* strict */) { lineParts[i - 1].content += " "; resultLine += " "; offset += 1; } else if (settings.InlineLinkSmartSpace && lineParts[i - 1].content.endsWith(" ")) { let charAtLinkBegin = this.getLinkBeginChar(lineParts[i]); if (charAtLinkBegin) { const tempContent = lineParts[i - 1].content + charAtLinkBegin; const regRevertSpace = /[\u4e00-\u9fa5] [\u4e00-\u9fa5]$/; if (regRevertSpace.test(tempContent)) { lineParts[i - 1].content = lineParts[i - 1].content.substring(0, lineParts[i - 1].content.length - 1); resultLine = resultLine.substring(0, resultLine.length - 1); offset -= 1; } } } else if (settings.InlineLinkSmartSpace && prevEnd === 0 /* none */) { const charAtTextEnd = lineParts[i - 1].content.charAt(lineParts[i - 1].content.length - 1); const charAtLinkBegin = this.getLinkBeginChar(lineParts[i]); if (charAtLinkBegin) { const regNoNeedSpace = /[\u4e00-\u9fa5][\u4e00-\u9fa5]/g; const twoNeighborChars = charAtTextEnd + charAtLinkBegin; if (!regNoNeedSpace.test(twoNeighborChars)) { lineParts[i - 1].content += " "; resultLine += " "; offset += 1; } } } else if (!settings.InlineLinkSmartSpace && settings.InlineLinkSpaceMode > prevEnd) { lineParts[i - 1].content += " "; resultLine += " "; offset += 1; } } else if (prevPartType === "text" /* text */) { if (shouldInsertSpaceBetweenParts("text" /* text */, lineParts[i].type, prevTextEndSpaceState, i > 0 ? lineParts[i - 1].rightSpaceRequire : 0 /* none */, lineParts[i].leftSpaceRequire, settings)) { lineParts[i - 1].content += " "; resultLine += " "; offset += 1; } } else if (prevPartType !== "none" /* none */) { if (shouldInsertSpaceBetweenParts(prevPartType, lineParts[i].type, prevTextEndSpaceState, i > 0 ? lineParts[i - 1].rightSpaceRequire : 0 /* none */, lineParts[i].leftSpaceRequire, settings)) { inlineChangeList.push({ text: " ", begin: lineParts[i].begin, end: lineParts[i].begin, origin: "" }); resultLine += " "; offset += 1; } } if (i === cursorLinePartIndex) { resultCursorCh = offset + cursorRelativeIndex; } resultLine += lineParts[i].content; offset += lineParts[i].content.length; prevPartType = lineParts[i].type; prevTextEndSpaceState = 0 /* none */; } } for (let i = 0; i < lineParts.length; i++) { if (lineParts[i].type === "text" /* text */ && lineParts[i].content != linePartsOrigin[i].content) { inlineChangeList.push({ text: lineParts[i].content, begin: linePartsOrigin[i].begin, end: linePartsOrigin[i].end, origin: linePartsOrigin[i].content }); } } inlineChangeList = inlineChangeList.sort((a, b) => a.begin - b.begin); return [resultLine, resultCursorCh, inlineChangeList]; } getLinkBeginChar(part) { if (part.type === "wikilink" /* wikilink */) { const regAlias = /\|/; const charOfAliasBegin = part.content.search(regAlias); let beginIndex = 2; if (part.content.charAt(0) === "!") beginIndex = 3; if (charOfAliasBegin !== -1) { beginIndex = charOfAliasBegin + 1; } else if (part.content.charAt(beginIndex) === "#") { beginIndex += 1; } const ch = part.content.charAt(beginIndex); return ch === "]" ? null : ch; } else { const regMdLinkBegin = /\[/; const charAtLinkBeginIndex = part.content.search(regMdLinkBegin) + 1; const ch = part.content.charAt(charAtLinkBeginIndex); return ch === "]" ? null : ch; } } }; function matchWithReg(text, regExp, type, inlineTypeArray, checkArray = false, leftSpaceRe = 0 /* none */, rightSpaceRe = 0 /* none */) { let retArray = inlineTypeArray; let matchArray = []; retArray = retArray.sort((a, b) => a.begin - b.begin); while (true) { let match = regExp.exec(text); if (!match) break; let valid = true; if (checkArray) { for (let i = 0; i < retArray.length; i++) { if (regExp.lastIndex > retArray[i].begin && retArray[i].end > match.index) { valid = false; break; } } } if (!valid) continue; matchArray.push({ content: match[0], type, begin: match.index, end: regExp.lastIndex, leftSpaceRequire: leftSpaceRe, rightSpaceRequire: rightSpaceRe }); } retArray = retArray.concat(matchArray); return retArray; } function splitTextWithLinkAndUserDefined(text, regExps) { let retArray = []; let regWikiLink = /\!{0,2}\[\[[^\[\]]*?\]\]/g; let regMdLink = /\!{0,2}\[[^\[\]]*?\]\([^\s]*\)/g; retArray = matchWithReg(text, regWikiLink, "wikilink" /* wikilink */, retArray); retArray = matchWithReg(text, regMdLink, "mdlink" /* mdlink */, retArray); let regExpList = []; let leftSRequireList = []; let rightSRequireList = []; let regNull = /^\s*$|^\/\//g; let regSRequire = /\|[\-=\+][\-=\+]$/; if (regExps) { let regs = regExps.split("\n"); for (let i = 0; i < regs.length; i++) { if (regNull.test(regs[i])) continue; if (!regSRequire.test(regs[i]) || regs[i].length <= 3) { new import_obsidian.Notice("EasyTyping: \u7B2C" + String(i) + "\u884C\u81EA\u5B9A\u4E49\u6B63\u5219\u4E0D\u7B26\u5408\u89C4\u8303\n" + regs[i]); continue; } let regItem = regs[i].substring(0, regs[i].length - 3); let spaceReqString = regs[i].substring(regs[i].length - 3); let isValidReg = true; try { let regTemp = new RegExp(regItem, "g"); } catch (error) { isValidReg = false; console.error("EasyTyping: Invalid RegExp:", regItem, error); } if (isValidReg) { regExpList.push(new RegExp(regItem, "g")); leftSRequireList.push(str2SpaceState(spaceReqString.charAt(1))); rightSRequireList.push(str2SpaceState(spaceReqString.charAt(2))); } } let regLen = regExpList.length; for (let i = 0; i < regLen; i++) { retArray = matchWithReg(text, regExpList[i], "user-defined" /* user */, retArray, true, leftSRequireList[i], rightSRequireList[i]); } } retArray = retArray.sort((a, b) => a.begin - b.begin); let textArray = []; let textBegin = 0; let textEnd = 0; for (let i = 0; i < retArray.length; i++) { if (textBegin < retArray[i].begin) { textEnd = retArray[i].begin; textArray.push({ content: text.substring(textBegin, textEnd), type: "text" /* text */, begin: textBegin, end: textEnd, leftSpaceRequire: 0 /* none */, rightSpaceRequire: 0 /* none */ }); } textBegin = retArray[i].end; } if (textBegin != text.length) { textArray.push({ content: text.substring(textBegin, text.length), type: "text" /* text */, begin: textBegin, end: text.length, leftSpaceRequire: 0 /* none */, rightSpaceRequire: 0 /* none */ }); } retArray = retArray.concat(textArray); retArray = retArray.sort((a, b) => a.begin - b.begin); return retArray; } function isCursorInUserDefinedRegexBlock(lineText, column, regExps) { const parts = splitTextWithLinkAndUserDefined(lineText, regExps); for (const part of parts) { if (part.type === "user-defined" /* user */ && column >= part.begin && column < part.end) { return true; } } return false; } function str2SpaceState(s) { switch (s) { case "+": return 2 /* strict */; case "=": return 1 /* soft */; case "-": default: return 0 /* none */; } } function string2SpaceState(s) { if (Number(s) == 0 /* none */) return 0 /* none */; if (Number(s) == 1 /* soft */) return 1 /* soft */; if (Number(s) == 2 /* strict */) return 2 /* strict */; return 0 /* none */; } function getPosLineType(state, pos) { const line = state.doc.lineAt(pos); let line_number = line.number; const tree = (0, import_language.ensureSyntaxTree)(state, line.to); if (!tree) return "text" /* text */; const token = tree.resolve(line.from, 1).name; if (token.contains("table")) { return "table" /* table */; } if (token.contains("hmd-frontmatter")) { return "frontmatter" /* frontmatter */; } if (token.contains("math")) { for (let p = line.from + 1; p < line.to; p += 1) { if (!tree.resolve(p, 1).name.contains("math")) { return "text" /* text */; } } return "formula" /* formula */; } else if (token.contains("code") && token.contains("block")) { for (let p = line.from + 1; p < line.to; p += 1) { let t = tree.resolve(p, 1).name; if (!(t.contains("code") && t.contains("block"))) { return "text" /* text */; } } return "codeblock" /* codeblock */; } else if (token.contains("quote") && !token.contains("callout")) { let callout_start_line = -1; for (let l = line_number - 1; l >= 1; l -= 1) { let l_line = state.doc.line(l); let l_token = tree.resolve(l_line.from, 1).name; if (!l_token.contains("quote")) { break; } if (l_token.contains("callout")) { callout_start_line = l; break; } } if (callout_start_line == -1) return "text" /* text */; let is_code_block = false; let reset = false; let reg_code_begin = /^>+ ```/; let reg_code_end = /^>+ ```$/; for (let l = callout_start_line + 1; l <= line_number; l += 1) { let l_line = state.doc.line(l); if (reset) { is_code_block = false; reset = false; } if (is_code_block && reg_code_end.test(l_line.text)) { is_code_block = true; reset = true; } else if (!is_code_block && reg_code_begin.test(l_line.text)) { is_code_block = true; } } if (is_code_block) { return "codeblock" /* codeblock */; } else return "text" /* text */; } else if (token.contains("list")) { for (let p = line.from + 1; p < line.to; p += 1) { let t = tree.resolve(p, 1).name; if (t.contains("code") && t.contains("block")) { return "codeblock" /* codeblock */; } } } return "text" /* text */; } function getPosLineType2(state, pos) { const line = state.doc.lineAt(pos); const tree = (0, import_language.syntaxTree)(state); const token = tree.resolve(line.from, 1).name; if (token.contains("hmd-frontmatter")) { return "frontmatter" /* frontmatter */; } if (token.contains("math")) { for (let p = line.from + 1; p < line.to; p += 1) { if (!tree.resolve(p, 1).name.contains("math")) { return "text" /* text */; } } return "formula" /* formula */; } else if (token.contains("code") && token.contains("block")) { for (let p = line.from + 1; p < line.to; p += 1) { let t = tree.resolve(p, 1).name; if (!(t.contains("code") && t.contains("block"))) { return "text" /* text */; } } return "codeblock" /* codeblock */; } for (let p = line.from; p < line.to; p += 1) { if (tree.resolve(p, 1).name.contains("list")) { return "list" /* list */; } else if (tree.resolve(p, 1).name.contains("callout")) { return "callout_title" /* callout_title */; } } if (token.contains("quote")) { return "quote" /* quote */; } return "text" /* text */; } // src/settings/settings_types.ts var DEFAULT_SETTINGS = { Tabout: true, SmartPaste: true, BetterCodeEdit: true, BetterBackspace: true, AutoFormat: true, AutoFormatPaste: true, ExcludeFiles: "", AutoCapital: false, languagePairs: [ { a: "chinese" /* Chinese */, b: "english" /* English */ }, { a: "chinese" /* Chinese */, b: "digit" /* Digit */ }, { a: "digit" /* Digit */, b: "english" /* English */ } ], PrefixDictionary: "n8n, /[1234][dD]/\npython3, Python3", SoftSpaceLeftSymbols: "-", SoftSpaceRightSymbols: "-", customScriptCategories: [], InlineCodeSpaceMode: 1 /* soft */, InlineFormulaSpaceMode: 1 /* soft */, InlineLinkSpaceMode: 1 /* soft */, InlineLinkSmartSpace: true, UserDefinedRegSwitch: true, UserDefinedRegExp: "{{.*?}}|++\n<.*?>|--\n\\[\\!.*?\\][-+]{0,1}|-+\n(file:///|https?://|ftp://|obsidian://|zotero://|www.)[^\\s\uFF08\uFF09\u300A\u300B\u3002,\uFF0C\uFF01\uFF1F;\uFF1B\uFF1A\u201C\u201D\u2018\u2019\\)\\(\\[\\]\\{\\}']+|--\n\n[a-zA-Z0-9_\\-.]+@[a-zA-Z0-9_\\-.]+|++\n// Tags in Obsidian//(? or \u300B to Markdown blockquote marker", "builtin-quote-space": "Auto-insert space after blockquote marker >" } }; var en_US_default = locale; // src/lang/locale/zh-CN.ts var locale2 = { settings: { smartPaste: { name: "\u667A\u80FD\u7C98\u8D34", desc: "\u5728\u5217\u8868\u6216\u5F15\u7528\u5757\u4E2D\u7C98\u8D34\u65F6\uFF0C\u81EA\u52A8\u6DFB\u52A0\u7F29\u8FDB\u548C\u5217\u8868/\u5F15\u7528\u7B26\u53F7" }, codeblockEdit: { name: "\u589E\u5F3A\u4EE3\u7801\u5757\u7F16\u8F91", desc: "\u589E\u5F3A\u4EE3\u7801\u5757\u5185\u7684\u7F16\u8F91\uFF08Cmd/Ctrl+A \u9009\u4E2D\u3001Tab\u3001\u5220\u9664\u3001\u7C98\u8D34\uFF09" }, backspaceEdit: { name: "\u667A\u80FD\u9000\u683C\u952E", desc: "\u589E\u5F3A\u5220\u9664\u7A7A\u5217\u8868\u9879\u6216\u7A7A\u5F15\u7528\u884C\u7684\u529F\u80FD" }, tabOut: { name: "Tab \u8DF3\u51FA\u914D\u5BF9\u7B26\u53F7", desc: "\u6309 Tab \u952E\u8DF3\u51FA\u914D\u5BF9\u7B26\u53F7\uFF0C\u5982\u3010\u3011\u3001\uFF08\uFF09\u3001\u300A\u300B\u3001\u5F15\u53F7\u3001\u884C\u5185\u4EE3\u7801\u7B49" }, autoFormatting: { name: "\u8F93\u5165\u65F6\u81EA\u52A8\u683C\u5F0F\u5316", desc: "\u662F\u5426\u5728\u7F16\u8F91\u6587\u6863\u65F6\u81EA\u52A8\u683C\u5F0F\u5316\u6587\u672C\uFF0C\u81EA\u52A8\u683C\u5F0F\u5316\u7684\u603B\u5F00\u5173" }, autoFormatPaste: { name: "\u7C98\u8D34\u65F6\u81EA\u52A8\u683C\u5F0F\u5316", desc: "\u7C98\u8D34\u65F6\u662F\u5426\u81EA\u52A8\u683C\u5F0F\u5316\uFF0CCMD/CTRL+SHIFT+V \u65E0\u683C\u5F0F\u7C98\u8D34\u65F6\u4E0D\u89E6\u53D1\u3002" }, languagePairSpacing: { name: "\u8BED\u8A00\u95F4\u7A7A\u683C\u7B56\u7565", desc: "\u5B9A\u4E49\u4E0D\u540C\u8BED\u8A00/\u7B26\u53F7\u7C7B\u578B\u4E4B\u95F4\u662F\u5426\u81EA\u52A8\u6DFB\u52A0\u7A7A\u683C" }, prefixDictionary: { name: "\u524D\u7F00\u8BCD\u5178", desc: "\u7528\u9017\u53F7\u3001\u7A7A\u683C\u6216\u6362\u884C\u5206\u9694\uFF0C\u652F\u6301\u8BCD\u6216 /\u6B63\u5219/\u3002\u5339\u914D\u7684 token \u4E0D\u4F1A\u88AB\u63D2\u5165\u7A7A\u683C\uFF0C\u6B63\u5728\u8F93\u5165\u7684\u524D\u7F00\u4E5F\u4F1A\u6682\u4E0D\u63D2\u5165\u7A7A\u683C" }, softSpaceSymbols: { leftName: "\u81EA\u5B9A\u4E49\u5DE6\u4FA7\u8F6F\u7A7A\u683C\u989D\u5916\u7B26\u53F7", leftDesc: `\u5E38\u89C1\u7684\u5168\u89D2\u6807\u70B9\u3001\u82F1\u6587\u5F15\u53F7\uFF08' "\uFF09\u548C\u5DE6\u62EC\u53F7\uFF08[ ( {\uFF09\u5DF2\u5185\u7F6E\u652F\u6301\u3002\u5728\u6B64\u6DFB\u52A0\u989D\u5916\u7684\u5DE6\u4FA7\u7B26\u53F7\uFF08\u5982 -\uFF09`, rightName: "\u81EA\u5B9A\u4E49\u53F3\u4FA7\u8F6F\u7A7A\u683C\u989D\u5916\u7B26\u53F7", rightDesc: `\u5E38\u89C1\u7684\u5168\u89D2\u6807\u70B9\u3001\u82F1\u6587\u5F15\u53F7\uFF08' "\uFF09\u3001\u53F3\u62EC\u53F7\uFF08] ) }\uFF09\u4EE5\u53CA\u82F1\u6587\u534A\u89D2\u6807\u70B9\uFF08. , ? ! : ;\uFF09\u5DF2\u5185\u7F6E\u4E3A\u53F3\u8F6F\u7A7A\u683C\u7B26\u53F7\u3002\u5728\u6B64\u6DFB\u52A0\u989D\u5916\u7684\u53F3\u4FA7\u7B26\u53F7\uFF08\u5982 -\uFF09` }, customScriptCategories: { name: "\u81EA\u5B9A\u4E49\u8BED\u8A00/\u7B26\u53F7\u96C6", desc: "\u6DFB\u52A0\u81EA\u5B9A\u4E49\u8BED\u8A00\u6216\u7B26\u53F7\u96C6\u7528\u4E8E\u7A7A\u683C\u7B56\u7565", namePlaceholder: "\u540D\u79F0", patternPlaceholder: "\u5B57\u7B26\u7C7B\u6A21\u5F0F" }, capitalizeFirstLetter: { name: "\u53E5\u9996\u5B57\u6BCD\u5927\u5199", desc: "\u82F1\u6587\u6BCF\u4E2A\u53E5\u9996\u5B57\u6BCD\u5927\u5199\uFF0C\u53EF\u64A4\u9500" }, spaceStrategyInlineCode: { name: "\u884C\u5185\u4EE3\u7801\u548C\u6587\u672C\u4E4B\u95F4\u7684\u7A7A\u683C\u7B56\u7565", desc: "\u5B9A\u4E49\u884C\u5185\u4EE3\u7801\u548C\u6587\u672C\u4E4B\u95F4\u7684\u7A7A\u683C\u7B56\u7565" }, spaceStrategyInlineFormula: { name: "\u884C\u5185\u516C\u5F0F\u548C\u6587\u672C\u4E4B\u95F4\u7684\u7A7A\u683C\u7B56\u7565", desc: "\u5B9A\u4E49\u884C\u5185\u516C\u5F0F\u548C\u6587\u672C\u4E4B\u95F4\u7684\u7A7A\u683C\u7B56\u7565" }, spaceStrategyLinkText: { name: "\u94FE\u63A5\u548C\u6587\u672C\u4E4B\u95F4\u7684\u7A7A\u683C\u7B56\u7565", desc: "\u5B9A\u4E49 [[wikilink]] [mdlink](...) \u548C\u6587\u672C\u4E4B\u95F4\u7684\u7A7A\u683C\u7B56\u7565" }, userDefinedRegexpSwitch: { name: "\u7528\u6237\u5B9A\u4E49\u7684\u6B63\u5219\u8868\u8FBE\u5F0F\u5F00\u5173", desc: "\u81EA\u5B9A\u4E49\u6B63\u5219\u8868\u8FBE\u5F0F\u5F00\u5173\uFF0C\u5339\u914D\u5230\u7684\u5185\u5BB9\u4E0D\u8FDB\u884C\u683C\u5F0F\u5316\uFF0C\u4E14\u53EF\u4EE5\u8BBE\u7F6E\u5339\u914D\u5230\u7684\u5185\u5BB9\u5757\u4E0E\u5176\u4ED6\u5185\u5BB9\u4E4B\u95F4\u7684\u7A7A\u683C\u7B56\u7565" }, userDefinedRegexp: { name: "\u7528\u6237\u5B9A\u4E49\u7684\u6B63\u5219\u8868\u8FBE\u5F0F", desc: "\u7528\u6237\u81EA\u5B9A\u4E49\u6B63\u5219\u8868\u8FBE\u5F0F\uFF0C\u5339\u914D\u5230\u7684\u5185\u5BB9\u4E0D\u8FDB\u884C\u683C\u5F0F\u5316\uFF0C\u6BCF\u884C\u4E00\u4E2A\u8868\u8FBE\u5F0F\uFF0C\u884C\u5C3E\u4E0D\u8981\u968F\u610F\u52A0\u7A7A\u683C\u3002\u6BCF\u884C\u672B\u5C3E3\u4E2A\u5B57\u7B26\u7684\u56FA\u5B9A\u4E3A|\u548C\u4E24\u4E2A\u7A7A\u683C\u7B56\u7565\u7B26\u53F7\uFF0C\u7A7A\u683C\u7B56\u7565\u7B26\u53F7\u4E3A-=+\uFF0C\u5206\u522B\u4EE3\u8868\u4E0D\u8981\u6C42\u7A7A\u683C(-)\uFF0C\u8F6F\u7A7A\u683C(=)\uFF0C\u4E25\u683C\u7A7A\u683C(+)\u3002\u8FD9\u4E24\u4E2A\u7A7A\u683C\u7B56\u7565\u7B26\u53F7\u5206\u522B\u4E3A\u5339\u914D\u533A\u5757\u7684\u5DE6\u53F3\u4E24\u8FB9\u7684\u7A7A\u683C\u7B56\u7565\u3002\u4EE5 // \u5F00\u5934\u7684\u884C\u4F5C\u4E3A\u6CE8\u91CA" }, userRulesRespectUserDefinedRegexBlocks: { name: "\u81EA\u5B9A\u4E49\u6B63\u5219\u533A\u5757\u540C\u65F6\u963B\u6B62\u7528\u6237\u89C4\u5219", desc: "\u542F\u7528\u540E\uFF0C\u547D\u4E2D\u81EA\u5B9A\u4E49\u6B63\u5219\u533A\u5757\u7684\u6587\u672C\u5C06\u4E0D\u4F1A\u89E6\u53D1\u81EA\u52A8\u7528\u6237\u89C4\u5219\u3002" }, excludeFoldersFiles: { name: "\u6392\u9664\u6587\u4EF6\u5939/\u6587\u4EF6", desc: "\u8BE5\u63D2\u4EF6\u5C06\u6BCF\u884C\u89E3\u6790\u4E3A\u4E00\u4E2A\u6392\u9664\u6587\u4EF6\u5939\u6216\u6587\u4EF6\u3002\u4F8B\u5982\uFF1ADailyNote/, DailyNote/WeekNotes/, DailyNote/test.md" }, fixMacOSContextMenu: { name: "\u4FEE\u590D MacOS \u53F3\u952E\u83DC\u5355\u5149\u6807\u4F4D\u7F6E", desc: "\u4FEE\u590D MacOS \u9F20\u6807\u53F3\u952E\u547C\u51FA\u83DC\u5355\u65F6\u5149\u6807\u8DF3\u5230\u4E0B\u4E00\u884C\u7684\u95EE\u9898 (\u9700\u8981\u91CD\u542F Obsidian \u751F\u6548)" }, fixMicrosoftIME: { name: "\u4FEE\u590D\u5FAE\u8F6F\u8F93\u5165\u6CD5\u95EE\u9898", desc: "\u9002\u914D\u65E7\u7248\u5FAE\u8F6F\u8F93\u5165\u6CD5" }, strictLineBreaks: { name: "\u4E25\u683C\u6362\u884C\u6A21\u5F0F\u56DE\u8F66\u589E\u5F3A", desc: "\u4E25\u683C\u6362\u884C\u7684\u8BBE\u7F6E\u4E0B\uFF0C\u5728\u666E\u901A\u6587\u672C\u884C\u8FDB\u884C\u4E00\u6B21\u56DE\u8F66\u4F1A\u6839\u636E\u6A21\u5F0F\u4EA7\u751F\u4E24\u4E2A\u6362\u884C\u7B26\u6216\u8005\u4E24\u4E2A\u7A7A\u683C\u548C\u56DE\u8F66" }, enhanceModA: { name: "\u589E\u5F3A Ctrl/Cmd+A \u529F\u80FD", desc: "\u7B2C\u4E00\u6B21\u9009\u4E2D\u5F53\u524D\u884C\uFF0C\u7B2C\u4E8C\u6B21\u9009\u4E2D\u5F53\u524D\u6587\u672C\u5757\uFF0C\u7B2C\u4E09\u6B21\u9009\u4E2D\u5168\u6587\u3002" }, collapsePersistentEnter: { name: "\u6298\u53E0\u6807\u9898\u56DE\u8F66\u4E0D\u5C55\u5F00", desc: "\u5728\u6298\u53E0\u7684\u6807\u9898\u884C\u6309\u56DE\u8F66\u65F6\uFF0C\u4E0D\u5C55\u5F00\u6298\u53E0\u5185\u5BB9\uFF0C\u76F4\u63A5\u5728\u4E0B\u65B9\u6DFB\u52A0\u540C\u7EA7\u6807\u9898\u884C" }, printDebugInfo: { name: "\u5728\u63A7\u5236\u53F0\u8F93\u51FA\u8C03\u8BD5\u4FE1\u606F", desc: "\u5728\u63A7\u5236\u53F0\u8F93\u51FA\u8C03\u8BD5\u4FE1\u606F" }, rulesStoragePath: { name: "\u89C4\u5219\u6587\u4EF6\u5B58\u50A8\u8DEF\u5F84", desc: "\u8BBE\u7F6E\u89C4\u5219\u6587\u4EF6\u7684\u5B58\u50A8\u8DEF\u5F84\uFF08\u76F8\u5BF9\u4E8E\u5E93\u6839\u76EE\u5F55\uFF09\uFF0C\u9009\u62E9\u9ED8\u8BA4\u5219\u5B58\u50A8\u5728\u63D2\u4EF6\u76EE\u5F55\u5185", defaultOption: "\u9ED8\u8BA4\uFF08\u63D2\u4EF6\u76EE\u5F55\uFF09", migrateButton: "\u8FC1\u79FB", migrateDesc: "\u5C06\u89C4\u5219\u6587\u4EF6\u4ECE\u4E0A\u6B21\u52A0\u8F7D\u7684\u8DEF\u5F84\u8FC1\u79FB\u5230\u5F53\u524D\u8BBE\u7F6E\u7684\u8DEF\u5F84", migrateSuccess: "\u89C4\u5219\u6587\u4EF6\u8FC1\u79FB\u6210\u529F" }, selectionReplaceRule: { name: "\u9009\u4E2D\u66FF\u6362\u89C4\u5219", desc: "\u7528\u6237\u5B9A\u4E49\u7684\u9009\u62E9\u66FF\u6362\u89C4\u5219" }, deleteRule: { name: "\u5220\u9664\u89C4\u5219", desc: "\u89C4\u5219\uFF1A\u7528 | \u4EE3\u8868\u5149\u6807\u4F4D\u7F6E\uFF0C\u5FC5\u987B\u5305\u542B\u5149\u6807\u3002\u63D0\u793A\uFF1A\u4F7F\u7528 | \u8868\u793A\u5149\u6807\u4F4D\u7F6E\u3002" }, convertRule: { name: "\u8F6C\u6362\u89C4\u5219", desc: "\u89C4\u5219\uFF1A\u7528 | \u4EE3\u8868\u5149\u6807\u4F4D\u7F6E\uFF0C\u5FC5\u987B\u5305\u542B\u5149\u6807\u3002\u63D0\u793A\uFF1A\u4F7F\u7528 | \u8868\u793A\u5149\u6807\u4F4D\u7F6E\u3002" }, trigger: { name: "\u89E6\u53D1\u5668" }, left: { name: "\u5DE6" }, right: { name: "\u53F3" }, oldPattern: { name: "\u65E7\u6A21\u5F0F" }, newPattern: { name: "\u65B0\u6A21\u5F0F" }, ruleEditModal: { addTitle: "\u6DFB\u52A0\u89C4\u5219", editTitle: "\u7F16\u8F91\u89C4\u5219", fieldType: "\u7C7B\u578B", fieldTrigger: "\u5149\u6807\u524D\u5339\u914D", fieldTriggerSelectKey: "\u89E6\u53D1\u6309\u952E\u5B57\u7B26", fieldTriggerRight: "\u5149\u6807\u540E\u5339\u914D", hintTriggerEscape: "\\\\\uFF1A\u53CD\u659C\u6760\uFF0C\\n\uFF1A\u6362\u884C\uFF0C\\t\uFF1A\u5236\u8868\u7B26", fieldReplacement: "\u66FF\u6362\u5185\u5BB9", fieldReplacementDescSelectKey: "${SEL}\uFF1A\u9009\u4E2D\u7684\u6587\u672C\u5185\u5BB9\uFF0C${0:${SEL}}\uFF1A\u5149\u6807\u7EE7\u7EED\u9009\u4E2D\u3002", fieldReplacementDescInputDelete: "[[0]]\uFF1A\u5DE6\u4FA7\u7B2C0\u6355\u83B7\u7EC4\uFF0C[[R1]]\uFF1A\u53F3\u4FA7\u7B2C1\u6355\u83B7\u7EC4\u3002", fieldIsRegex: "\u4F7F\u7528\u6B63\u5219\u8868\u8FBE\u5F0F\u5339\u914D", fieldTriggerMode: "\u89E6\u53D1\u65B9\u5F0F", fieldScope: "\u4F5C\u7528\u57DF", fieldScopeLanguage: "\u8BED\u8A00\uFF08\u53EF\u9009\uFF09", fieldRegexFlags: "\u6B63\u5219\u6807\u5FD7", fieldRegexFlagsDesc: "\u4EC5\u652F\u6301 i / m / u\uFF0C\u4F8B\u5982 im", fieldPriority: "\u4F18\u5148\u7EA7", fieldPriorityDesc: "\u6570\u503C\u8D8A\u5C0F\uFF0C\u4F18\u5148\u7EA7\u8D8A\u9AD8\uFF0C\u9ED8\u8BA4 100", fieldDescription: "\u63CF\u8FF0", buttonSave: "\u4FDD\u5B58", invalidRegex: "\u6B63\u5219\u8868\u8FBE\u5F0F\u65E0\u6548", fieldIsFunction: "\u4F7F\u7528\u51FD\u6570\u5F0F\u66FF\u6362", functionHintInputDelete: "\u53C2\u6570\uFF1AleftMatches (string[])\u3001rightMatches (string[])\u3002\u8FD4\u56DE\u5B57\u7B26\u4E32\u6216 undefined \u8DF3\u8FC7\u3002", functionHintSelectKey: "\u53C2\u6570\uFF1AselectionText (string)\u3001key (string)\u3002\u8FD4\u56DE\u5B57\u7B26\u4E32\u6216 undefined \u8DF3\u8FC7\u3002", hintTabstop: "$0\uFF1A\u5149\u6807\u4F4D\u7F6E\uFF0C$1/$2\uFF1A\u6309 Tab \u8DF3\u8F6C\u7684\u4F4D\u7F6E\uFF0C${1:text}\uFF1A\u8DF3\u8F6C\u5E76\u9009\u4E2D text\u3002", functionPlaceholder: "// \u793A\u4F8B\uFF1A\nconst d = new Date();\nreturn d.toISOString().slice(0,10) + '$0';", groupMatch: "\u5339\u914D\u6761\u4EF6", groupReplacement: "\u66FF\u6362", groupOther: "\u5176\u4ED6" }, ruleType: { input: "\u8F93\u5165", delete: "\u5220\u9664", selectKey: "\u9009\u4E2D\u66FF\u6362" } }, commands: { formatArticle: "\u683C\u5F0F\u5316\u5168\u6587", formatSelection: "\u683C\u5F0F\u5316\u9009\u4E2D\u90E8\u5206/\u5F53\u524D\u884C", deleteBlankLine: "\u522A\u9664\u9009\u4E2D\u90E8\u5206/\u5168\u6587\u7684\u591A\u4F59\u7A7A\u767D\u884C", insertCodeblock: "\u63D2\u5165\u4EE3\u7801\u5757", switchAutoformat: "\u5207\u6362\u81EA\u52A8\u683C\u5F0F\u5316\u5F00\u5173", pasteWithoutFormat: "\u65E0\u683C\u5F0F\u5316\u7C98\u8D34", toggleComment: "\u5207\u6362\u6CE8\u91CA", gotoNewLine: "\u8DF3\u5230\u5F53\u524D\u884C\u540E\u65B0\u884C", selectBlock: "\u9009\u62E9\u5F53\u524D\u6587\u672C\u5757" }, headers: { main: "Obsidian EasyTyping \u63D2\u4EF6", githubDetail: "\u8BE6\u60C5\u89C1 Github\uFF1A", enhancedEditing: "\u589E\u5F3A\u7F16\u8F91\u8BBE\u7F6E", customizeEditRule: "\u81EA\u5B9A\u4E49\u7F16\u8F91\u8F6C\u6362\u89C4\u5219", autoformatSetting: "\u81EA\u52A8\u683C\u5F0F\u5316\u8BBE\u7F6E", detailedSetting: "\u884C\u5185\u5143\u7D20\u95F4\u7A7A\u683C", customRegexpBlock: "\u81EA\u5B9A\u4E49\u6B63\u5219\u533A\u5757", excludeFoldersFiles: "\u6307\u5B9A\u6587\u4EF6\u4E0D\u81EA\u52A8\u683C\u5F0F\u5316", experimentalFeatures: "\u5B9E\u9A8C\u529F\u80FD", languagePairSection: "\u8BED\u8A00\u95F4\u7A7A\u683C\u7B56\u7565", addLanguagePair: "\u6DFB\u52A0\u65B0\u8BED\u8A00/\u7B26\u53F7\u5BF9\uFF1A", prefixDictSection: "\u524D\u7F00\u8BCD\u5178", softSpaceSection: "\u81EA\u5B9A\u4E49\u8F6F\u7A7A\u683C\u7B26\u53F7", customScriptSection: "\u81EA\u5B9A\u4E49\u8BED\u8A00/\u7B26\u53F7\u96C6", spaceStrategyIntro: "\u7A7A\u683C\u7B56\u7565\u8BF4\u660E\uFF1A\n\u65E0\u8981\u6C42\uFF1A\u5BF9\u76F8\u5173\u533A\u5757\u4E0E\u5DE6\u53F3\u6587\u672C\u6CA1\u6709\u7A7A\u683C\u8981\u6C42\u3002\n\u8F6F\u7A7A\u683C\uFF1A\u5BF9\u76F8\u5173\u533A\u5757\u4E0E\u5468\u56F4\u533A\u5757\u53EA\u8981\u6C42\u6709\u8F6F\u7A7A\u683C\uFF08\u4F8B\u5982\u5F53\u524D\u5757\u5DE6\u53F3\u4E34\u8FD1\u6587\u672C\u4E3A\u6807\u70B9\u7B26\u53F7\u65F6\uFF0C\u4E0D\u9700\u8981\u518D\u63D2\u5165\u771F\u5B9E\u7A7A\u683C\uFF09\u3002\n\u4E25\u683C\u7A7A\u683C\uFF1A\u5F53\u524D\u5757\u4E0E\u4E34\u8FD1\u6587\u672C\u4E4B\u95F4\u4E25\u683C\u6DFB\u52A0\u771F\u5B9E\u7A7A\u683C\u3002", aboutRegexp: { header: "\u6B63\u5219\u8868\u8FBE\u5F0F\u76F8\u5173\u77E5\u8BC6\uFF0C\u89C1 ", text: "\u300A\u962E\u4E00\u5CF0\uFF1A\u6B63\u5219\u8868\u8FBE\u5F0F\u7B80\u660E\u6559\u7A0B\u300B" }, customizeSelectionRule: "\u81EA\u5B9A\u4E49\u9009\u4E2D\u6587\u672C\u7F16\u8F91\u589E\u5F3A\u89C4\u5219", customizeDeleteRule: "\u81EA\u5B9A\u4E49\u5220\u9664\u7F16\u8F91\u589E\u5F3A\u89C4\u5219", customizeConvertRule: "\u81EA\u5B9A\u4E49\u7F16\u8F91\u8F6C\u6362\u89C4\u5219", editSelectionReplaceRule: "\u7F16\u8F91\u9009\u4E2D\u66FF\u6362\u89C4\u5219", builtinRulesSection: "\u5185\u7F6E\u89C4\u5219", userRulesSection: "\u7528\u6237\u89C4\u5219", deletedRulesSection: "\u5DF2\u5220\u9664\u7684\u5185\u7F6E\u89C4\u5219", tabs: { editEnhance: "\u7F16\u8F91\u589E\u5F3A", autoFormat: "\u81EA\u52A8\u683C\u5F0F\u5316", builtinRules: "\u5185\u7F6E\u89C4\u5219", userRules: "\u81EA\u5B9A\u4E49\u89C4\u5219", other: "\u5176\u4ED6\u8BBE\u7F6E" } }, dropdownOptions: { enterTwice: "\u4E24\u6B21\u56DE\u8F66", twoSpace: "\u52A0\u4E24\u4E2A\u7A7A\u683C", mixMode: "\u6DF7\u5408\u6A21\u5F0F", noRequire: "\u65E0\u8981\u6C42", softSpace: "\u8F6F\u7A7A\u683C", strictSpace: "\u4E25\u683C\u7A7A\u683C", dummy: "\u5446\u7A7A\u683C", smart: "\u667A\u80FD\u7A7A\u683C", scopeAll: "\u5168\u90E8", scopeText: "\u6587\u672C", scopeFormula: "\u516C\u5F0F", scopeCode: "\u4EE3\u7801", triggerModeAuto: "\u81EA\u52A8", triggerModeTab: "Tab \u952E", ruleTypeInput: "\u8F93\u5165", ruleTypeDelete: "\u5220\u9664", ruleTypeSelectKey: "\u9009\u4E2D\u66FF\u6362" }, toolTip: { switch: "\u529F\u80FD\u5F00\u5173", editRule: "\u7F16\u8F91\u89C4\u5219", removeRule: "\u5220\u9664\u89C4\u5219", addRule: "\u6DFB\u52A0\u89C4\u5219", enableRule: "\u542F\u7528/\u7981\u7528\u89C4\u5219", restoreRule: "\u6062\u590D\u6B64\u89C4\u5219", resetAllRules: "\u91CD\u7F6E\u5185\u7F6E\u89C4\u5219", resetSuccess: "\u5185\u7F6E\u89C4\u5219\u5DF2\u91CD\u7F6E", exportRules: "\u5BFC\u51FA\u89C4\u5219", importRules: "\u5BFC\u5165\u89C4\u5219", noRulesToExport: "\u6CA1\u6709\u53EF\u5BFC\u51FA\u7684\u7528\u6237\u89C4\u5219", importSuccess: "\u5BFC\u5165\u4E86 %d \u6761\u89C4\u5219\uFF0C\u8DF3\u8FC7 %d \u6761\u91CD\u590D\u89C4\u5219", importInvalidJson: "\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1A\u4E0D\u662F\u6709\u6548\u7684 JSON", importNoRules: "\u6587\u4EF6\u4E2D\u6CA1\u6709\u53EF\u5BFC\u5165\u7684\u89C4\u5219" }, placeHolder: { triggerSymbol: "\u89E6\u53D1\u7B26", newLeftSideString: "\u5DE6\u8FB9\u7B26\u53F7", newRightSideString: "\u53F3\u8FB9\u7B26\u53F7", addRule: "\u6DFB\u52A0\u89C4\u5219", noticeInvaidTrigger: "\u65E0\u6548\u7684\u89E6\u53D1\u7B26, \u89E6\u53D1\u7B26\u5FC5\u987B\u662F\u5355\u5B57\u7B26\u6216\u8005\u662F \u2014\u2014\u3001\u2026\u2026", noticeWarnTriggerExists: "\u65E0\u6548\u89C4\u5219! \u89E6\u53D1\u7B26 %s \u5DF2\u5B58\u5728", noticeMissingInput: "missing input", beforeDelete: "\u5220\u9664\u524D|", newPattern: "\u89E6\u53D1\u89C4\u5219\u540E\u5B57\u7B26\u4E32\u6A21\u5F0F", noticeInvaidTriggerPatternContainSymbol: "\u65E0\u6548\u89C4\u5219, \u8F6C\u6362\u524D\u6A21\u5F0F\u5FC5\u987B\u5305\u542B\u4EE3\u8868\u5149\u6807\u4F4D\u7F6E\u7684\u7B26\u53F7 |", beforeConvert: "\u8F6C\u6362\u524D|", noticeInvalidPatternString: "Invalid pattern string!" }, button: { update: "\u66F4\u65B0" }, scriptCategoryLabels: { chinese: "\u4E2D\u6587", japanese: "\u65E5\u6587", korean: "\u97E9\u6587", cjk: "\u4E2D\u65E5\u97E9", english: "\u82F1\u6587", digit: "\u6570\u5B57", russian: "\u4FC4\u6587", unknown: "\u672A\u77E5" }, builtinRuleDescriptions: { "builtin-autopair-input": "\u8F93\u5165\u5168\u89D2\u62EC\u53F7/\u5F15\u53F7\u65F6\u81EA\u52A8\u8865\u5168\u914D\u5BF9", "builtin-autopair-jump": "\u8F93\u5165\u53F3\u4FA7\u914D\u5BF9\u7B26\u53F7\u65F6\u81EA\u52A8\u8DF3\u8FC7\uFF0C\u907F\u514D\u91CD\u590D\u63D2\u5165", "builtin-autopair-delete": "\u5220\u9664\u5168\u89D2\u62EC\u53F7/\u5F15\u53F7\u65F6\u540C\u65F6\u5220\u9664\u914D\u5BF9", "builtin-conv-backtick": "\u8FDE\u7EED\u4E2D\u6587\u95F4\u9694\u53F7 \xB7\xB7 \u8F6C\u884C\u5185\u4EE3\u7801", "builtin-conv-codeblock": "\u884C\u5185\u4EE3\u7801\u4E2D\u7EE7\u7EED\u8F93\u5165 \xB7 \u5347\u7EA7\u4E3A\u4EE3\u7801\u5757", "builtin-conv-formula": "\uFFE5/$ \u7B26\u53F7\u7EC4\u5408\u8F6C\u884C\u5185\u6216\u5757\u7EA7\u516C\u5F0F", "builtin-conv-linestart": "\u884C\u9996 \u300B \u8F6C\u5F15\u7528\u6807\u8BB0\u3001\u884C\u9996 \u3001 \u8F6C\u659C\u6760", "builtin-conv-hw2fw": "CJK\u5B57\u7B26\u540E\u534A\u89D2\u6807\u70B9\u8F6C\u5168\u89D2", "builtin-fw2hw-double": "\u8FDE\u7EED\u8F93\u5165\u4E24\u4E2A\u76F8\u540C\u5168\u89D2\u6807\u70B9\u8F6C\u5BF9\u5E94\u534A\u89D2", "builtin-del-inline-formula": "\u5220\u9664\u884C\u5185\u516C\u5F0F $...$ \u914D\u5BF9", "builtin-del-highlight": "\u5220\u9664\u9AD8\u4EAE ==...== \u914D\u5BF9", "builtin-del-block-formula": "\u5220\u9664\u5757\u7EA7\u516C\u5F0F $$...$$ \u914D\u5BF9", "builtin-del-codeblock": "\u5FEB\u901F\u5220\u9664\u7A7A\u4EE3\u7801\u5757", "builtin-del-wikilink": "\u5FEB\u901F\u5220\u9664\u53CC\u94FE\u53CA\u5D4C\u5165\uFF08![[]]\uFF09", "builtin-sel-wrap-symbols": "\u9009\u4E2D\u6587\u5B57\u540E\u8F93\u5165 \u3010/\xA5/\uFFE5 \u5305\u88F9\u4E3A []/$$", "builtin-sel-wrap-backtick": "\u9009\u4E2D\u6587\u5B57\u540E\u8F93\u5165 \xB7 \u5305\u88F9\u4E3A\u884C\u5185\u4EE3\u7801", "builtin-sel-wrap-quotes": "\u9009\u4E2D\u6587\u5B57\u540E\u8F93\u5165\u5168\u89D2\u5F15\u53F7\uFF0C\u914D\u5BF9\u5F15\u53F7\u5305\u88F9", "builtin-sel-wrap-cjk-brackets": "\u9009\u4E2D\u6587\u5B57\u540E\u8F93\u5165\u300A\uFF08\uFF0C\u914D\u5BF9\u62EC\u53F7\u5305\u88F9", "builtin-quote-convert": "\u8F93\u5165 > \u6216 \u300B \u8F6C\u4E3A Markdown \u5F15\u7528\u6807\u8BB0", "builtin-quote-space": "\u5F15\u7528\u6807\u8BB0 > \u540E\u81EA\u52A8\u8865\u7A7A\u683C" } }; var zh_CN_default = locale2; // src/lang/locale/zh-TW.ts var locale3 = { settings: { smartPaste: { name: "\u667A\u6167\u7C98\u8CBC", desc: "\u5728\u5217\u8868\u6216\u5F15\u7528\u584A\u4E2D\u7C98\u8CBC\u6642\uFF0C\u81EA\u52D5\u6DFB\u52A0\u7E2E\u9032\u548C\u5217\u8868/\u5F15\u7528\u7B26\u865F" }, codeblockEdit: { name: "\u589E\u5F3A\u4EE3\u78BC\u584A\u7DE8\u8F2F", desc: "\u589E\u5F3A\u4EE3\u78BC\u584A\u5167\u7684\u7DE8\u8F2F\uFF08Cmd/Ctrl+A \u9078\u4E2D\u3001Tab\u3001\u522A\u9664\u3001\u7C98\u8CBC\uFF09" }, backspaceEdit: { name: "\u667A\u6167\u9000\u683C\u9375", desc: "\u589E\u5F37\u522A\u9664\u7A7A\u5217\u8868\u9805\u6216\u7A7A\u5F15\u7528\u884C\u7684\u529F\u80FD" }, tabOut: { name: "Tab \u8DF3\u51FA\u914D\u5C0D\u7B26\u865F", desc: "\u6309 Tab \u9375\u8DF3\u51FA\u914D\u5C0D\u7B26\u865F\uFF0C\u5982\u3010\u3011\u3001\uFF08\uFF09\u3001\u300A\u300B\u3001\u5F15\u865F\u3001\u884C\u5167\u4EE3\u78BC\u7B49" }, autoFormatting: { name: "\u8F38\u5165\u6642\u81EA\u52D5\u683C\u5F0F\u5316", desc: "\u662F\u5426\u5728\u7DE8\u8F2F\u6587\u6A94\u6642\u81EA\u52D5\u683C\u5F0F\u5316\u6587\u672C\uFF0C\u81EA\u52D5\u683C\u5F0F\u5316\u7684\u7E3D\u958B\u95DC" }, autoFormatPaste: { name: "\u7C98\u8CBC\u6642\u81EA\u52D5\u683C\u5F0F\u5316", desc: "\u7C98\u8CBC\u6642\u662F\u5426\u81EA\u52D5\u683C\u5F0F\u5316\uFF0CCMD/CTRL+SHIFT+V \u7121\u683C\u5F0F\u7C98\u8CBC\u6642\u4E0D\u89F8\u767C\u3002" }, languagePairSpacing: { name: "\u8A9E\u8A00\u9593\u7A7A\u683C\u7B56\u7565", desc: "\u5B9A\u7FA9\u4E0D\u540C\u8A9E\u8A00/\u7B26\u865F\u985E\u578B\u4E4B\u9593\u662F\u5426\u81EA\u52D5\u6DFB\u52A0\u7A7A\u683C" }, prefixDictionary: { name: "\u524D\u7DB4\u8A5E\u5178", desc: "\u7528\u9017\u865F\u3001\u7A7A\u683C\u6216\u63DB\u884C\u5206\u9694\uFF0C\u652F\u63F4\u8A5E\u6216 /\u6B63\u5247/\u3002\u5339\u914D\u7684 token \u4E0D\u6703\u88AB\u63D2\u5165\u7A7A\u683C\uFF0C\u6B63\u5728\u8F38\u5165\u7684\u524D\u7DB4\u4E5F\u6703\u66AB\u4E0D\u63D2\u5165\u7A7A\u683C" }, softSpaceSymbols: { leftName: "\u81EA\u5B9A\u7FA9\u5DE6\u5074\u8EDF\u7A7A\u683C\u984D\u5916\u7B26\u865F", leftDesc: `\u5E38\u898B\u7684\u5168\u89D2\u6A19\u9EDE\u3001\u82F1\u6587\u5F15\u865F\uFF08' "\uFF09\u548C\u5DE6\u62EC\u865F\uFF08[ ( {\uFF09\u5DF2\u5167\u7F6E\u652F\u6301\u3002\u5728\u6B64\u6DFB\u52A0\u984D\u5916\u7684\u5DE6\u5074\u7B26\u865F\uFF08\u5982 -\uFF09`, rightName: "\u81EA\u5B9A\u7FA9\u53F3\u5074\u8EDF\u7A7A\u683C\u984D\u5916\u7B26\u865F", rightDesc: `\u5E38\u898B\u7684\u5168\u89D2\u6A19\u9EDE\u3001\u82F1\u6587\u5F15\u865F\uFF08' "\uFF09\u3001\u53F3\u62EC\u865F\uFF08] ) }\uFF09\u4EE5\u53CA\u82F1\u6587\u534A\u89D2\u6A19\u9EDE\uFF08. , ? ! : ;\uFF09\u5DF2\u5167\u7F6E\u70BA\u53F3\u5074\u8EDF\u7A7A\u683C\u7B26\u865F\u3002\u5728\u6B64\u6DFB\u52A0\u984D\u5916\u7684\u53F3\u5074\u7B26\u865F\uFF08\u5982 -\uFF09` }, customScriptCategories: { name: "\u81EA\u5B9A\u7FA9\u8A9E\u8A00/\u7B26\u865F\u96C6", desc: "\u6DFB\u52A0\u81EA\u5B9A\u7FA9\u8A9E\u8A00\u6216\u7B26\u865F\u96C6\u7528\u65BC\u7A7A\u683C\u7B56\u7565", namePlaceholder: "\u540D\u7A31", patternPlaceholder: "\u5B57\u5143\u985E\u6A21\u5F0F" }, capitalizeFirstLetter: { name: "\u53E5\u9996\u5B57\u6BCD\u5927\u5BEB", desc: "\u82F1\u6587\u6BCF\u500B\u53E5\u9996\u5B57\u6BCD\u5927\u5BEB\uFF0C\u53EF\u53D6\u6D88" }, textPunctuationSpace: { name: "\u6587\u672C\u548C\u6A19\u9EDE\u9593\u7A7A\u683C", desc: "\u5728\u6587\u672C\u548C\u6A19\u9EDE\u4E4B\u9593\u667A\u80FD\u63D2\u5165\u7A7A\u683C" }, spaceStrategyInlineCode: { name: "\u884C\u5167\u4EE3\u78BC\u548C\u6587\u672C\u4E4B\u9593\u7684\u7A7A\u683C\u7B56\u7565", desc: "\u5B9A\u7FA9\u884C\u5167\u4EE3\u78BC\u548C\u6587\u672C\u4E4B\u9593\u7684\u7A7A\u683C\u7B56\u7565" }, spaceStrategyInlineFormula: { name: "\u884C\u5167\u516C\u5F0F\u548C\u6587\u672C\u4E4B\u9593\u7684\u7A7A\u683C\u7B56\u7565", desc: "\u5B9A\u7FA9\u884C\u5167\u516C\u5F0F\u548C\u6587\u672C\u4E4B\u9593\u7684\u7A7A\u683C\u7B56\u7565" }, spaceStrategyLinkText: { name: "\u9023\u7D50\u548C\u6587\u672C\u4E4B\u9593\u7684\u7A7A\u683C\u7B56\u7565", desc: "\u5B9A\u7FA9 [[wikilink]] [mdlink](...) \u548C\u6587\u672C\u4E4B\u9593\u7684\u7A7A\u683C\u7B56\u7565" }, userDefinedRegexpSwitch: { name: "\u7528\u6236\u5B9A\u7FA9\u7684\u6B63\u5247\u8868\u9054\u5F0F\u958B\u95DC", desc: "\u81EA\u5B9A\u7FA9\u6B63\u5247\u8868\u9054\u5F0F\u958B\u95DC\uFF0C\u5339\u914D\u5230\u7684\u5167\u5BB9\u4E0D\u9032\u884C\u683C\u5F0F\u5316\uFF0C\u4E14\u53EF\u4EE5\u8A2D\u7F6E\u5339\u914D\u5230\u7684\u5167\u5BB9\u584A\u8207\u5176\u4ED6\u5167\u5BB9\u4E4B\u9593\u7684\u7A7A\u683C\u7B56\u7565" }, userDefinedRegexp: { name: "\u7528\u6236\u5B9A\u7FA9\u7684\u6B63\u5247\u8868\u9054\u5F0F", desc: "\u7528\u6236\u81EA\u5B9A\u7FA9\u6B63\u5247\u8868\u9054\u5F0F\uFF0C\u5339\u914D\u5230\u7684\u5167\u5BB9\u4E0D\u9032\u884C\u683C\u5F0F\u5316\uFF0C\u6BCF\u884C\u4E00\u500B\u8868\u9054\u5F0F\uFF0C\u884C\u5C3E\u4E0D\u8981\u96A8\u610F\u52A0\u7A7A\u683C\u3002\u6BCF\u884C\u672B\u5C3E3\u500B\u5B57\u7B26\u7684\u56FA\u5B9A\u70BA|\u548C\u5169\u500B\u7A7A\u683C\u7B56\u7565\u7B26\u865F\uFF0C\u7A7A\u683C\u7B56\u7565\u7B26\u865F\u70BA-=+\uFF0C\u5206\u5225\u4EE3\u8868\u4E0D\u8981\u6C42\u7A7A\u683C(-)\uFF0C\u8EDF\u7A7A\u683C(=)\uFF0C\u56B4\u683C\u7A7A\u683C(+)\u3002\u9019\u5169\u500B\u7A7A\u683C\u7B56\u7565\u7B26\u865F\u5206\u5225\u70BA\u5339\u914D\u5340\u584A\u7684\u5DE6\u53F3\u5169\u908A\u7684\u7A7A\u683C\u7B56\u7565\u3002\u4EE5 // \u958B\u982D\u7684\u884C\u4F5C\u70BA\u8A3B\u91CB" }, userRulesRespectUserDefinedRegexBlocks: { name: "\u81EA\u5B9A\u7FA9\u6B63\u5247\u5340\u584A\u540C\u6642\u963B\u6B62\u7528\u6236\u898F\u5247", desc: "\u555F\u7528\u5F8C\uFF0C\u547D\u4E2D\u81EA\u5B9A\u7FA9\u6B63\u5247\u5340\u584A\u7684\u6587\u672C\u5C07\u4E0D\u6703\u89F8\u767C\u81EA\u52D5\u7528\u6236\u898F\u5247\u3002" }, excludeFoldersFiles: { name: "\u6392\u9664\u6587\u4EF6\u593E/\u6587\u4EF6", desc: "\u8A72\u63D2\u4EF6\u5C07\u6BCF\u884C\u89E3\u6790\u70BA\u4E00\u500B\u6392\u9664\u6587\u4EF6\u593E\u6216\u6587\u4EF6\u3002\u4F8B\u5982\uFF1ADailyNote/, DailyNote/WeekNotes/, DailyNote/test.md" }, fixMacOSContextMenu: { name: "\u4FEE\u5FA9 MacOS \u53F3\u9375\u83DC\u55AE\u5149\u6A19\u4F4D\u7F6E", desc: "\u4FEE\u5FA9 MacOS \u9F20\u6A19\u53F3\u9375\u547C\u51FA\u83DC\u55AE\u6642\u5149\u6A19\u8DF3\u5230\u4E0B\u4E00\u884C\u7684\u554F\u984C (\u9700\u8981\u91CD\u555F Obsidian \u751F\u6548)" }, fixMicrosoftIME: { name: "\u4FEE\u5FA9\u5FAE\u8EDF\u8F38\u5165\u6CD5\u554F\u984C", desc: "\u9069\u914D\u820A\u7248\u5FAE\u8EDF\u8F38\u5165\u6CD5" }, strictLineBreaks: { name: "\u56B4\u683C\u63DB\u884C\u6A21\u5F0F\u56DE\u8ECA\u589E\u5F37", desc: "\u56B4\u683C\u63DB\u884C\u7684\u8A2D\u7F6E\u4E0B\uFF0C\u5728\u666E\u901A\u6587\u672C\u884C\u9032\u884C\u4E00\u6B21\u56DE\u8ECA\u6703\u6839\u64DA\u6A21\u5F0F\u7522\u751F\u5169\u500B\u63DB\u884C\u7B26\u6216\u8005\u5169\u500B\u7A7A\u683C\u548C\u56DE\u8ECA" }, enhanceModA: { name: "\u589E\u5F37 Mod+A \u529F\u80FD", desc: "\u7B2C\u4E00\u6B21\u9078\u4E2D\u7576\u524D\u884C\uFF0C\u7B2C\u4E8C\u6B21\u9078\u4E2D\u7576\u524D\u6587\u672C\u584A\uFF0C\u7B2C\u4E09\u6B21\u9078\u4E2D\u5168\u6587\u3002" }, collapsePersistentEnter: { name: "\u6298\u758A\u6A19\u984C\u56DE\u8ECA\u4E0D\u5C55\u958B", desc: "\u5728\u6298\u758A\u7684\u6A19\u984C\u884C\u6309\u56DE\u8ECA\u6642\uFF0C\u4E0D\u5C55\u958B\u6298\u758A\u5167\u5BB9\uFF0C\u76F4\u63A5\u5728\u4E0B\u65B9\u6DFB\u52A0\u540C\u7D1A\u6A19\u984C\u884C" }, printDebugInfo: { name: "\u5728\u63A7\u5236\u53F0\u8F38\u51FA\u8ABF\u8A66\u8CC7\u8A0A", desc: "\u5728\u63A7\u5236\u53F0\u8F38\u51FA\u8ABF\u8A66\u8CC7\u8A0A" }, rulesStoragePath: { name: "\u898F\u5247\u6A94\u6848\u5132\u5B58\u8DEF\u5F91", desc: "\u8A2D\u5B9A\u898F\u5247\u6A94\u6848\u7684\u5132\u5B58\u8DEF\u5F91\uFF08\u76F8\u5C0D\u65BC\u5EAB\u6839\u76EE\u9304\uFF09\uFF0C\u9078\u64C7\u9810\u8A2D\u5247\u5132\u5B58\u5728\u5916\u639B\u76EE\u9304\u5167", defaultOption: "\u9810\u8A2D\uFF08\u5916\u639B\u76EE\u9304\uFF09", migrateButton: "\u9077\u79FB", migrateDesc: "\u5C07\u898F\u5247\u6A94\u6848\u5F9E\u4E0A\u6B21\u8F09\u5165\u7684\u8DEF\u5F91\u9077\u79FB\u5230\u7576\u524D\u8A2D\u5B9A\u7684\u8DEF\u5F91", migrateSuccess: "\u898F\u5247\u6A94\u6848\u9077\u79FB\u6210\u529F" }, selectionReplaceRule: { name: "\u9078\u4E2D\u66FF\u63DB\u898F\u5247", desc: "\u7528\u6236\u5B9A\u7FA9\u7684\u9078\u4E2D\u66FF\u63DB\u898F\u5247" }, deleteRule: { name: "\u522A\u9664\u898F\u5247", desc: "\u898F\u5247\uFF1A\u7528 | \u4EE3\u8868\u5149\u6A19\u4F4D\u7F6E\uFF0C\u5FC5\u9808\u5305\u542B\u5149\u6A19\u3002\u63D0\u793A\uFF1A\u4F7F\u7528 | \u8868\u793A\u5149\u6A19\u4F4D\u7F6E\u3002" }, convertRule: { name: "\u8F49\u63DB\u898F\u5247", desc: "\u898F\u5247\uFF1A\u7528 | \u4EE3\u8868\u5149\u6A19\u4F4D\u7F6E\uFF0C\u5FC5\u9808\u5305\u542B\u5149\u6A19\u3002\u63D0\u793A\uFF1A\u4F7F\u7528 | \u8868\u793A\u5149\u6A19\u4F4D\u7F6E\u3002" }, trigger: { name: "\u89F8\u767C\u5668" }, left: { name: "\u5DE6" }, right: { name: "\u53F3" }, oldPattern: { name: "\u820A\u6A21\u5F0F" }, newPattern: { name: "\u65B0\u6A21\u5F0F" }, ruleEditModal: { addTitle: "\u65B0\u589E\u898F\u5247", editTitle: "\u7DE8\u8F2F\u898F\u5247", fieldType: "\u985E\u578B", fieldTrigger: "\u6E38\u6A19\u524D\u5339\u914D", fieldTriggerSelectKey: "\u89F8\u767C\u6309\u9375\u5B57\u7B26", fieldTriggerRight: "\u6E38\u6A19\u5F8C\u5339\u914D", hintTriggerEscape: "\\\\\uFF1A\u53CD\u659C\u7DDA\uFF0C\\n\uFF1A\u63DB\u884C\uFF0C\\t\uFF1A\u5236\u8868\u7B26", fieldReplacement: "\u66FF\u63DB\u5167\u5BB9", fieldReplacementDescSelectKey: "${SEL}\uFF1A\u9078\u4E2D\u7684\u6587\u672C\u5167\u5BB9\uFF0C${0:${SEL}}\uFF1A\u6E38\u6A19\u7E7C\u7E8C\u9078\u4E2D\u3002", fieldReplacementDescInputDelete: "[[0]]\uFF1A\u5DE6\u5074\u7B2C0\u6355\u7372\u7D44\uFF0C[[R1]]\uFF1A\u53F3\u5074\u7B2C1\u6355\u7372\u7D44\u3002", fieldIsRegex: "\u4F7F\u7528\u6B63\u5247\u8868\u9054\u5F0F\u5339\u914D", fieldTriggerMode: "\u89F8\u767C\u65B9\u5F0F", fieldScope: "\u4F5C\u7528\u57DF", fieldScopeLanguage: "\u8A9E\u8A00\uFF08\u53EF\u9078\uFF09", fieldRegexFlags: "\u6B63\u5247\u6A19\u8A8C", fieldRegexFlagsDesc: "\u50C5\u652F\u63F4 i / m / u\uFF0C\u4F8B\u5982 im", fieldPriority: "\u512A\u5148\u7D1A", fieldPriorityDesc: "\u6578\u503C\u8D8A\u5C0F\uFF0C\u512A\u5148\u7D1A\u8D8A\u9AD8\uFF0C\u9810\u8A2D 100", fieldDescription: "\u63CF\u8FF0", buttonSave: "\u5132\u5B58", invalidRegex: "\u6B63\u898F\u8868\u9054\u5F0F\u7121\u6548", fieldIsFunction: "\u4F7F\u7528\u51FD\u5F0F\u66FF\u63DB", functionHintInputDelete: "\u53C3\u6578\uFF1AleftMatches (string[])\u3001rightMatches (string[])\u3002\u56DE\u50B3\u5B57\u4E32\u6216 undefined \u8DF3\u904E\u3002", functionHintSelectKey: "\u53C3\u6578\uFF1AselectionText (string)\u3001key (string)\u3002\u56DE\u50B3\u5B57\u4E32\u6216 undefined \u8DF3\u904E\u3002", hintTabstop: "$0\uFF1A\u6E38\u6A19\u4F4D\u7F6E\uFF0C$1/$2\uFF1A\u6309 Tab \u8DF3\u8F49\u7684\u4F4D\u7F6E\uFF0C${1:text}\uFF1A\u8DF3\u8F49\u4E26\u9078\u4E2D text\u3002", functionPlaceholder: "// \u7BC4\u4F8B\uFF1A\nconst d = new Date();\nreturn d.toISOString().slice(0,10) + '$0';", groupMatch: "\u5339\u914D\u689D\u4EF6", groupReplacement: "\u66FF\u63DB", groupOther: "\u5176\u4ED6" }, ruleType: { input: "\u8F38\u5165", delete: "\u522A\u9664", selectKey: "\u9078\u4E2D\u66FF\u63DB" } }, commands: { formatArticle: "\u683C\u5F0F\u5316\u5168\u6587", formatSelection: "\u683C\u5F0F\u5316\u9078\u4E2D\u90E8\u5206/\u7576\u524D\u884C", deleteBlankLine: "\u522A\u9664\u9078\u4E2D\u90E8\u5206/\u5168\u6587\u7684\u591A\u9918\u7A7A\u767D\u884C", insertCodeblock: "\u63D2\u5165\u4EE3\u78BC\u584A", switchAutoformat: "\u5207\u63DB\u81EA\u52D5\u683C\u5F0F\u5316\u958B\u95DC", pasteWithoutFormat: "\u7121\u683C\u5F0F\u5316\u7C98\u8CBC", toggleComment: "\u5207\u63DB\u8A3B\u91CB", gotoNewLine: "\u8DF3\u5230\u7576\u524D\u884C\u5F8C\u7684\u65B0\u884C", selectBlock: "\u9078\u64C7\u7576\u524D\u6587\u672C\u584A" }, headers: { main: "Obsidian EasyTyping \u63D2\u4EF6", githubDetail: "\u8A73\u60C5\u898B Github\uFF1A", enhancedEditing: "\u589E\u5F37\u7DE8\u8F2F\u8A2D\u7F6E", customizeEditRule: "\u81EA\u5B9A\u7FA9\u7DE8\u8F2F\u8F49\u63DB\u898F\u5247", autoformatSetting: "\u81EA\u52D5\u683C\u5F0F\u5316\u8A2D\u7F6E", detailedSetting: "\u884C\u5167\u5143\u7D20\u9593\u7A7A\u683C", customRegexpBlock: "\u81EA\u5B9A\u7FA9\u6B63\u5247\u5340\u584A", excludeFoldersFiles: "\u6307\u5B9A\u6587\u4EF6\u4E0D\u81EA\u52D5\u683C\u5F0F\u5316", experimentalFeatures: "\u5BE6\u9A57\u529F\u80FD", languagePairSection: "\u8A9E\u8A00\u9593\u7A7A\u683C\u7B56\u7565", addLanguagePair: "\u65B0\u589E\u8A9E\u8A00/\u7B26\u865F\u5C0D\uFF1A", prefixDictSection: "\u524D\u7DB4\u8A5E\u5178", softSpaceSection: "\u81EA\u5B9A\u7FA9\u8EDF\u7A7A\u683C\u7B26\u865F", customScriptSection: "\u81EA\u5B9A\u7FA9\u8A9E\u8A00/\u7B26\u865F\u96C6", spaceStrategyIntro: "\u7A7A\u683C\u7B56\u7565\u8AAA\u660E\uFF1A\n\u7121\u8981\u6C42\uFF1A\u5C0D\u76F8\u95DC\u5340\u584A\u8207\u5DE6\u53F3\u6587\u672C\u6C92\u6709\u7A7A\u683C\u8981\u6C42\u3002\n\u8EDF\u7A7A\u683C\uFF1A\u5C0D\u76F8\u95DC\u5340\u584A\u8207\u5468\u570D\u5340\u584A\u53EA\u8981\u6C42\u6709\u8EDF\u7A7A\u683C\uFF08\u4F8B\u5982\u7576\u524D\u584A\u5DE6\u53F3\u81E8\u8FD1\u6587\u672C\u70BA\u6A19\u9EDE\u7B26\u865F\u6642\uFF0C\u4E0D\u9700\u8981\u518D\u63D2\u5165\u771F\u5BE6\u7A7A\u683C\uFF09\u3002\n\u56B4\u683C\u7A7A\u683C\uFF1A\u7576\u524D\u584A\u8207\u81E8\u8FD1\u6587\u672C\u4E4B\u9593\u56B4\u683C\u6DFB\u52A0\u771F\u5BE6\u7A7A\u683C\u3002", aboutRegexp: { header: "\u6B63\u5247\u8868\u9054\u5F0F\u76F8\u95DC\u77E5\u8B58\uFF0C\u898B ", text: "\u300A\u962E\u4E00\u5CF0\uFF1A\u6B63\u5247\u8868\u9054\u5F0F\u7C21\u660E\u6559\u7A0B\u300B" }, customizeSelectionRule: "\u81EA\u5B9A\u7FA9\u9078\u4E2D\u6587\u672C\u7DE8\u8F2F\u589E\u5F3A\u898F\u5247", customizeDeleteRule: "\u81EA\u5B9A\u7FA9\u522A\u9664\u7DE8\u8F2F\u589E\u5F3A\u898F\u5247", customizeConvertRule: "\u81EA\u5B9A\u7FA9\u7DE8\u8F2F\u8F49\u63DB\u898F\u5247", editSelectionReplaceRule: "\u7DE8\u8F2F\u9078\u4E2D\u66FF\u63DB\u898F\u5247", builtinRulesSection: "\u5167\u5EFA\u898F\u5247", userRulesSection: "\u4F7F\u7528\u8005\u898F\u5247", deletedRulesSection: "\u5DF2\u522A\u9664\u7684\u5167\u5EFA\u898F\u5247", tabs: { editEnhance: "\u7DE8\u8F2F\u589E\u5F37", autoFormat: "\u81EA\u52D5\u683C\u5F0F\u5316", builtinRules: "\u5167\u5EFA\u898F\u5247", userRules: "\u81EA\u8A02\u898F\u5247", other: "\u5176\u4ED6\u8A2D\u5B9A" } }, dropdownOptions: { enterTwice: "\u5169\u6B21\u56DE\u8ECA", twoSpace: "\u52A0\u5169\u500B\u7A7A\u683C", mixMode: "\u6DF7\u5408\u6A21\u5F0F", noRequire: "\u7121\u8981\u6C42", softSpace: "\u8EDF\u7A7A\u683C", strictSpace: "\u56B4\u683C\u7A7A\u683C", dummy: "\u5446\u7A7A\u683C", smart: "\u667A\u80FD\u7A7A\u683C", scopeAll: "\u5168\u90E8", scopeText: "\u6587\u672C", scopeFormula: "\u516C\u5F0F", scopeCode: "\u7A0B\u5F0F\u78BC", triggerModeAuto: "\u81EA\u52D5", triggerModeTab: "Tab \u9375", ruleTypeInput: "\u8F38\u5165", ruleTypeDelete: "\u522A\u9664", ruleTypeSelectKey: "\u9078\u4E2D\u66FF\u63DB" }, toolTip: { switch: "\u529F\u80FD\u958B\u95DC", editRule: "\u7DE8\u8F2F\u898F\u5247", removeRule: "\u522A\u9664\u898F\u5247", addRule: "\u6DFB\u52A0\u898F\u5247", enableRule: "\u555F\u7528/\u505C\u7528\u898F\u5247", restoreRule: "\u6062\u5FA9\u6B64\u898F\u5247", resetAllRules: "\u91CD\u7F6E\u5167\u5EFA\u898F\u5247", resetSuccess: "\u5167\u5EFA\u898F\u5247\u5DF2\u91CD\u7F6E", exportRules: "\u532F\u51FA\u898F\u5247", importRules: "\u532F\u5165\u898F\u5247", noRulesToExport: "\u6C92\u6709\u53EF\u532F\u51FA\u7684\u4F7F\u7528\u8005\u898F\u5247", importSuccess: "\u532F\u5165\u4E86 %d \u689D\u898F\u5247\uFF0C\u8DF3\u904E %d \u689D\u91CD\u8907\u898F\u5247", importInvalidJson: "\u6A94\u6848\u683C\u5F0F\u932F\u8AA4\uFF1A\u4E0D\u662F\u6709\u6548\u7684 JSON", importNoRules: "\u6A94\u6848\u4E2D\u6C92\u6709\u53EF\u532F\u5165\u7684\u898F\u5247" }, placeHolder: { triggerSymbol: "\u89F8\u767C\u7B26", newLeftSideString: "\u5DE6\u908A\u7B26\u865F", newRightSideString: "\u53F3\u908A\u7B26\u865F", addRule: "\u6DFB\u52A0\u898F\u5247", noticeInvaidTrigger: "\u7121\u6548\u7684\u89F8\u767C\u7B26, \u89F8\u767C\u7B26\u5FC5\u9808\u662F\u55AE\u5B57\u7B26\u6216\u8005\u662F \u2014\u2014\u3001\u2026\u2026", noticeWarnTriggerExists: "\u7121\u6548\u898F\u5247! \u89F8\u767C\u7B26 %s \u5DF2\u5B58\u5728", noticeMissingInput: "missing input", beforeDelete: "\u522A\u9664\u524D|", newPattern: "\u89F8\u767C\u898F\u5247\u5F8C\u5B57\u4E32\u6A21\u5F0F", noticeInvaidTriggerPatternContainSymbol: "\u7121\u6548\u898F\u5247, \u8F49\u63DB\u524D\u6A21\u5F0F\u5FC5\u9808\u5305\u542B\u4EE3\u8868\u5149\u6A19\u4F4D\u7F6E\u7684\u7B26\u865F |", beforeConvert: "\u8F49\u63DB\u524D|", noticeInvalidPatternString: "Invalid pattern string!" }, button: { update: "\u66F4\u65B0" }, scriptCategoryLabels: { chinese: "\u4E2D\u6587", japanese: "\u65E5\u6587", korean: "\u97D3\u6587", cjk: "\u4E2D\u65E5\u97D3", english: "\u82F1\u6587", digit: "\u6578\u5B57", russian: "\u4FC4\u6587", unknown: "\u672A\u77E5" }, builtinRuleDescriptions: { "builtin-autopair-input": "\u8F38\u5165\u5168\u89D2\u62EC\u865F/\u5F15\u865F\u6642\u81EA\u52D5\u88DC\u5168\u914D\u5C0D", "builtin-autopair-jump": "\u8F38\u5165\u53F3\u5074\u914D\u5C0D\u7B26\u865F\u6642\u81EA\u52D5\u8DF3\u904E\uFF0C\u907F\u514D\u91CD\u8907\u63D2\u5165", "builtin-autopair-delete": "\u522A\u9664\u5168\u89D2\u62EC\u865F/\u5F15\u865F\u6642\u540C\u6642\u522A\u9664\u914D\u5C0D", "builtin-conv-backtick": "\u9023\u7E8C\u4E2D\u6587\u9593\u9694\u865F \xB7\xB7 \u8F49\u884C\u5167\u4EE3\u78BC", "builtin-conv-codeblock": "\u884C\u5167\u4EE3\u78BC\u4E2D\u7E7C\u7E8C\u8F38\u5165 \xB7 \u5347\u7D1A\u70BA\u4EE3\u78BC\u584A", "builtin-conv-formula": "\uFFE5/$ \u7B26\u865F\u7D44\u5408\u8F49\u884C\u5167\u6216\u584A\u7D1A\u516C\u5F0F", "builtin-conv-linestart": "\u884C\u9996 \u300B \u8F49\u5F15\u7528\u6A19\u8A18\u3001\u884C\u9996 \u3001 \u8F49\u659C\u7DDA", "builtin-conv-hw2fw": "CJK\u5B57\u5143\u5F8C\u534A\u89D2\u6A19\u9EDE\u8F49\u5168\u89D2", "builtin-fw2hw-double": "\u9023\u7E8C\u8F38\u5165\u5169\u500B\u76F8\u540C\u5168\u89D2\u6A19\u9EDE\u8F49\u5C0D\u61C9\u534A\u89D2", "builtin-del-inline-formula": "\u522A\u9664\u884C\u5167\u516C\u5F0F $...$ \u914D\u5C0D", "builtin-del-highlight": "\u522A\u9664\u9AD8\u4EAE ==...== \u914D\u5C0D", "builtin-del-block-formula": "\u522A\u9664\u584A\u7D1A\u516C\u5F0F $$...$$ \u914D\u5C0D", "builtin-del-codeblock": "\u5FEB\u901F\u522A\u9664\u7A7A\u4EE3\u78BC\u584A", "builtin-del-wikilink": "\u5FEB\u901F\u522A\u9664\u96D9\u93C8\u53CA\u5D4C\u5165\uFF08![[]]\uFF09", "builtin-sel-wrap-backtick": "\u9078\u4E2D\u6587\u5B57\u5F8C\u8F38\u5165 \xB7 \u5305\u88F9\u70BA\u884C\u5167\u4EE3\u78BC", "builtin-sel-wrap-symbols": "\u9078\u4E2D\u6587\u5B57\u5F8C\u8F38\u5165 \u3010/\xA5/\uFFE5 \u5305\u88F9\u70BA []/$$", "builtin-sel-wrap-quotes": "\u9078\u4E2D\u6587\u5B57\u5F8C\u8F38\u5165\u5168\u89D2\u5F15\u865F\uFF0C\u914D\u5C0D\u5F15\u865F\u5305\u88F9", "builtin-sel-wrap-cjk-brackets": "\u9078\u4E2D\u6587\u5B57\u5F8C\u8F38\u5165\u300A\uFF08\uFF0C\u914D\u5C0D\u62EC\u865F\u5305\u88F9", "builtin-quote-convert": "\u8F38\u5165 > \u6216 \u300B \u8F49\u70BA Markdown \u5F15\u7528\u6A19\u8A18", "builtin-quote-space": "\u5F15\u7528\u6A19\u8A18 > \u5F8C\u81EA\u52D5\u88DC\u7A7A\u683C" } }; var zh_TW_default = locale3; // src/lang/locale/ru-RU.ts var locale4 = { settings: { smartPaste: { name: "\u0423\u043C\u043D\u0430\u044F \u0432\u0441\u0442\u0430\u0432\u043A\u0430 \u0432 \u0441\u043F\u0438\u0441\u043A\u0430\u0445 \u0438 \u0446\u0438\u0442\u0430\u0442\u0430\u0445", desc: "\u041F\u0440\u0438 \u0432\u0441\u0442\u0430\u0432\u043A\u0435 \u0432 \u0441\u043F\u0438\u0441\u043A\u0438 \u0438\u043B\u0438 \u0431\u043B\u043E\u043A\u0438 \u0446\u0438\u0442\u0430\u0442 \u0430\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0438 \u0434\u043E\u0431\u0430\u0432\u043B\u044F\u044E\u0442\u0441\u044F \u043E\u0442\u0441\u0442\u0443\u043F\u044B \u0438 \u043C\u0430\u0440\u043A\u0435\u0440\u044B \u0441\u043F\u0438\u0441\u043A\u0430/\u0446\u0438\u0442\u0430\u0442\u044B." }, codeblockEdit: { name: "\u0423\u043B\u0443\u0447\u0448\u0435\u043D\u0438\u0435 \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u043A\u043E\u0434\u043E\u0432\u044B\u0445 \u0431\u043B\u043E\u043A\u043E\u0432", desc: "\u0423\u043B\u0443\u0447\u0448\u0435\u043D\u0438\u0435 \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u0432 \u043A\u043E\u0434\u043E\u0432\u044B\u0445 \u0431\u043B\u043E\u043A\u0430\u0445 (Tab, \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u0435, \u0432\u0441\u0442\u0430\u0432\u043A\u0430, Cmd/Ctrl+A \u0432\u044B\u0434\u0435\u043B\u0435\u043D\u0438\u0435)." }, backspaceEdit: { name: "\u0423\u043C\u043D\u044B\u0439 Backspace", desc: "\u0423\u043B\u0443\u0447\u0448\u0435\u043D\u0438\u0435 \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u044F \u043F\u0443\u0441\u0442\u044B\u0445 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u043E\u0432 \u0441\u043F\u0438\u0441\u043A\u0430 \u0438\u043B\u0438 \u043F\u0443\u0441\u0442\u044B\u0445 \u0441\u0442\u0440\u043E\u043A \u0441\u0441\u044B\u043B\u043E\u043A." }, tabOut: { name: "Tab \u0434\u043B\u044F \u0432\u044B\u0445\u043E\u0434\u0430 \u0438\u0437 \u043F\u0430\u0440\u043D\u044B\u0445 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432", desc: "\u041D\u0430\u0436\u043C\u0438\u0442\u0435 Tab, \u0447\u0442\u043E\u0431\u044B \u043F\u0435\u0440\u0435\u043C\u0435\u0441\u0442\u0438\u0442\u044C \u043A\u0443\u0440\u0441\u043E\u0440 \u0437\u0430 \u043F\u0440\u0435\u0434\u0435\u043B\u044B \u043F\u0430\u0440\u043D\u044B\u0445 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432, \u0442\u0430\u043A\u0438\u0445 \u043A\u0430\u043A \u3010\u3011, \uFF08\uFF09, \u300A\u300B, \u043A\u0430\u0432\u044B\u0447\u043A\u0438 \u0438\u043B\u0438 \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u043E\u0433\u043E \u043A\u043E\u0434\u0430." }, autoFormatting: { name: "\u0410\u0432\u0442\u043E\u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435 \u043F\u0440\u0438 \u043D\u0430\u0431\u043E\u0440\u0435 \u0442\u0435\u043A\u0441\u0442\u0430", desc: "\u0412\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435/\u0432\u044B\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435 \u0430\u0432\u0442\u043E\u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u0442\u0435\u043A\u0441\u0442\u0430 \u0432\u043E \u0432\u0440\u0435\u043C\u044F \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430." }, autoFormatPaste: { name: "\u0410\u0432\u0442\u043E\u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435 \u043F\u0440\u0438 \u0432\u0441\u0442\u0430\u0432\u043A\u0435", desc: "\u0412\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435/\u0432\u044B\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435 \u0430\u0432\u0442\u043E\u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u043F\u0440\u0438 \u0432\u0441\u0442\u0430\u0432\u043A\u0435. CMD/CTRL+SHIFT+V (\u0432\u0441\u0442\u0430\u0432\u043A\u0430 \u0431\u0435\u0437 \u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F) \u043D\u0435 \u0432\u044B\u0437\u044B\u0432\u0430\u0435\u0442 \u0441\u0440\u0430\u0431\u0430\u0442\u044B\u0432\u0430\u043D\u0438\u0435." }, languagePairSpacing: { name: "\u0421\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044F \u043F\u0440\u043E\u0431\u0435\u043B\u043E\u0432 \u043C\u0435\u0436\u0434\u0443 \u044F\u0437\u044B\u043A\u0430\u043C\u0438", desc: "\u041E\u043F\u0440\u0435\u0434\u0435\u043B\u0438\u0442\u0435, \u043C\u0435\u0436\u0434\u0443 \u043A\u0430\u043A\u0438\u043C\u0438 \u043F\u0430\u0440\u0430\u043C\u0438 \u044F\u0437\u044B\u043A\u043E\u0432/\u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432 \u0434\u043E\u043B\u0436\u043D\u044B \u0430\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0438 \u0434\u043E\u0431\u0430\u0432\u043B\u044F\u0442\u044C\u0441\u044F \u043F\u0440\u043E\u0431\u0435\u043B\u044B" }, prefixDictionary: { name: "\u0421\u043B\u043E\u0432\u0430\u0440\u044C \u043F\u0440\u0435\u0444\u0438\u043A\u0441\u043E\u0432", desc: "\u0420\u0430\u0437\u0434\u0435\u043B\u044F\u0439\u0442\u0435 \u0437\u0430\u043F\u0438\u0441\u0438 \u0437\u0430\u043F\u044F\u0442\u044B\u043C\u0438, \u043F\u0440\u043E\u0431\u0435\u043B\u0430\u043C\u0438 \u0438\u043B\u0438 \u043F\u0435\u0440\u0435\u043D\u043E\u0441\u0430\u043C\u0438 \u0441\u0442\u0440\u043E\u043A. \u041F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044E\u0442\u0441\u044F \u0441\u043B\u043E\u0432\u0430 \u0438 /\u0440\u0435\u0433\u0443\u043B\u044F\u0440\u043D\u044B\u0435 \u0432\u044B\u0440\u0430\u0436\u0435\u043D\u0438\u044F/. \u0421\u043E\u0432\u043F\u0430\u0434\u0430\u044E\u0449\u0438\u0435 \u0442\u043E\u043A\u0435\u043D\u044B \u043D\u0435 \u043F\u043E\u043B\u0443\u0447\u0430\u0442 \u043F\u0440\u043E\u0431\u0435\u043B\u043E\u0432" }, softSpaceSymbols: { leftName: "\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0435 \u0434\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u044B\u0435 \u0441\u0438\u043C\u0432\u043E\u043B\u044B \u043C\u044F\u0433\u043A\u043E\u0433\u043E \u043F\u0440\u043E\u0431\u0435\u043B\u0430 \u0441\u043B\u0435\u0432\u0430", leftDesc: `\u041E\u0431\u0449\u0435\u043F\u0440\u0438\u043D\u044F\u0442\u044B\u0435 \u043F\u043E\u043B\u043D\u043E\u0448\u0438\u0440\u0438\u043D\u043D\u044B\u0435 \u0437\u043D\u0430\u043A\u0438 \u043F\u0440\u0435\u043F\u0438\u043D\u0430\u043D\u0438\u044F, \u0430\u043D\u0433\u043B\u0438\u0439\u0441\u043A\u0438\u0435 \u043A\u0430\u0432\u044B\u0447\u043A\u0438 (' "), \u0430 \u0442\u0430\u043A\u0436\u0435 \u043E\u0442\u043A\u0440\u044B\u0432\u0430\u044E\u0449\u0438\u0435 \u0441\u043A\u043E\u0431\u043A\u0438 ([ ( {) \u0443\u0436\u0435 \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u044B. \u0414\u043E\u0431\u0430\u0432\u044C\u0442\u0435 \u0437\u0434\u0435\u0441\u044C \u0434\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u044B\u0435 \u0441\u0438\u043C\u0432\u043E\u043B\u044B \u0434\u043B\u044F \u043B\u0435\u0432\u043E\u0439 \u0441\u0442\u043E\u0440\u043E\u043D\u044B (\u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440, -).`, rightName: "\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0435 \u0434\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u044B\u0435 \u0441\u0438\u043C\u0432\u043E\u043B\u044B \u043C\u044F\u0433\u043A\u043E\u0433\u043E \u043F\u0440\u043E\u0431\u0435\u043B\u0430 \u0441\u043F\u0440\u0430\u0432\u0430", rightDesc: `\u041E\u0431\u0449\u0435\u043F\u0440\u0438\u043D\u044F\u0442\u044B\u0435 \u043F\u043E\u043B\u043D\u043E\u0448\u0438\u0440\u0438\u043D\u043D\u044B\u0435 \u0437\u043D\u0430\u043A\u0438 \u043F\u0440\u0435\u043F\u0438\u043D\u0430\u043D\u0438\u044F, \u0430\u043D\u0433\u043B\u0438\u0439\u0441\u043A\u0438\u0435 \u043A\u0430\u0432\u044B\u0447\u043A\u0438 (' "), \u0437\u0430\u043A\u0440\u044B\u0432\u0430\u044E\u0449\u0438\u0435 \u0441\u043A\u043E\u0431\u043A\u0438 (] ) }), \u0430 \u0442\u0430\u043A\u0436\u0435 \u0430\u043D\u0433\u043B\u0438\u0439\u0441\u043A\u0430\u044F \u043F\u043E\u043B\u0443\u0448\u0438\u0440\u0438\u043D\u043D\u0430\u044F \u043F\u0443\u043D\u043A\u0442\u0443\u0430\u0446\u0438\u044F (. , ? ! : ;) \u0443\u0436\u0435 \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u044B \u043A\u0430\u043A \u0441\u0438\u043C\u0432\u043E\u043B\u044B \u043F\u0440\u0430\u0432\u043E\u0433\u043E \u043C\u044F\u0433\u043A\u043E\u0433\u043E \u043F\u0440\u043E\u0431\u0435\u043B\u0430. \u0414\u043E\u0431\u0430\u0432\u044C\u0442\u0435 \u0437\u0434\u0435\u0441\u044C \u0434\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u044B\u0435 \u0441\u0438\u043C\u0432\u043E\u043B\u044B \u0434\u043B\u044F \u043F\u0440\u0430\u0432\u043E\u0439 \u0441\u0442\u043E\u0440\u043E\u043D\u044B (\u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440, -).` }, customScriptCategories: { name: "\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0435 \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u0438 \u0441\u043A\u0440\u0438\u043F\u0442\u043E\u0432", desc: "\u0414\u043E\u0431\u0430\u0432\u044C\u0442\u0435 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0435 \u044F\u0437\u044B\u043A\u0438 \u0438\u043B\u0438 \u043D\u0430\u0431\u043E\u0440\u044B \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432", namePlaceholder: "\u0418\u043C\u044F", patternPlaceholder: "\u0428\u0430\u0431\u043B\u043E\u043D \u043A\u043B\u0430\u0441\u0441\u0430 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432" }, capitalizeFirstLetter: { name: "\u0417\u0430\u0433\u043B\u0430\u0432\u043D\u0430\u044F \u0431\u0443\u043A\u0432\u0430 \u0432 \u043D\u0430\u0447\u0430\u043B\u0435 \u043A\u0430\u0436\u0434\u043E\u0433\u043E \u043F\u0440\u0435\u0434\u043B\u043E\u0436\u0435\u043D\u0438\u044F", desc: "\u041F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u043E\u0432\u0430\u043D\u0438\u0435 \u043F\u0435\u0440\u0432\u043E\u0439 \u0431\u0443\u043A\u0432\u044B \u043A\u0430\u0436\u0434\u043E\u0433\u043E \u043F\u0440\u0435\u0434\u043B\u043E\u0436\u0435\u043D\u0438\u044F \u0432 \u0430\u043D\u0433\u043B\u0438\u0439\u0441\u043A\u043E\u043C \u0432 \u0437\u0430\u0433\u043B\u0430\u0432\u043D\u0443\u044E." }, textPunctuationSpace: { name: "\u0418\u043D\u0442\u0435\u043B\u043B\u0435\u043A\u0442\u0443\u0430\u043B\u044C\u043D\u0430\u044F \u0432\u0441\u0442\u0430\u0432\u043A\u0430 \u043F\u0440\u043E\u0431\u0435\u043B\u0430 \u043C\u0435\u0436\u0434\u0443 \u0442\u0435\u043A\u0441\u0442\u043E\u043C \u0438 \u043F\u0443\u043D\u043A\u0442\u0443\u0430\u0446\u0438\u0435\u0439", desc: "\u0418\u043D\u0442\u0435\u043B\u043B\u0435\u043A\u0442\u0443\u0430\u043B\u044C\u043D\u0430\u044F \u0432\u0441\u0442\u0430\u0432\u043A\u0430 \u043F\u0440\u043E\u0431\u0435\u043B\u0430 \u043C\u0435\u0436\u0434\u0443 \u0442\u0435\u043A\u0441\u0442\u043E\u043C \u0438 \u043F\u0443\u043D\u043A\u0442\u0443\u0430\u0446\u0438\u0435\u0439." }, spaceStrategyInlineCode: { name: "\u0421\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044F \u043F\u0440\u043E\u0431\u0435\u043B\u043E\u0432 \u043C\u0435\u0436\u0434\u0443 \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u043C \u043A\u043E\u0434\u043E\u043C \u0438 \u0442\u0435\u043A\u0441\u0442\u043E\u043C", desc: "\u041E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u0438\u0435 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u043F\u0440\u043E\u0431\u0435\u043B\u043E\u0432 \u043C\u0435\u0436\u0434\u0443 \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u043C \u043A\u043E\u0434\u043E\u043C \u0438 \u0442\u0435\u043A\u0441\u0442\u043E\u043C." }, spaceStrategyInlineFormula: { name: "\u0421\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044F \u043F\u0440\u043E\u0431\u0435\u043B\u043E\u0432 \u043C\u0435\u0436\u0434\u0443 \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u043E\u0439 \u0444\u043E\u0440\u043C\u0443\u043B\u043E\u0439 \u0438 \u0442\u0435\u043A\u0441\u0442\u043E\u043C", desc: "\u041E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u0438\u0435 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u043F\u0440\u043E\u0431\u0435\u043B\u043E\u0432 \u043C\u0435\u0436\u0434\u0443 \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u043C\u0438 \u0444\u043E\u0440\u043C\u0443\u043B\u0430\u043C\u0438 \u0438 \u0442\u0435\u043A\u0441\u0442\u043E\u043C." }, spaceStrategyLinkText: { name: "\u0421\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044F \u043F\u0440\u043E\u0431\u0435\u043B\u043E\u0432 \u043C\u0435\u0436\u0434\u0443 \u0441\u0441\u044B\u043B\u043A\u043E\u0439 \u0438 \u0442\u0435\u043A\u0441\u0442\u043E\u043C", desc: "\u041E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u0438\u0435 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u043F\u0440\u043E\u0431\u0435\u043B\u043E\u0432 \u043C\u0435\u0436\u0434\u0443 [[\u0432\u0438\u043A\u0438\u0441\u0441\u044B\u043B\u043A\u0430\u043C\u0438]] [markdown-\u0441\u0441\u044B\u043B\u043A\u0430\u043C\u0438](...) \u0438 \u0442\u0435\u043A\u0441\u0442\u043E\u043C." }, userDefinedRegexpSwitch: { name: "\u041F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0445 \u0440\u0435\u0433\u0443\u043B\u044F\u0440\u043D\u044B\u0445 \u0432\u044B\u0440\u0430\u0436\u0435\u043D\u0438\u0439", desc: "\u0412\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435/\u0432\u044B\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0445 \u0440\u0435\u0433\u0443\u043B\u044F\u0440\u043D\u044B\u0445 \u0432\u044B\u0440\u0430\u0436\u0435\u043D\u0438\u0439, \u043F\u0440\u0435\u0434\u043E\u0442\u0432\u0440\u0430\u0449\u0435\u043D\u0438\u0435 \u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u0438 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0430 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u043F\u0440\u043E\u0431\u0435\u043B\u043E\u0432 \u043C\u0435\u0436\u0434\u0443 \u0441\u043E\u0432\u043F\u0430\u0434\u0430\u044E\u0449\u0438\u043C \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u043C\u044B\u043C \u0438 \u0434\u0440\u0443\u0433\u0438\u043C \u0442\u0435\u043A\u0441\u0442\u043E\u043C." }, userDefinedRegexp: { name: "\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u043E\u0435 \u0440\u0435\u0433\u0443\u043B\u044F\u0440\u043D\u043E\u0435 \u0432\u044B\u0440\u0430\u0436\u0435\u043D\u0438\u0435, \u043E\u0434\u043D\u043E \u0432\u044B\u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u043D\u0430 \u0441\u0442\u0440\u043E\u043A\u0443", desc: "\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u043E\u0435 \u0440\u0435\u0433\u0443\u043B\u044F\u0440\u043D\u043E\u0435 \u0432\u044B\u0440\u0430\u0436\u0435\u043D\u0438\u0435, \u0441\u043E\u0432\u043F\u0430\u0434\u0430\u044E\u0449\u0435\u0435 \u0441 \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u043C\u044B\u043C, \u043D\u0435 \u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044F, \u043E\u0434\u043D\u043E \u0432\u044B\u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u043D\u0430 \u0441\u0442\u0440\u043E\u043A\u0443, \u043D\u0435 \u0434\u043E\u0431\u0430\u0432\u043B\u044F\u0439\u0442\u0435 \u043F\u0440\u043E\u0431\u0435\u043B\u044B \u0432 \u043A\u043E\u043D\u0446\u0435 \u0441\u0442\u0440\u043E\u043A\u0438.\u041A\u043E\u043D\u0435\u0446 \u043A\u0430\u0436\u0434\u043E\u0439 \u0441\u0442\u0440\u043E\u043A\u0438 \u0444\u0438\u043A\u0441\u0438\u0440\u043E\u0432\u0430\u043D \u0442\u0440\u0435\u043C\u044F \u0441\u0438\u043C\u0432\u043E\u043B\u0430\u043C\u0438: | \u0438 \u0434\u0432\u0443\u043C\u044F \u0441\u0438\u043C\u0432\u043E\u043B\u0430\u043C\u0438 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u043F\u0440\u043E\u0431\u0435\u043B\u043E\u0432, \u0441\u0438\u043C\u0432\u043E\u043B\u044B \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u043F\u0440\u043E\u0431\u0435\u043B\u043E\u0432 - \u044D\u0442\u043E - = +, \u043A\u043E\u0442\u043E\u0440\u044B\u0435 \u0441\u043E\u043E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043D\u043D\u043E \u043E\u0431\u043E\u0437\u043D\u0430\u0447\u0430\u044E\u0442 \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0442\u0440\u0435\u0431\u043E\u0432\u0430\u043D\u0438\u044F \u043F\u0440\u043E\u0431\u0435\u043B\u043E\u0432 (-), \u043C\u044F\u0433\u043A\u0438\u0435 \u043F\u0440\u043E\u0431\u0435\u043B\u044B (=), \u0441\u0442\u0440\u043E\u0433\u0438\u0435 \u043F\u0440\u043E\u0431\u0435\u043B\u044B (+).\u042D\u0442\u0438 \u0434\u0432\u0430 \u0441\u0438\u043C\u0432\u043E\u043B\u0430 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u043F\u0440\u043E\u0431\u0435\u043B\u043E\u0432 \u044F\u0432\u043B\u044F\u044E\u0442\u0441\u044F \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0435\u0439 \u043F\u0440\u043E\u0431\u0435\u043B\u043E\u0432 \u0434\u043B\u044F \u043B\u0435\u0432\u043E\u0439 \u0438 \u043F\u0440\u0430\u0432\u043E\u0439 \u0441\u0442\u043E\u0440\u043E\u043D \u0441\u043E\u0432\u043F\u0430\u0434\u0430\u044E\u0449\u0435\u0433\u043E \u0431\u043B\u043E\u043A\u0430 \u0441\u043E\u043E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043D\u043D\u043E. \u0421\u0442\u0440\u043E\u043A\u0438, \u043D\u0430\u0447\u0438\u043D\u0430\u044E\u0449\u0438\u0435\u0441\u044F \u0441 //, \u043E\u0431\u0440\u0430\u0431\u0430\u0442\u044B\u0432\u0430\u044E\u0442\u0441\u044F \u043A\u0430\u043A \u043A\u043E\u043C\u043C\u0435\u043D\u0442\u0430\u0440\u0438\u0438" }, userRulesRespectUserDefinedRegexBlocks: { name: "\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0435 \u043F\u0440\u0430\u0432\u0438\u043B\u0430 \u0443\u0432\u0430\u0436\u0430\u044E\u0442 \u0431\u043B\u043E\u043A\u0438 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0445 \u0440\u0435\u0433\u0443\u043B\u044F\u0440\u043D\u044B\u0445 \u0432\u044B\u0440\u0430\u0436\u0435\u043D\u0438\u0439", desc: "\u041F\u0440\u0438 \u0432\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0438 \u0442\u0435\u043A\u0441\u0442, \u0441\u043E\u0432\u043F\u0430\u0434\u0430\u044E\u0449\u0438\u0439 \u0441 \u0431\u043B\u043E\u043A\u0430\u043C\u0438 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0445 \u0440\u0435\u0433\u0443\u043B\u044F\u0440\u043D\u044B\u0445 \u0432\u044B\u0440\u0430\u0436\u0435\u043D\u0438\u0439, \u043D\u0435 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043F\u0443\u0441\u043A\u0430\u0442\u044C \u0430\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0438\u0435 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0435 \u043F\u0440\u0430\u0432\u0438\u043B\u0430." }, excludeFoldersFiles: { name: "\u0418\u0441\u043A\u043B\u044E\u0447\u0438\u0442\u044C \u043F\u0430\u043F\u043A\u0438/\u0444\u0430\u0439\u043B\u044B", desc: "\u042D\u0442\u043E\u0442 \u043F\u043B\u0430\u0433\u0438\u043D \u0431\u0443\u0434\u0435\u0442 \u043E\u0431\u0440\u0430\u0431\u0430\u0442\u044B\u0432\u0430\u0442\u044C \u043A\u0430\u0436\u0434\u0443\u044E \u0441\u0442\u0440\u043E\u043A\u0443 \u043A\u0430\u043A \u0438\u0441\u043A\u043B\u044E\u0447\u0430\u0435\u043C\u0443\u044E \u043F\u0430\u043F\u043A\u0443 \u0438\u043B\u0438 \u0444\u0430\u0439\u043B. \u041D\u0430\u043F\u0440\u0438\u043C\u0435\u0440: DailyNote/, DailyNote/WeekNotes/, DailyNote/test.md" }, fixMacOSContextMenu: { name: "\u0418\u0441\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u044F \u043A\u0443\u0440\u0441\u043E\u0440\u0430 \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442\u043D\u043E\u0433\u043E \u043C\u0435\u043D\u044E MacOS (\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044F \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u043A Obsidian)", desc: "\u0418\u0441\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u044B, \u043A\u043E\u0433\u0434\u0430 \u043A\u0443\u0440\u0441\u043E\u0440 \u043F\u0435\u0440\u0435\u0441\u043A\u0430\u043A\u0438\u0432\u0430\u0435\u0442 \u043D\u0430 \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0443\u044E \u0441\u0442\u0440\u043E\u043A\u0443 \u043F\u0440\u0438 \u0432\u044B\u0437\u043E\u0432\u0435 \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442\u043D\u043E\u0433\u043E \u043C\u0435\u043D\u044E \u043D\u0430 MacOS (\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044F \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u043A Obsidian)." }, fixMicrosoftIME: { name: "\u0418\u0441\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u044B \u0441 Microsoft Input Method", desc: "\u0410\u0434\u0430\u043F\u0442\u0430\u0446\u0438\u044F \u0434\u043B\u044F \u0441\u0442\u0430\u0440\u044B\u0445 \u0432\u0435\u0440\u0441\u0438\u0439 Microsoft Input Method." }, strictLineBreaks: { name: "\u0420\u0435\u0436\u0438\u043C \u0441\u0442\u0440\u043E\u0433\u0438\u0445 \u0440\u0430\u0437\u0440\u044B\u0432\u043E\u0432 \u0441\u0442\u0440\u043E\u043A", desc: "\u0412 \u0440\u0435\u0436\u0438\u043C\u0435 \u0441\u0442\u0440\u043E\u0433\u0438\u0445 \u0440\u0430\u0437\u0440\u044B\u0432\u043E\u0432 \u0441\u0442\u0440\u043E\u043A, \u043E\u0434\u043D\u043E\u043A\u0440\u0430\u0442\u043D\u043E\u0435 \u043D\u0430\u0436\u0430\u0442\u0438\u0435 Enter \u0432 \u043E\u0431\u044B\u0447\u043D\u044B\u0445 \u0442\u0435\u043A\u0441\u0442\u043E\u0432\u044B\u0445 \u0441\u0442\u0440\u043E\u043A\u0430\u0445 \u0441\u043E\u0437\u0434\u0430\u0441\u0442 \u0434\u0432\u0430 \u0440\u0430\u0437\u0440\u044B\u0432\u0430 \u0441\u0442\u0440\u043E\u043A\u0438 \u0438\u043B\u0438 \u0434\u0432\u0430 \u043F\u0440\u043E\u0431\u0435\u043B\u0430 \u0438 Enter." }, enhanceModA: { name: "\u0423\u043B\u0443\u0447\u0448\u0438\u0442\u044C \u0432\u044B\u0434\u0435\u043B\u0435\u043D\u0438\u0435 Mod+A \u0432 \u0442\u0435\u043A\u0441\u0442\u0435", desc: "\u0421\u043D\u0430\u0447\u0430\u043B\u0430 \u0432\u044B\u0434\u0435\u043B\u0438\u0442\u0435 \u0442\u0435\u043A\u0443\u0449\u0443\u044E \u0441\u0442\u0440\u043E\u043A\u0443, \u0437\u0430\u0442\u0435\u043C \u0432\u044B\u0434\u0435\u043B\u0438\u0442\u0435 \u0442\u0435\u043A\u0443\u0449\u0438\u0439 \u0442\u0435\u043A\u0441\u0442\u043E\u0432\u044B\u0439 \u0431\u043B\u043E\u043A, \u0437\u0430\u0442\u0435\u043C \u0432\u044B\u0434\u0435\u043B\u0438\u0442\u0435 \u0432\u0435\u0441\u044C \u0442\u0435\u043A\u0441\u0442." }, collapsePersistentEnter: { name: "Enter \u0431\u0435\u0437 \u0440\u0430\u0437\u0432\u043E\u0440\u0430\u0447\u0438\u0432\u0430\u043D\u0438\u044F \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0430", desc: "\u041F\u0440\u0438 \u043D\u0430\u0436\u0430\u0442\u0438\u0438 Enter \u043D\u0430 \u0441\u0432\u0451\u0440\u043D\u0443\u0442\u043E\u043C \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0435 \u0434\u043E\u0431\u0430\u0432\u043B\u044F\u0435\u0442 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A \u0442\u043E\u0433\u043E \u0436\u0435 \u0443\u0440\u043E\u0432\u043D\u044F, \u043D\u0435 \u0440\u0430\u0437\u0432\u043E\u0440\u0430\u0447\u0438\u0432\u0430\u044F \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u043C\u043E\u0435." }, printDebugInfo: { name: "\u0412\u044B\u0432\u043E\u0434 \u043E\u0442\u043B\u0430\u0434\u043E\u0447\u043D\u043E\u0439 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0438 \u0432 \u043A\u043E\u043D\u0441\u043E\u043B\u044C", desc: "\u0412\u044B\u0432\u043E\u0434 \u043E\u0442\u043B\u0430\u0434\u043E\u0447\u043D\u043E\u0439 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0438 \u0432 \u043A\u043E\u043D\u0441\u043E\u043B\u044C." }, rulesStoragePath: { name: "\u041F\u0443\u0442\u044C \u0445\u0440\u0430\u043D\u0435\u043D\u0438\u044F \u0444\u0430\u0439\u043B\u043E\u0432 \u043F\u0440\u0430\u0432\u0438\u043B", desc: "\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u043F\u0443\u0442\u044C \u0445\u0440\u0430\u043D\u0435\u043D\u0438\u044F \u0444\u0430\u0439\u043B\u043E\u0432 \u043F\u0440\u0430\u0432\u0438\u043B (\u043E\u0442\u043D\u043E\u0441\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u043A\u043E\u0440\u043D\u044F \u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0430). \u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E \u0434\u043B\u044F \u0445\u0440\u0430\u043D\u0435\u043D\u0438\u044F \u0432 \u043A\u0430\u0442\u0430\u043B\u043E\u0433\u0435 \u043F\u043B\u0430\u0433\u0438\u043D\u0430", defaultOption: "\u041F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E (\u043A\u0430\u0442\u0430\u043B\u043E\u0433 \u043F\u043B\u0430\u0433\u0438\u043D\u0430)", migrateButton: "\u041F\u0435\u0440\u0435\u043D\u0435\u0441\u0442\u0438", migrateDesc: "\u041F\u0435\u0440\u0435\u043D\u0435\u0441\u0442\u0438 \u0444\u0430\u0439\u043B\u044B \u043F\u0440\u0430\u0432\u0438\u043B \u0438\u0437 \u0440\u0430\u043D\u0435\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043D\u043D\u043E\u0433\u043E \u043F\u0443\u0442\u0438 \u0432 \u0442\u0435\u043A\u0443\u0449\u0438\u0439", migrateSuccess: "\u0424\u0430\u0439\u043B\u044B \u043F\u0440\u0430\u0432\u0438\u043B \u0443\u0441\u043F\u0435\u0448\u043D\u043E \u043F\u0435\u0440\u0435\u043D\u0435\u0441\u0435\u043D\u044B" }, selectionReplaceRule: { name: "\u041F\u0440\u0430\u0432\u0438\u043B\u043E \u0437\u0430\u043C\u0435\u043D\u044B \u0432\u044B\u0434\u0435\u043B\u0435\u043D\u043D\u043E\u0433\u043E \u0442\u0435\u043A\u0441\u0442\u0430", desc: "\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u043E\u0435 \u043F\u0440\u0430\u0432\u0438\u043B\u043E \u0437\u0430\u043C\u0435\u043D\u044B \u0432\u044B\u0434\u0435\u043B\u0435\u043D\u043D\u043E\u0433\u043E \u0442\u0435\u043A\u0441\u0442\u0430" }, deleteRule: { name: "\u041F\u0440\u0430\u0432\u0438\u043B\u043E \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u044F", desc: "\u041F\u0440\u0430\u0432\u0438\u043B\u043E: \u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435 | \u0434\u043B\u044F \u0443\u043A\u0430\u0437\u0430\u043D\u0438\u044F \u043F\u043E\u0437\u0438\u0446\u0438\u0438 \u043A\u0443\u0440\u0441\u043E\u0440\u0430. \u041F\u043E\u0434\u0441\u043A\u0430\u0437\u043A\u0430: \u0418\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435 | \u0434\u043B\u044F \u0443\u043A\u0430\u0437\u0430\u043D\u0438\u044F \u043F\u043E\u0437\u0438\u0446\u0438\u0438 \u043A\u0443\u0440\u0441\u043E\u0440\u0430." }, convertRule: { name: "\u041F\u0440\u0430\u0432\u0438\u043B\u043E \u043F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u043E\u0432\u0430\u043D\u0438\u044F", desc: "\u041F\u0440\u0430\u0432\u0438\u043B\u043E: \u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435 | \u0434\u043B\u044F \u0443\u043A\u0430\u0437\u0430\u043D\u0438\u044F \u043F\u043E\u0437\u0438\u0446\u0438\u0438 \u043A\u0443\u0440\u0441\u043E\u0440\u0430. \u041F\u043E\u0434\u0441\u043A\u0430\u0437\u043A\u0430: \u0418\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435 | \u0434\u043B\u044F \u0443\u043A\u0430\u0437\u0430\u043D\u0438\u044F \u043F\u043E\u0437\u0438\u0446\u0438\u0438 \u043A\u0443\u0440\u0441\u043E\u0440\u0430." }, trigger: { name: "\u0422\u0440\u0438\u0433\u0433\u0435\u0440" }, left: { name: "\u041B\u0435\u0432\u044B\u0439" }, right: { name: "\u041F\u0440\u0430\u0432\u044B\u0439" }, oldPattern: { name: "\u0421\u0442\u0430\u0440\u044B\u0439 \u0448\u0430\u0431\u043B\u043E\u043D" }, newPattern: { name: "\u041D\u043E\u0432\u044B\u0439 \u0448\u0430\u0431\u043B\u043E\u043D" }, ruleEditModal: { addTitle: "\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u043F\u0440\u0430\u0432\u0438\u043B\u043E", editTitle: "\u0420\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u043F\u0440\u0430\u0432\u0438\u043B\u043E", fieldType: "\u0422\u0438\u043F", fieldTrigger: "\u0421\u043E\u0432\u043F\u0430\u0434\u0435\u043D\u0438\u0435 \u043F\u0435\u0440\u0435\u0434 \u043A\u0443\u0440\u0441\u043E\u0440\u043E\u043C", fieldTriggerSelectKey: "\u0421\u0438\u043C\u0432\u043E\u043B \u0437\u0430\u043F\u0443\u0441\u043A\u0430", fieldTriggerRight: "\u0421\u043E\u0432\u043F\u0430\u0434\u0435\u043D\u0438\u0435 \u043F\u043E\u0441\u043B\u0435 \u043A\u0443\u0440\u0441\u043E\u0440\u0430", hintTriggerEscape: "\\\\: \u043E\u0431\u0440\u0430\u0442\u043D\u0430\u044F \u043A\u043E\u0441\u0430\u044F \u0447\u0435\u0440\u0442\u0430, \\n: \u043D\u043E\u0432\u0430\u044F \u0441\u0442\u0440\u043E\u043A\u0430, \\t: \u0442\u0430\u0431\u0443\u043B\u044F\u0446\u0438\u044F", fieldReplacement: "\u0417\u0430\u043C\u0435\u043D\u0430", fieldReplacementDescSelectKey: "${SEL}: \u0432\u044B\u0434\u0435\u043B\u0435\u043D\u043D\u044B\u0439 \u0442\u0435\u043A\u0441\u0442, ${0:${SEL}}: \u043E\u0441\u0442\u0430\u0432\u0438\u0442\u044C \u0442\u0435\u043A\u0441\u0442 \u0432\u044B\u0434\u0435\u043B\u0435\u043D\u043D\u044B\u043C.", fieldReplacementDescInputDelete: "[[0]]: 0-\u044F \u043B\u0435\u0432\u0430\u044F \u0433\u0440\u0443\u043F\u043F\u0430 \u0437\u0430\u0445\u0432\u0430\u0442\u0430, [[R1]]: 1-\u044F \u043F\u0440\u0430\u0432\u0430\u044F \u0433\u0440\u0443\u043F\u043F\u0430 \u0437\u0430\u0445\u0432\u0430\u0442\u0430.", fieldIsRegex: "\u0418\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C \u0440\u0435\u0433\u0443\u043B\u044F\u0440\u043D\u044B\u0435 \u0432\u044B\u0440\u0430\u0436\u0435\u043D\u0438\u044F", fieldTriggerMode: "\u0420\u0435\u0436\u0438\u043C \u0437\u0430\u043F\u0443\u0441\u043A\u0430", fieldScope: "\u041E\u0431\u043B\u0430\u0441\u0442\u044C", fieldScopeLanguage: "\u042F\u0437\u044B\u043A (\u043D\u0435\u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E)", fieldRegexFlags: "\u0424\u043B\u0430\u0433\u0438 regex", fieldRegexFlagsDesc: "\u041F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044E\u0442\u0441\u044F \u0442\u043E\u043B\u044C\u043A\u043E i / m / u, \u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440 im", fieldPriority: "\u041F\u0440\u0438\u043E\u0440\u0438\u0442\u0435\u0442", fieldPriorityDesc: "\u0427\u0435\u043C \u043C\u0435\u043D\u044C\u0448\u0435 \u0447\u0438\u0441\u043B\u043E, \u0442\u0435\u043C \u0432\u044B\u0448\u0435 \u043F\u0440\u0438\u043E\u0440\u0438\u0442\u0435\u0442, \u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E 100", fieldDescription: "\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435", buttonSave: "\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C", invalidRegex: "\u041D\u0435\u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u043E\u0435 \u0440\u0435\u0433\u0443\u043B\u044F\u0440\u043D\u043E\u0435 \u0432\u044B\u0440\u0430\u0436\u0435\u043D\u0438\u0435", fieldIsFunction: "\u0418\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C \u0444\u0443\u043D\u043A\u0446\u0438\u044E \u0437\u0430\u043C\u0435\u043D\u044B", functionHintInputDelete: "\u0410\u0440\u0433\u0443\u043C\u0435\u043D\u0442\u044B: leftMatches (string[]), rightMatches (string[]). \u0412\u0435\u0440\u043D\u0438\u0442\u0435 \u0441\u0442\u0440\u043E\u043A\u0443 \u0438\u043B\u0438 undefined \u0434\u043B\u044F \u043F\u0440\u043E\u043F\u0443\u0441\u043A\u0430.", functionHintSelectKey: "\u0410\u0440\u0433\u0443\u043C\u0435\u043D\u0442\u044B: selectionText (string), key (string). \u0412\u0435\u0440\u043D\u0438\u0442\u0435 \u0441\u0442\u0440\u043E\u043A\u0443 \u0438\u043B\u0438 undefined \u0434\u043B\u044F \u043F\u0440\u043E\u043F\u0443\u0441\u043A\u0430.", hintTabstop: "$0: \u043F\u043E\u0437\u0438\u0446\u0438\u044F \u043A\u0443\u0440\u0441\u043E\u0440\u0430, $1/$2: \u043F\u043E\u0437\u0438\u0446\u0438\u0438 \u043F\u0435\u0440\u0435\u0445\u043E\u0434\u0430 Tab, ${1:text}: \u043F\u0435\u0440\u0435\u0439\u0442\u0438 \u0438 \u0432\u044B\u0434\u0435\u043B\u0438\u0442\u044C text.", functionPlaceholder: "// \u041F\u0440\u0438\u043C\u0435\u0440:\nconst d = new Date();\nreturn d.toISOString().slice(0,10) + '$0';", groupMatch: "\u0423\u0441\u043B\u043E\u0432\u0438\u044F \u0441\u043E\u043E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u044F", groupReplacement: "\u0417\u0430\u043C\u0435\u043D\u0430", groupOther: "\u041F\u0440\u043E\u0447\u0435\u0435" }, ruleType: { input: "\u0412\u0432\u043E\u0434", delete: "\u0423\u0434\u0430\u043B\u0435\u043D\u0438\u0435", selectKey: "\u0417\u0430\u043C\u0435\u043D\u0430 \u0432\u044B\u0431\u043E\u0440\u0430" } }, commands: { formatArticle: "\u0424\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0442\u0435\u043A\u0443\u0449\u0443\u044E \u0441\u0442\u0430\u0442\u044C\u044E", formatSelection: "\u0424\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0432\u044B\u0434\u0435\u043B\u0435\u043D\u043D\u044B\u0439 \u0442\u0435\u043A\u0441\u0442 \u0438\u043B\u0438 \u0442\u0435\u043A\u0443\u0449\u0443\u044E \u0441\u0442\u0440\u043E\u043A\u0443", deleteBlankLine: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u043F\u0443\u0441\u0442\u044B\u0435 \u0441\u0442\u0440\u043E\u043A\u0438 \u0432 \u0432\u044B\u0434\u0435\u043B\u0435\u043D\u043D\u043E\u043C \u0438\u043B\u0438 \u0432\u0441\u0435\u0439 \u0441\u0442\u0430\u0442\u044C\u0435", insertCodeblock: "\u0412\u0441\u0442\u0430\u0432\u0438\u0442\u044C \u0431\u043B\u043E\u043A \u043A\u043E\u0434\u0430 \u0441/\u0431\u0435\u0437 \u0432\u044B\u0434\u0435\u043B\u0435\u043D\u0438\u0435\u043C", switchAutoformat: "\u041F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0438\u0442\u044C \u0430\u0432\u0442\u043E\u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435", pasteWithoutFormat: "\u0412\u0441\u0442\u0430\u0432\u0438\u0442\u044C \u0431\u0435\u0437 \u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F", toggleComment: "\u041F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0438\u0442\u044C \u043A\u043E\u043C\u043C\u0435\u043D\u0442\u0430\u0440\u0438\u0439", gotoNewLine: "\u041F\u0435\u0440\u0435\u0439\u0442\u0438 \u043A \u043D\u043E\u0432\u043E\u0439 \u0441\u0442\u0440\u043E\u043A\u0435 \u043F\u043E\u0441\u043B\u0435 \u0442\u0435\u043A\u0443\u0449\u0435\u0439", selectBlock: "\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0442\u0435\u043A\u0443\u0449\u0438\u0439 \u0442\u0435\u043A\u0441\u0442\u043E\u0432\u044B\u0439 \u0431\u043B\u043E\u043A" }, headers: { main: "\u041F\u043B\u0430\u0433\u0438\u043D Obsidian EasyTyping", githubDetail: "\u041F\u043E\u0434\u0440\u043E\u0431\u043D\u0435\u0435 \u043D\u0430 Github: ", enhancedEditing: "\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430 \u0443\u043B\u0443\u0447\u0448\u0435\u043D\u043D\u043E\u0433\u043E \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F", customizeEditRule: "\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430 \u043F\u0440\u0430\u0432\u0438\u043B\u0430 \u043F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u043E\u0432\u0430\u043D\u0438\u044F \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F", autoformatSetting: "\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430 \u0430\u0432\u0442\u043E\u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F", detailedSetting: "\u041F\u0440\u043E\u0431\u0435\u043B\u044B \u043C\u0435\u0436\u0434\u0443 \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u043C\u0438 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430\u043C\u0438", customRegexpBlock: "\u0411\u043B\u043E\u043A \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0445 \u0440\u0435\u0433\u0443\u043B\u044F\u0440\u043D\u044B\u0445 \u0432\u044B\u0440\u0430\u0436\u0435\u043D\u0438\u0439", excludeFoldersFiles: "\u0418\u0441\u043A\u043B\u044E\u0447\u0438\u0442\u044C \u043F\u0430\u043F\u043A\u0438/\u0444\u0430\u0439\u043B\u044B", experimentalFeatures: "\u042D\u043A\u0441\u043F\u0435\u0440\u0438\u043C\u0435\u043D\u0442\u0430\u043B\u044C\u043D\u044B\u0435 \u0444\u0443\u043D\u043A\u0446\u0438\u0438", languagePairSection: "\u0421\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044F \u043F\u0440\u043E\u0431\u0435\u043B\u043E\u0432 \u043C\u0435\u0436\u0434\u0443 \u044F\u0437\u044B\u043A\u0430\u043C\u0438", addLanguagePair: "\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u043D\u043E\u0432\u0443\u044E \u043F\u0430\u0440\u0443 \u044F\u0437\u044B\u043A\u043E\u0432/\u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432:", prefixDictSection: "\u0421\u043B\u043E\u0432\u0430\u0440\u044C \u043F\u0440\u0435\u0444\u0438\u043A\u0441\u043E\u0432", softSpaceSection: "\u0421\u0438\u043C\u0432\u043E\u043B\u044B \u043C\u044F\u0433\u043A\u043E\u0433\u043E \u043F\u0440\u043E\u0431\u0435\u043B\u0430", customScriptSection: "\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0435 \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u0438 \u0441\u043A\u0440\u0438\u043F\u0442\u043E\u0432", spaceStrategyIntro: "\u0421\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044F \u043F\u0440\u043E\u0431\u0435\u043B\u043E\u0432:\n\u041D\u0435\u0442 \u0442\u0440\u0435\u0431\u043E\u0432\u0430\u043D\u0438\u0439: \u041D\u0435\u0442 \u0442\u0440\u0435\u0431\u043E\u0432\u0430\u043D\u0438\u0439 \u043A \u043F\u0440\u043E\u0431\u0435\u043B\u0430\u043C \u043C\u0435\u0436\u0434\u0443 \u044D\u0442\u0438\u043C \u0431\u043B\u043E\u043A\u043E\u043C \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u0438 \u0438 \u043E\u043A\u0440\u0443\u0436\u0430\u044E\u0449\u0438\u043C \u0442\u0435\u043A\u0441\u0442\u043E\u043C.\n\u041C\u044F\u0433\u043A\u0438\u0439 \u043F\u0440\u043E\u0431\u0435\u043B: \u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044F \u0442\u043E\u043B\u044C\u043A\u043E \u043C\u044F\u0433\u043A\u0438\u0439 \u043F\u0440\u043E\u0431\u0435\u043B \u043C\u0435\u0436\u0434\u0443 \u044D\u0442\u0438\u043C \u0431\u043B\u043E\u043A\u043E\u043C \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u0438 \u0438 \u043E\u043A\u0440\u0443\u0436\u0430\u044E\u0449\u0438\u043C\u0438 \u0431\u043B\u043E\u043A\u0430\u043C\u0438.\n\u0421\u0442\u0440\u043E\u0433\u0438\u0439 \u043F\u0440\u043E\u0431\u0435\u043B: \u0421\u0442\u0440\u043E\u0433\u043E\u0435 \u0434\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u043F\u0440\u043E\u0431\u0435\u043B\u043E\u0432 \u043C\u0435\u0436\u0434\u0443 \u0442\u0435\u043A\u0443\u0449\u0438\u043C \u0431\u043B\u043E\u043A\u043E\u043C \u0438 \u043F\u0440\u0438\u043B\u0435\u0433\u0430\u044E\u0449\u0438\u043C \u0442\u0435\u043A\u0441\u0442\u043E\u043C.", aboutRegexp: { header: "\u0414\u043B\u044F \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0438 \u043E \u0440\u0435\u0433\u0443\u043B\u044F\u0440\u043D\u044B\u0445 \u0432\u044B\u0440\u0430\u0436\u0435\u043D\u0438\u044F\u0445 \u0441\u043C. ", text: "Yifeng Nguyen: \u041A\u0440\u0430\u0442\u043A\u043E\u0435 \u0440\u0443\u043A\u043E\u0432\u043E\u0434\u0441\u0442\u0432\u043E \u043F\u043E \u0440\u0435\u0433\u0443\u043B\u044F\u0440\u043D\u044B\u043C \u0432\u044B\u0440\u0430\u0436\u0435\u043D\u0438\u044F\u043C" }, customizeSelectionRule: "\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430 \u043F\u0440\u0430\u0432\u0438\u043B\u0430 \u0437\u0430\u043C\u0435\u043D\u044B \u0432\u044B\u0434\u0435\u043B\u0435\u043D\u043D\u043E\u0433\u043E \u0442\u0435\u043A\u0441\u0442\u0430", customizeDeleteRule: "\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430 \u043F\u0440\u0430\u0432\u0438\u043B\u0430 \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u044F", customizeConvertRule: "\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430 \u043F\u0440\u0430\u0432\u0438\u043B\u0430 \u043F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u043E\u0432\u0430\u043D\u0438\u044F", editSelectionReplaceRule: "\u0420\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435 \u043F\u0440\u0430\u0432\u0438\u043B\u0430 \u0437\u0430\u043C\u0435\u043D\u044B \u0432\u044B\u0434\u0435\u043B\u0435\u043D\u043D\u043E\u0433\u043E \u0442\u0435\u043A\u0441\u0442\u0430", builtinRulesSection: "\u0412\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u0435 \u043F\u0440\u0430\u0432\u0438\u043B\u0430", userRulesSection: "\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0435 \u043F\u0440\u0430\u0432\u0438\u043B\u0430", deletedRulesSection: "\u0423\u0434\u0430\u043B\u0451\u043D\u043D\u044B\u0435 \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u0435 \u043F\u0440\u0430\u0432\u0438\u043B\u0430", tabs: { editEnhance: "\u0420\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435", autoFormat: "\u0410\u0432\u0442\u043E\u0444\u043E\u0440\u043C\u0430\u0442", builtinRules: "\u0412\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u0435", userRules: "\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0435", other: "\u041F\u0440\u043E\u0447\u0435\u0435" } }, dropdownOptions: { enterTwice: "\u0414\u0432\u0430\u0436\u0434\u044B \u043D\u0430\u0436\u043C\u0438\u0442\u0435 Enter", twoSpace: "\u0414\u0432\u0430 \u043F\u0440\u043E\u0431\u0435\u043B\u0430", mixMode: "\u0421\u043C\u0435\u0448\u0430\u043D\u043D\u044B\u0439 \u0440\u0435\u0436\u0438\u043C", noRequire: "\u041D\u0435\u0442 \u0442\u0440\u0435\u0431\u043E\u0432\u0430\u043D\u0438\u0439", softSpace: "\u041C\u044F\u0433\u043A\u0438\u0439 \u043F\u0440\u043E\u0431\u0435\u043B", strictSpace: "\u0421\u0442\u0440\u043E\u0433\u0438\u0439 \u043F\u0440\u043E\u0431\u0435\u043B", dummy: "\u0424\u0438\u043A\u0442\u0438\u0432\u043D\u044B\u0439", smart: "\u0423\u043C\u043D\u044B\u0439", scopeAll: "\u0412\u0441\u0435", scopeText: "\u0422\u0435\u043A\u0441\u0442", scopeFormula: "\u0424\u043E\u0440\u043C\u0443\u043B\u0430", scopeCode: "\u041A\u043E\u0434", triggerModeAuto: "\u0410\u0432\u0442\u043E", triggerModeTab: "Tab", ruleTypeInput: "\u0412\u0432\u043E\u0434", ruleTypeDelete: "\u0423\u0434\u0430\u043B\u0435\u043D\u0438\u0435", ruleTypeSelectKey: "\u0417\u0430\u043C\u0435\u043D\u0430 \u0432\u044B\u0431\u043E\u0440\u0430" }, toolTip: { switch: "\u041F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0438\u0442\u044C", editRule: "\u0420\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u043F\u0440\u0430\u0432\u0438\u043B\u043E", removeRule: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u043F\u0440\u0430\u0432\u0438\u043B\u043E", addRule: "\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u043F\u0440\u0430\u0432\u0438\u043B\u043E", enableRule: "\u0412\u043A\u043B\u044E\u0447\u0438\u0442\u044C/\u0412\u044B\u043A\u043B\u044E\u0447\u0438\u0442\u044C \u043F\u0440\u0430\u0432\u0438\u043B\u043E", restoreRule: "\u0412\u043E\u0441\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C \u044D\u0442\u043E \u043F\u0440\u0430\u0432\u0438\u043B\u043E", resetAllRules: "\u0421\u0431\u0440\u043E\u0441\u0438\u0442\u044C \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u0435 \u043F\u0440\u0430\u0432\u0438\u043B\u0430", resetSuccess: "\u0412\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u0435 \u043F\u0440\u0430\u0432\u0438\u043B\u0430 \u0443\u0441\u043F\u0435\u0448\u043D\u043E \u0441\u0431\u0440\u043E\u0448\u0435\u043D\u044B", exportRules: "\u042D\u043A\u0441\u043F\u043E\u0440\u0442 \u043F\u0440\u0430\u0432\u0438\u043B", importRules: "\u0418\u043C\u043F\u043E\u0440\u0442 \u043F\u0440\u0430\u0432\u0438\u043B", noRulesToExport: "\u041D\u0435\u0442 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0445 \u043F\u0440\u0430\u0432\u0438\u043B \u0434\u043B\u044F \u044D\u043A\u0441\u043F\u043E\u0440\u0442\u0430", importSuccess: "\u0418\u043C\u043F\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u043E %d \u043F\u0440\u0430\u0432\u0438\u043B, \u043F\u0440\u043E\u043F\u0443\u0449\u0435\u043D\u043E %d \u0434\u0443\u0431\u043B\u0438\u043A\u0430\u0442\u043E\u0432", importInvalidJson: "\u041E\u0448\u0438\u0431\u043A\u0430 \u0444\u043E\u0440\u043C\u0430\u0442\u0430: \u043D\u0435\u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u044B\u0439 JSON", importNoRules: "\u0412 \u0444\u0430\u0439\u043B\u0435 \u043D\u0435\u0442 \u043F\u0440\u0430\u0432\u0438\u043B \u0434\u043B\u044F \u0438\u043C\u043F\u043E\u0440\u0442\u0430" }, placeHolder: { triggerSymbol: "\u0421\u0438\u043C\u0432\u043E\u043B \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430", newLeftSideString: "\u041D\u043E\u0432\u0430\u044F \u0441\u0442\u0440\u043E\u043A\u0430 \u0441 \u043B\u0435\u0432\u043E\u0439 \u0441\u0442\u043E\u0440\u043E\u043D\u044B", newRightSideString: "\u041D\u043E\u0432\u0430\u044F \u0441\u0442\u0440\u043E\u043A\u0430 \u0441 \u043F\u0440\u0430\u0432\u043E\u0439 \u0441\u0442\u043E\u0440\u043E\u043D\u044B", addRule: "\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u043F\u0440\u0430\u0432\u0438\u043B\u043E", noticeInvaidTrigger: "\u041D\u0435\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043B\u044C\u043D\u044B\u0439 \u0442\u0440\u0438\u0433\u0433\u0435\u0440, \u0442\u0440\u0438\u0433\u0433\u0435\u0440 \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u043C \u0434\u043B\u0438\u043D\u043E\u0439 1 \u0438\u043B\u0438 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u043C \u2014\u2014, \u2026\u2026", noticeWarnTriggerExists: "\u0412\u043D\u0438\u043C\u0430\u043D\u0438\u0435! \u0422\u0440\u0438\u0433\u0433\u0435\u0440 %s \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442!", noticeMissingInput: "\u041E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432\u0432\u043E\u0434", beforeDelete: "\u0414\u043E \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u044F", newPattern: "\u041D\u043E\u0432\u044B\u0439 \u0448\u0430\u0431\u043B\u043E\u043D", noticeInvaidTriggerPatternContainSymbol: "\u041D\u0435\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043B\u044C\u043D\u044B\u0439 \u0442\u0440\u0438\u0433\u0433\u0435\u0440, \u0448\u0430\u0431\u043B\u043E\u043D \u0434\u043E\u043B\u0436\u0435\u043D \u0441\u043E\u0434\u0435\u0440\u0436\u0430\u0442\u044C \u0441\u0438\u043C\u0432\u043E\u043B |, \u0443\u043A\u0430\u0437\u044B\u0432\u0430\u044E\u0449\u0438\u0439 \u043D\u0430 \u043F\u043E\u0437\u0438\u0446\u0438\u044E \u043A\u0443\u0440\u0441\u043E\u0440\u0430", beforeConvert: "\u0414\u043E \u043F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u043E\u0432\u0430\u043D\u0438\u044F", noticeInvalidPatternString: "\u041D\u0435\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u0441\u0442\u0440\u043E\u043A\u0430 \u0448\u0430\u0431\u043B\u043E\u043D\u0430!" }, button: { update: "\u041E\u0431\u043D\u043E\u0432\u0438\u0442\u044C" }, scriptCategoryLabels: { chinese: "\u041A\u0438\u0442\u0430\u0439\u0441\u043A\u0438\u0439", japanese: "\u042F\u043F\u043E\u043D\u0441\u043A\u0438\u0439", korean: "\u041A\u043E\u0440\u0435\u0439\u0441\u043A\u0438\u0439", cjk: "CJK", english: "\u0410\u043D\u0433\u043B\u0438\u0439\u0441\u043A\u0438\u0439", digit: "\u0426\u0438\u0444\u0440\u044B", russian: "\u0420\u0443\u0441\u0441\u043A\u0438\u0439", unknown: "\u041D\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043D\u044B\u0439" }, builtinRuleDescriptions: { "builtin-autopair-input": "\u0410\u0432\u0442\u043E\u0434\u043E\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u0435 \u043F\u0430\u0440\u043D\u044B\u0445 \u043F\u043E\u043B\u043D\u043E\u0448\u0438\u0440\u0438\u043D\u043D\u044B\u0445 \u0441\u043A\u043E\u0431\u043E\u043A/\u043A\u0430\u0432\u044B\u0447\u0435\u043A", "builtin-autopair-jump": "\u041F\u0435\u0440\u0435\u0441\u043A\u043E\u043A \u0447\u0435\u0440\u0435\u0437 \u0437\u0430\u043A\u0440\u044B\u0432\u0430\u044E\u0449\u0438\u0439 \u043F\u0430\u0440\u043D\u044B\u0439 \u0441\u0438\u043C\u0432\u043E\u043B", "builtin-autopair-delete": "\u0423\u0434\u0430\u043B\u0435\u043D\u0438\u0435 \u043E\u0431\u0435\u0438\u0445 \u0441\u0442\u043E\u0440\u043E\u043D \u043F\u0430\u0440\u043D\u044B\u0445 \u043F\u043E\u043B\u043D\u043E\u0448\u0438\u0440\u0438\u043D\u043D\u044B\u0445 \u0441\u043A\u043E\u0431\u043E\u043A/\u043A\u0430\u0432\u044B\u0447\u0435\u043A", "builtin-conv-backtick": "\u0414\u0432\u043E\u0439\u043D\u0430\u044F \u0441\u0440\u0435\u0434\u043D\u044F\u044F \u0442\u043E\u0447\u043A\u0430 \xB7\xB7 \u043F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u0443\u0435\u0442\u0441\u044F \u0432 \u0441\u0442\u0440\u043E\u0447\u043D\u044B\u0439 \u043A\u043E\u0434", "builtin-conv-codeblock": "\u0412\u0432\u043E\u0434 \xB7 \u0432 \u0441\u0442\u0440\u043E\u0447\u043D\u043E\u043C \u043A\u043E\u0434\u0435 \u043F\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0435\u0433\u043E \u0432 \u0431\u043B\u043E\u043A \u043A\u043E\u0434\u0430", "builtin-conv-formula": "\u041A\u043E\u043C\u0431\u0438\u043D\u0430\u0446\u0438\u0438 \uFFE5/$ \u043F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u0443\u044E\u0442\u0441\u044F \u0432 \u0441\u0442\u0440\u043E\u0447\u043D\u0443\u044E \u0438\u043B\u0438 \u0431\u043B\u043E\u0447\u043D\u0443\u044E \u0444\u043E\u0440\u043C\u0443\u043B\u0443", "builtin-conv-linestart": "\u300B \u0432 \u043D\u0430\u0447\u0430\u043B\u0435 \u0441\u0442\u0440\u043E\u043A\u0438 \u2192 \u0446\u0438\u0442\u0430\u0442\u0430, \u3001 \u0432 \u043D\u0430\u0447\u0430\u043B\u0435 \u0441\u0442\u0440\u043E\u043A\u0438 \u2192 \u043A\u043E\u0441\u0430\u044F \u0447\u0435\u0440\u0442\u0430", "builtin-conv-hw2fw": "\u041F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u043E\u0432\u0430\u043D\u0438\u0435 \u043F\u043E\u043B\u0443\u0448\u0438\u0440\u0438\u043D\u043D\u043E\u0439 \u043F\u0443\u043D\u043A\u0442\u0443\u0430\u0446\u0438\u0438 \u0432 \u043F\u043E\u043B\u043D\u043E\u0448\u0438\u0440\u0438\u043D\u043D\u0443\u044E \u043F\u043E\u0441\u043B\u0435 CJK-\u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432", "builtin-fw2hw-double": "\u0414\u0432\u043E\u0439\u043D\u0430\u044F \u043E\u0434\u0438\u043D\u0430\u043A\u043E\u0432\u0430\u044F \u043F\u043E\u043B\u043D\u043E\u0448\u0438\u0440\u0438\u043D\u043D\u0430\u044F \u043F\u0443\u043D\u043A\u0442\u0443\u0430\u0446\u0438\u044F \u043F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u0443\u0435\u0442\u0441\u044F \u0432 \u043F\u043E\u043B\u0443\u0448\u0438\u0440\u0438\u043D\u043D\u0443\u044E", "builtin-del-inline-formula": "\u0423\u0434\u0430\u043B\u0435\u043D\u0438\u0435 \u043F\u0430\u0440\u044B \u0441\u0442\u0440\u043E\u0447\u043D\u043E\u0439 \u0444\u043E\u0440\u043C\u0443\u043B\u044B $...$", "builtin-del-highlight": "\u0423\u0434\u0430\u043B\u0435\u043D\u0438\u0435 \u043F\u0430\u0440\u044B \u0432\u044B\u0434\u0435\u043B\u0435\u043D\u0438\u044F ==...==", "builtin-del-block-formula": "\u0423\u0434\u0430\u043B\u0435\u043D\u0438\u0435 \u043F\u0430\u0440\u044B \u0431\u043B\u043E\u0447\u043D\u043E\u0439 \u0444\u043E\u0440\u043C\u0443\u043B\u044B $$...$$", "builtin-del-codeblock": "\u0411\u044B\u0441\u0442\u0440\u043E\u0435 \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u0435 \u043F\u0443\u0441\u0442\u043E\u0433\u043E \u0431\u043B\u043E\u043A\u0430 \u043A\u043E\u0434\u0430", "builtin-del-wikilink": "\u0411\u044B\u0441\u0442\u0440\u043E\u0435 \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u0435 \u0432\u0438\u043A\u0438-\u0441\u0441\u044B\u043B\u043A\u0438 \u0438 \u0432\u0441\u0442\u0430\u0432\u043A\u0438 (![[]])", "builtin-sel-wrap-backtick": "\u041E\u0431\u0435\u0440\u043D\u0443\u0442\u044C \u0432\u044B\u0434\u0435\u043B\u0435\u043D\u0438\u0435 \u0432 \xB7 \u0432 \u043E\u0431\u0440\u0430\u0442\u043D\u044B\u0435 \u043A\u0430\u0432\u044B\u0447\u043A\u0438", "builtin-sel-wrap-symbols": "\u041E\u0431\u0435\u0440\u043D\u0443\u0442\u044C \u0432\u044B\u0434\u0435\u043B\u0435\u043D\u0438\u0435 \u0432 []/$ \u0441 \u043F\u043E\u043C\u043E\u0449\u044C\u044E \u3010/\xA5/\uFFE5", "builtin-sel-wrap-quotes": "\u041E\u0431\u0435\u0440\u043D\u0443\u0442\u044C \u0432\u044B\u0434\u0435\u043B\u0435\u043D\u0438\u0435 \u043F\u0430\u0440\u043D\u044B\u043C\u0438 \u043F\u043E\u043B\u043D\u043E\u0448\u0438\u0440\u0438\u043D\u043D\u044B\u043C\u0438 \u043A\u0430\u0432\u044B\u0447\u043A\u0430\u043C\u0438", "builtin-sel-wrap-cjk-brackets": "\u041E\u0431\u0435\u0440\u043D\u0443\u0442\u044C \u0432\u044B\u0434\u0435\u043B\u0435\u043D\u0438\u0435 \u0441\u043A\u043E\u0431\u043A\u0430\u043C\u0438 \u300A\u300B \u0438\u043B\u0438 \uFF08\uFF09", "builtin-quote-convert": "\u041F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u043E\u0432\u0430\u043D\u0438\u0435 > \u0438\u043B\u0438 \u300B \u0432 \u043C\u0430\u0440\u043A\u0435\u0440 \u0446\u0438\u0442\u0430\u0442\u044B Markdown", "builtin-quote-space": "\u0410\u0432\u0442\u043E\u0432\u0441\u0442\u0430\u0432\u043A\u0430 \u043F\u0440\u043E\u0431\u0435\u043B\u0430 \u043F\u043E\u0441\u043B\u0435 \u043C\u0430\u0440\u043A\u0435\u0440\u0430 \u0446\u0438\u0442\u0430\u0442\u044B >" } }; var ru_RU_default = locale4; // src/lang/locale/ja-JP.ts var locale5 = { settings: { smartPaste: { name: "\u30B9\u30DE\u30FC\u30C8\u8CBC\u308A\u4ED8\u3051", desc: "\u30EA\u30B9\u30C8\u3084\u5F15\u7528\u30D6\u30ED\u30C3\u30AF\u5185\u3067\u8CBC\u308A\u4ED8\u3051\u308B\u969B\u3001\u9069\u5207\u306A\u30A4\u30F3\u30C7\u30F3\u30C8\u3068\u30EA\u30B9\u30C8/\u5F15\u7528\u30DE\u30FC\u30AB\u30FC\u3092\u81EA\u52D5\u7684\u306B\u8FFD\u52A0\u3057\u307E\u3059\u3002" }, codeblockEdit: { name: "\u30B3\u30FC\u30C9\u30D6\u30ED\u30C3\u30AF\u7DE8\u96C6\u306E\u5F37\u5316", desc: "\u30B3\u30FC\u30C9\u30D6\u30ED\u30C3\u30AF\u5185\u306E\u7DE8\u96C6\u3092\u6539\u5584\u3057\u307E\u3059\uFF08Tab\u3001\u524A\u9664\u3001\u8CBC\u308A\u4ED8\u3051\u3001Cmd/Ctrl+A \u9078\u629E\uFF09\u3002" }, backspaceEdit: { name: "\u30B9\u30DE\u30FC\u30C8\u30D0\u30C3\u30AF\u30B9\u30DA\u30FC\u30B9", desc: "\u7A7A\u306E\u30EA\u30B9\u30C8\u9805\u76EE\u3084\u5F15\u7528\u884C\u3067\u306E\u30D0\u30C3\u30AF\u30B9\u30DA\u30FC\u30B9\u6A5F\u80FD\u3092\u5411\u4E0A\u3055\u305B\u307E\u3059\u3002" }, tabOut: { name: "Tab\u3067\u30DA\u30A2\u8A18\u53F7\u306E\u5916\u3078\u79FB\u52D5", desc: "Tab \u30AD\u30FC\u3092\u62BC\u3057\u3066\u3010\u3011\u3001\uFF08\uFF09\u3001\u300A\u300B\u3001\u5F15\u7528\u7B26\u3001\u30A4\u30F3\u30E9\u30A4\u30F3\u30B3\u30FC\u30C9\u306A\u3069\u306E\u30DA\u30A2\u8A18\u53F7\u306E\u5916\u3078\u30AB\u30FC\u30BD\u30EB\u3092\u79FB\u52D5\u3057\u307E\u3059\u3002" }, autoFormatting: { name: "\u5165\u529B\u6642\u306E\u81EA\u52D5\u66F8\u5F0F\u8A2D\u5B9A", desc: "\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u7DE8\u96C6\u4E2D\u306E\u30C6\u30AD\u30B9\u30C8\u81EA\u52D5\u66F8\u5F0F\u8A2D\u5B9A\u3092\u5207\u308A\u66FF\u3048\u307E\u3059\u3002" }, autoFormatPaste: { name: "\u8CBC\u308A\u4ED8\u3051\u6642\u306E\u81EA\u52D5\u66F8\u5F0F\u8A2D\u5B9A", desc: "\u8CBC\u308A\u4ED8\u3051\u6642\u306E\u81EA\u52D5\u66F8\u5F0F\u8A2D\u5B9A\u3092\u5207\u308A\u66FF\u3048\u307E\u3059\u3002CMD/CTRL+SHIFT+V\uFF08\u66F8\u5F0F\u306A\u3057\u8CBC\u308A\u4ED8\u3051\uFF09\u3067\u306F\u30C8\u30EA\u30AC\u30FC\u3055\u308C\u307E\u305B\u3093\u3002" }, languagePairSpacing: { name: "\u8A00\u8A9E\u30DA\u30A2\u30B9\u30DA\u30FC\u30B7\u30F3\u30B0", desc: "\u7570\u306A\u308B\u8A00\u8A9E/\u8A18\u53F7\u30DA\u30A2\u9593\u306E\u81EA\u52D5\u30B9\u30DA\u30FC\u30B7\u30F3\u30B0\u30EB\u30FC\u30EB\u3092\u5B9A\u7FA9\u3057\u307E\u3059\u3002" }, prefixDictionary: { name: "\u63A5\u982D\u8F9E\u8F9E\u66F8", desc: "\u30AB\u30F3\u30DE\u3001\u30B9\u30DA\u30FC\u30B9\u3001\u6539\u884C\u3067\u533A\u5207\u308A\u307E\u3059\u3002\u5358\u8A9E\u307E\u305F\u306F /\u6B63\u898F\u8868\u73FE/ \u306B\u5BFE\u5FDC\u3002\u30DE\u30C3\u30C1\u3057\u305F\u30C8\u30FC\u30AF\u30F3\u306B\u306F\u30B9\u30DA\u30FC\u30B9\u304C\u633F\u5165\u3055\u308C\u305A\u3001\u5165\u529B\u4E2D\u306E\u63A5\u982D\u8F9E\u3082\u30B9\u30DA\u30FC\u30B9\u633F\u5165\u304C\u6291\u5236\u3055\u308C\u307E\u3059\u3002" }, softSpaceSymbols: { leftName: "\u30AB\u30B9\u30BF\u30E0\u5DE6\u5074\u30BD\u30D5\u30C8\u30B9\u30DA\u30FC\u30B9\u8A18\u53F7", leftDesc: `\u4E00\u822C\u7684\u306A\u5168\u89D2\u53E5\u8AAD\u70B9\u3001\u82F1\u8A9E\u306E\u5F15\u7528\u7B26\uFF08' "\uFF09\u3001\u304A\u3088\u3073\u958B\u304D\u62EC\u5F27\uFF08[ ( {\uFF09\u306F\u5185\u8535\u3055\u308C\u3066\u3044\u307E\u3059\u3002\u3053\u3053\u306B\u8FFD\u52A0\u306E\u5DE6\u5074\u8A18\u53F7\u3092\u8FFD\u52A0\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u4F8B\uFF1A-\uFF09\u3002`, rightName: "\u30AB\u30B9\u30BF\u30E0\u53F3\u5074\u30BD\u30D5\u30C8\u30B9\u30DA\u30FC\u30B9\u8A18\u53F7", rightDesc: `\u4E00\u822C\u7684\u306A\u5168\u89D2\u53E5\u8AAD\u70B9\u3001\u82F1\u8A9E\u306E\u5F15\u7528\u7B26\uFF08' "\uFF09\u3001\u9589\u3058\u62EC\u5F27\uFF08] ) }\uFF09\u3001\u304A\u3088\u3073\u82F1\u8A9E\u306E\u534A\u89D2\u53E5\u8AAD\u70B9\uFF08. , ? ! : ;\uFF09\u306F\u53F3\u5074\u30BD\u30D5\u30C8\u30B9\u30DA\u30FC\u30B9\u8A18\u53F7\u3068\u3057\u3066\u5185\u8535\u3055\u308C\u3066\u3044\u307E\u3059\u3002\u3053\u3053\u306B\u8FFD\u52A0\u306E\u53F3\u5074\u8A18\u53F7\u3092\u8FFD\u52A0\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u4F8B\uFF1A-\uFF09\u3002` }, customScriptCategories: { name: "\u30AB\u30B9\u30BF\u30E0\u6587\u5B57\u30AB\u30C6\u30B4\u30EA", desc: "\u30B9\u30DA\u30FC\u30B7\u30F3\u30B0\u6226\u7565\u7528\u306E\u30AB\u30B9\u30BF\u30E0\u8A00\u8A9E\u307E\u305F\u306F\u8A18\u53F7\u30BB\u30C3\u30C8\u3092\u8FFD\u52A0\u3057\u307E\u3059\u3002", namePlaceholder: "\u540D\u524D", patternPlaceholder: "\u6587\u5B57\u30AF\u30E9\u30B9\u30D1\u30BF\u30FC\u30F3" }, capitalizeFirstLetter: { name: "\u6587\u982D\u306E\u5927\u6587\u5B57\u5316", desc: "\u82F1\u8A9E\u306E\u5404\u6587\u306E\u6700\u521D\u306E\u6587\u5B57\u3092\u5927\u6587\u5B57\u306B\u3057\u307E\u3059\u3002" }, spaceStrategyInlineCode: { name: "\u30A4\u30F3\u30E9\u30A4\u30F3\u30B3\u30FC\u30C9\u3068\u30C6\u30AD\u30B9\u30C8\u9593\u306E\u30B9\u30DA\u30FC\u30B7\u30F3\u30B0\u6226\u7565", desc: "\u30A4\u30F3\u30E9\u30A4\u30F3\u30B3\u30FC\u30C9\u3068\u30C6\u30AD\u30B9\u30C8\u9593\u306E\u30B9\u30DA\u30FC\u30B7\u30F3\u30B0\u6226\u7565\u3092\u5B9A\u7FA9\u3057\u307E\u3059\u3002" }, spaceStrategyInlineFormula: { name: "\u30A4\u30F3\u30E9\u30A4\u30F3\u6570\u5F0F\u3068\u30C6\u30AD\u30B9\u30C8\u9593\u306E\u30B9\u30DA\u30FC\u30B7\u30F3\u30B0\u6226\u7565", desc: "\u30A4\u30F3\u30E9\u30A4\u30F3\u6570\u5F0F\u3068\u30C6\u30AD\u30B9\u30C8\u9593\u306E\u30B9\u30DA\u30FC\u30B7\u30F3\u30B0\u6226\u7565\u3092\u5B9A\u7FA9\u3057\u307E\u3059\u3002" }, spaceStrategyLinkText: { name: "\u30EA\u30F3\u30AF\u3068\u30C6\u30AD\u30B9\u30C8\u9593\u306E\u30B9\u30DA\u30FC\u30B7\u30F3\u30B0\u6226\u7565", desc: "[[\u30A6\u30A3\u30AD\u30EA\u30F3\u30AF]] [\u30DE\u30FC\u30AF\u30C0\u30A6\u30F3\u30EA\u30F3\u30AF](...) \u3068\u30C6\u30AD\u30B9\u30C8\u9593\u306E\u30B9\u30DA\u30FC\u30B7\u30F3\u30B0\u6226\u7565\u3092\u5B9A\u7FA9\u3057\u307E\u3059\u3002" }, userDefinedRegexpSwitch: { name: "\u30E6\u30FC\u30B6\u30FC\u5B9A\u7FA9\u6B63\u898F\u8868\u73FE\u30B9\u30A4\u30C3\u30C1", desc: "\u30AB\u30B9\u30BF\u30E0\u6B63\u898F\u8868\u73FE\u3092\u6709\u52B9\u306B\u3057\u3001\u30DE\u30C3\u30C1\u3057\u305F\u30B3\u30F3\u30C6\u30F3\u30C4\u306E\u66F8\u5F0F\u8A2D\u5B9A\u3092\u9632\u6B62\u3057\u3001\u30DE\u30C3\u30C1\u3057\u305F\u30B3\u30F3\u30C6\u30F3\u30C4\u3068\u4ED6\u306E\u30C6\u30AD\u30B9\u30C8\u9593\u306E\u30B9\u30DA\u30FC\u30B7\u30F3\u30B0\u6226\u7565\u3092\u8A2D\u5B9A\u3057\u307E\u3059\u3002" }, userDefinedRegexp: { name: "\u30E6\u30FC\u30B6\u30FC\u5B9A\u7FA9\u6B63\u898F\u8868\u73FE\uFF081\u884C\u306B1\u3064\uFF09", desc: "\u30E6\u30FC\u30B6\u30FC\u5B9A\u7FA9\u306E\u6B63\u898F\u8868\u73FE\u3067\u3001\u30DE\u30C3\u30C1\u3057\u305F\u30B3\u30F3\u30C6\u30F3\u30C4\u306F\u66F8\u5F0F\u8A2D\u5B9A\u3055\u308C\u307E\u305B\u3093\u30021\u884C\u306B1\u3064\u306E\u5F0F\u3092\u8A18\u8FF0\u3057\u3001\u884C\u672B\u306B\u30B9\u30DA\u30FC\u30B9\u3092\u8FFD\u52A0\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002\u5404\u884C\u306E\u672B\u5C3E3\u6587\u5B57\u306F | \u30682\u3064\u306E\u30B9\u30DA\u30FC\u30B7\u30F3\u30B0\u6226\u7565\u8A18\u53F7\u3067\u56FA\u5B9A\u3055\u308C\u307E\u3059\u3002\u30B9\u30DA\u30FC\u30B7\u30F3\u30B0\u6226\u7565\u8A18\u53F7\u306F - = + \u3067\u3001\u305D\u308C\u305E\u308C\u30B9\u30DA\u30FC\u30B9\u4E0D\u8981(-)\u3001\u30BD\u30D5\u30C8\u30B9\u30DA\u30FC\u30B9(=)\u3001\u53B3\u5BC6\u30B9\u30DA\u30FC\u30B9(+)\u3092\u610F\u5473\u3057\u307E\u3059\u3002\u3053\u308C\u30892\u3064\u306E\u30B9\u30DA\u30FC\u30B7\u30F3\u30B0\u6226\u7565\u8A18\u53F7\u306F\u3001\u30DE\u30C3\u30C1\u30D6\u30ED\u30C3\u30AF\u306E\u5DE6\u53F3\u306E\u30B9\u30DA\u30FC\u30B7\u30F3\u30B0\u6226\u7565\u3067\u3059\u3002// \u3067\u59CB\u307E\u308B\u884C\u306F\u30B3\u30E1\u30F3\u30C8\u3068\u3057\u3066\u6271\u308F\u308C\u307E\u3059\u3002" }, userRulesRespectUserDefinedRegexBlocks: { name: "\u30E6\u30FC\u30B6\u30FC\u30EB\u30FC\u30EB\u306F\u30AB\u30B9\u30BF\u30E0\u6B63\u898F\u8868\u73FE\u30D6\u30ED\u30C3\u30AF\u3092\u5C0A\u91CD", desc: "\u6709\u52B9\u6642\u3001\u30AB\u30B9\u30BF\u30E0\u6B63\u898F\u8868\u73FE\u30D6\u30ED\u30C3\u30AF\u306B\u30DE\u30C3\u30C1\u3057\u305F\u30C6\u30AD\u30B9\u30C8\u306F\u81EA\u52D5\u30E6\u30FC\u30B6\u30FC\u30EB\u30FC\u30EB\u3092\u30C8\u30EA\u30AC\u30FC\u3057\u307E\u305B\u3093\u3002" }, excludeFoldersFiles: { name: "\u9664\u5916\u30D5\u30A9\u30EB\u30C0/\u30D5\u30A1\u30A4\u30EB", desc: "\u3053\u306E\u30D7\u30E9\u30B0\u30A4\u30F3\u306F\u5404\u884C\u3092\u9664\u5916\u30D5\u30A9\u30EB\u30C0\u307E\u305F\u306F\u30D5\u30A1\u30A4\u30EB\u3068\u3057\u3066\u89E3\u6790\u3057\u307E\u3059\u3002\u4F8B\uFF1ADailyNote/\u3001DailyNote/WeekNotes/\u3001DailyNote/test.md" }, fixMacOSContextMenu: { name: "macOS \u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u30E1\u30CB\u30E5\u30FC\u306E\u30AB\u30FC\u30BD\u30EB\u4F4D\u7F6E\u3092\u4FEE\u6B63\uFF08Obsidian\u306E\u518D\u8D77\u52D5\u304C\u5FC5\u8981\uFF09", desc: "macOS \u3067\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u30E1\u30CB\u30E5\u30FC\u3092\u547C\u3073\u51FA\u3057\u305F\u969B\u306B\u30AB\u30FC\u30BD\u30EB\u304C\u6B21\u306E\u884C\u306B\u30B8\u30E3\u30F3\u30D7\u3059\u308B\u554F\u984C\u3092\u4FEE\u6B63\u3057\u307E\u3059\uFF08Obsidian\u306E\u518D\u8D77\u52D5\u304C\u5FC5\u8981\uFF09\u3002" }, fixMicrosoftIME: { name: "Microsoft IME \u306E\u554F\u984C\u3092\u4FEE\u6B63", desc: "\u65E7\u30D0\u30FC\u30B8\u30E7\u30F3\u306E Microsoft IME \u306B\u5BFE\u5FDC\u3057\u307E\u3059\u3002" }, strictLineBreaks: { name: "\u53B3\u5BC6\u6539\u884C\u30E2\u30FC\u30C9", desc: "\u53B3\u5BC6\u6539\u884C\u30E2\u30FC\u30C9\u3067\u306F\u3001\u901A\u5E38\u306E\u30C6\u30AD\u30B9\u30C8\u884C\u3067 Enter \u30921\u56DE\u62BC\u3059\u3068\u30012\u3064\u306E\u6539\u884C\u307E\u305F\u306F2\u3064\u306E\u30B9\u30DA\u30FC\u30B9\u3068 Enter \u304C\u751F\u6210\u3055\u308C\u307E\u3059\u3002" }, enhanceModA: { name: "Ctrl/Cmd+A \u9078\u629E\u306E\u5F37\u5316", desc: "1\u56DE\u76EE\uFF1A\u73FE\u5728\u306E\u884C\u3092\u9078\u629E\u30012\u56DE\u76EE\uFF1A\u73FE\u5728\u306E\u30C6\u30AD\u30B9\u30C8\u30D6\u30ED\u30C3\u30AF\u3092\u9078\u629E\u30013\u56DE\u76EE\uFF1A\u5168\u30C6\u30AD\u30B9\u30C8\u3092\u9078\u629E\u3002" }, collapsePersistentEnter: { name: "\u6298\u308A\u305F\u305F\u307F\u6642\u306EEnter\u52D5\u4F5C\u7DAD\u6301", desc: "\u6298\u308A\u305F\u305F\u307E\u308C\u305F\u898B\u51FA\u3057\u3067 Enter \u3092\u62BC\u3059\u3068\u3001\u6298\u308A\u305F\u305F\u307F\u3092\u5C55\u958B\u305B\u305A\u306B\u4E0B\u306B\u540C\u30EC\u30D9\u30EB\u306E\u898B\u51FA\u3057\u3092\u633F\u5165\u3057\u307E\u3059\u3002" }, printDebugInfo: { name: "\u30B3\u30F3\u30BD\u30FC\u30EB\u306B\u30C7\u30D0\u30C3\u30B0\u60C5\u5831\u3092\u51FA\u529B", desc: "\u30B3\u30F3\u30BD\u30FC\u30EB\u306B\u30C7\u30D0\u30C3\u30B0\u60C5\u5831\u3092\u51FA\u529B\u3057\u307E\u3059\u3002" }, rulesStoragePath: { name: "\u30EB\u30FC\u30EB\u30D5\u30A1\u30A4\u30EB\u306E\u4FDD\u5B58\u30D1\u30B9", desc: "\u30EB\u30FC\u30EB\u30D5\u30A1\u30A4\u30EB\u306E\u4FDD\u5B58\u30D1\u30B9\u3092\u8A2D\u5B9A\u3057\u307E\u3059\uFF08\u30DC\u30EB\u30C8\u30EB\u30FC\u30C8\u304B\u3089\u306E\u76F8\u5BFE\u30D1\u30B9\uFF09\u3002\u30C7\u30D5\u30A9\u30EB\u30C8\u3092\u9078\u629E\u3059\u308B\u3068\u30D7\u30E9\u30B0\u30A4\u30F3\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306B\u4FDD\u5B58\u3055\u308C\u307E\u3059", defaultOption: "\u30C7\u30D5\u30A9\u30EB\u30C8\uFF08\u30D7\u30E9\u30B0\u30A4\u30F3\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\uFF09", migrateButton: "\u79FB\u884C", migrateDesc: "\u524D\u56DE\u8AAD\u307F\u8FBC\u3093\u3060\u30D1\u30B9\u304B\u3089\u73FE\u5728\u306E\u30D1\u30B9\u306B\u30EB\u30FC\u30EB\u30D5\u30A1\u30A4\u30EB\u3092\u79FB\u884C\u3057\u307E\u3059", migrateSuccess: "\u30EB\u30FC\u30EB\u30D5\u30A1\u30A4\u30EB\u306E\u79FB\u884C\u304C\u5B8C\u4E86\u3057\u307E\u3057\u305F" }, selectionReplaceRule: { name: "\u9078\u629E\u7F6E\u63DB\u30EB\u30FC\u30EB", desc: "\u30E6\u30FC\u30B6\u30FC\u5B9A\u7FA9\u306E\u9078\u629E\u7F6E\u63DB\u30EB\u30FC\u30EB" }, deleteRule: { name: "\u524A\u9664\u30EB\u30FC\u30EB", desc: "\u30EB\u30FC\u30EB\uFF1A| \u3067\u30AB\u30FC\u30BD\u30EB\u4F4D\u7F6E\u3092\u793A\u3057\u307E\u3059\u3002\u30D2\u30F3\u30C8\uFF1A| \u3092\u4F7F\u7528\u3057\u3066\u30AB\u30FC\u30BD\u30EB\u4F4D\u7F6E\u3092\u8868\u3057\u307E\u3059\u3002" }, convertRule: { name: "\u5909\u63DB\u30EB\u30FC\u30EB", desc: "\u30EB\u30FC\u30EB\uFF1A| \u3067\u30AB\u30FC\u30BD\u30EB\u4F4D\u7F6E\u3092\u793A\u3057\u307E\u3059\u3002\u30D2\u30F3\u30C8\uFF1A| \u3092\u4F7F\u7528\u3057\u3066\u30AB\u30FC\u30BD\u30EB\u4F4D\u7F6E\u3092\u8868\u3057\u307E\u3059\u3002" }, trigger: { name: "\u30C8\u30EA\u30AC\u30FC" }, left: { name: "\u5DE6" }, right: { name: "\u53F3" }, oldPattern: { name: "\u65E7\u30D1\u30BF\u30FC\u30F3" }, newPattern: { name: "\u65B0\u30D1\u30BF\u30FC\u30F3" }, ruleEditModal: { addTitle: "\u30EB\u30FC\u30EB\u3092\u8FFD\u52A0", editTitle: "\u30EB\u30FC\u30EB\u3092\u7DE8\u96C6", fieldType: "\u30BF\u30A4\u30D7", fieldTrigger: "\u30AB\u30FC\u30BD\u30EB\u524D\u30DE\u30C3\u30C1", fieldTriggerSelectKey: "\u30C8\u30EA\u30AC\u30FC\u30AD\u30FC", fieldTriggerRight: "\u30AB\u30FC\u30BD\u30EB\u5F8C\u30DE\u30C3\u30C1", hintTriggerEscape: "\\\\: \u30D0\u30C3\u30AF\u30B9\u30E9\u30C3\u30B7\u30E5\u3001\\n: \u6539\u884C\u3001\\t: \u30BF\u30D6", fieldReplacement: "\u7F6E\u63DB\u5185\u5BB9", fieldReplacementDescSelectKey: "${SEL}: \u9078\u629E\u3055\u308C\u305F\u30C6\u30AD\u30B9\u30C8\u3001${0:${SEL}}: \u30C6\u30AD\u30B9\u30C8\u3092\u9078\u629E\u3057\u307E\u3059\u3002", fieldReplacementDescInputDelete: "[[0]]: \u5DE6\u5074\u7B2C0\u30AD\u30E3\u30D7\u30C1\u30E3\u30B0\u30EB\u30FC\u30D7\u3001[[R1]]: \u53F3\u5074\u7B2C1\u30AD\u30E3\u30D7\u30C1\u30E3\u30B0\u30EB\u30FC\u30D7\u3002", fieldIsRegex: "\u6B63\u898F\u8868\u73FE\u3067\u30DE\u30C3\u30C1", fieldTriggerMode: "\u30C8\u30EA\u30AC\u30FC\u65B9\u5F0F", fieldScope: "\u30B9\u30B3\u30FC\u30D7", fieldScopeLanguage: "\u8A00\u8A9E\uFF08\u4EFB\u610F\uFF09", fieldRegexFlags: "\u6B63\u898F\u8868\u73FE\u30D5\u30E9\u30B0", fieldRegexFlagsDesc: "i / m / u \u306E\u307F\u5BFE\u5FDC\u3002\u4F8B: im", fieldPriority: "\u512A\u5148\u5EA6", fieldPriorityDesc: "\u6570\u5024\u304C\u5C0F\u3055\u3044\u307B\u3069\u512A\u5148\u5EA6\u304C\u9AD8\u3044\u3001\u30C7\u30D5\u30A9\u30EB\u30C8100", fieldDescription: "\u8AAC\u660E", buttonSave: "\u4FDD\u5B58", invalidRegex: "\u7121\u52B9\u306A\u6B63\u898F\u8868\u73FE", fieldIsFunction: "\u95A2\u6570\u3067\u7F6E\u63DB", functionHintInputDelete: "\u5F15\u6570: leftMatches (string[])\u3001rightMatches (string[])\u3002\u6587\u5B57\u5217\u307E\u305F\u306F undefined \u3092\u8FD4\u3057\u3066\u30B9\u30AD\u30C3\u30D7\u3002", functionHintSelectKey: "\u5F15\u6570: selectionText (string)\u3001key (string)\u3002\u6587\u5B57\u5217\u307E\u305F\u306F undefined \u3092\u8FD4\u3057\u3066\u30B9\u30AD\u30C3\u30D7\u3002", hintTabstop: "$0: \u30AB\u30FC\u30BD\u30EB\u4F4D\u7F6E\u3001$1/$2: Tab \u30B8\u30E3\u30F3\u30D7\u4F4D\u7F6E\u3001${1:text}: \u30B8\u30E3\u30F3\u30D7\u3057\u3066 text \u3092\u9078\u629E\u3002", functionPlaceholder: "// \u4F8B:\nconst d = new Date();\nreturn d.toISOString().slice(0,10) + '$0';", groupMatch: "\u30DE\u30C3\u30C1\u6761\u4EF6", groupReplacement: "\u7F6E\u63DB", groupOther: "\u305D\u306E\u4ED6" }, ruleType: { input: "\u5165\u529B", delete: "\u524A\u9664", selectKey: "\u9078\u629E\u7F6E\u63DB" } }, commands: { formatArticle: "\u73FE\u5728\u306E\u8A18\u4E8B\u3092\u66F8\u5F0F\u8A2D\u5B9A", formatSelection: "\u9078\u629E\u3057\u305F\u30C6\u30AD\u30B9\u30C8\u307E\u305F\u306F\u73FE\u5728\u306E\u884C\u3092\u66F8\u5F0F\u8A2D\u5B9A", deleteBlankLine: "\u9078\u629E\u7BC4\u56F2\u307E\u305F\u306F\u8A18\u4E8B\u5168\u4F53\u306E\u7A7A\u767D\u884C\u3092\u524A\u9664", insertCodeblock: "\u30B3\u30FC\u30C9\u30D6\u30ED\u30C3\u30AF\u3092\u633F\u5165", switchAutoformat: "\u81EA\u52D5\u66F8\u5F0F\u3092\u5207\u308A\u66FF\u3048", pasteWithoutFormat: "\u66F8\u5F0F\u306A\u3057\u3067\u8CBC\u308A\u4ED8\u3051", toggleComment: "\u30B3\u30E1\u30F3\u30C8\u3092\u5207\u308A\u66FF\u3048", gotoNewLine: "\u73FE\u5728\u306E\u884C\u306E\u5F8C\u306B\u65B0\u3057\u3044\u884C\u3078\u79FB\u52D5", selectBlock: "\u73FE\u5728\u306E\u30C6\u30AD\u30B9\u30C8\u30D6\u30ED\u30C3\u30AF\u3092\u9078\u629E" }, headers: { main: "Obsidian EasyTyping \u30D7\u30E9\u30B0\u30A4\u30F3", githubDetail: "\u8A73\u7D30\u306F Github \u3092\u3054\u89A7\u304F\u3060\u3055\u3044\uFF1A", enhancedEditing: "\u7DE8\u96C6\u5F37\u5316\u8A2D\u5B9A", customizeEditRule: "\u7DE8\u96C6\u5909\u63DB\u30EB\u30FC\u30EB\u306E\u30AB\u30B9\u30BF\u30DE\u30A4\u30BA", autoformatSetting: "\u81EA\u52D5\u66F8\u5F0F\u8A2D\u5B9A", detailedSetting: "\u30A4\u30F3\u30E9\u30A4\u30F3\u8981\u7D20\u9593\u306E\u30B9\u30DA\u30FC\u30B7\u30F3\u30B0", customRegexpBlock: "\u30AB\u30B9\u30BF\u30E0\u6B63\u898F\u8868\u73FE\u30D6\u30ED\u30C3\u30AF", excludeFoldersFiles: "\u9664\u5916\u30D5\u30A9\u30EB\u30C0/\u30D5\u30A1\u30A4\u30EB", experimentalFeatures: "\u5B9F\u9A13\u7684\u6A5F\u80FD", languagePairSection: "\u8A00\u8A9E\u30DA\u30A2\u30B9\u30DA\u30FC\u30B7\u30F3\u30B0", addLanguagePair: "\u65B0\u3057\u3044\u8A00\u8A9E/\u8A18\u53F7\u30DA\u30A2\u3092\u8FFD\u52A0\uFF1A", prefixDictSection: "\u63A5\u982D\u8F9E\u8F9E\u66F8", softSpaceSection: "\u30BD\u30D5\u30C8\u30B9\u30DA\u30FC\u30B9\u8A18\u53F7", customScriptSection: "\u30AB\u30B9\u30BF\u30E0\u6587\u5B57\u30AB\u30C6\u30B4\u30EA", spaceStrategyIntro: "\u30B9\u30DA\u30FC\u30B7\u30F3\u30B0\u6226\u7565\u306E\u8AAC\u660E\uFF1A\n\u4E0D\u8981\uFF1A\u3053\u306E\u30AB\u30C6\u30B4\u30EA\u30D6\u30ED\u30C3\u30AF\u3068\u5468\u56F2\u306E\u30C6\u30AD\u30B9\u30C8\u9593\u306B\u30B9\u30DA\u30FC\u30B7\u30F3\u30B0\u306F\u4E0D\u8981\u3067\u3059\u3002\n\u30BD\u30D5\u30C8\u30B9\u30DA\u30FC\u30B9\uFF1A\u3053\u306E\u30AB\u30C6\u30B4\u30EA\u30D6\u30ED\u30C3\u30AF\u3068\u5468\u56F2\u306E\u30D6\u30ED\u30C3\u30AF\u9593\u306B\u30BD\u30D5\u30C8\u30B9\u30DA\u30FC\u30B9\u306E\u307F\u5FC5\u8981\u3067\u3059\uFF08\u4F8B\uFF1A\u96A3\u63A5\u30C6\u30AD\u30B9\u30C8\u304C\u53E5\u8AAD\u70B9\u306E\u5834\u5408\u3001\u5B9F\u969B\u306E\u30B9\u30DA\u30FC\u30B9\u306F\u8FFD\u52A0\u3055\u308C\u307E\u305B\u3093\uFF09\u3002\n\u53B3\u5BC6\u30B9\u30DA\u30FC\u30B9\uFF1A\u73FE\u5728\u306E\u30D6\u30ED\u30C3\u30AF\u3068\u96A3\u63A5\u30C6\u30AD\u30B9\u30C8\u9593\u306B\u53B3\u5BC6\u306B\u5B9F\u969B\u306E\u30B9\u30DA\u30FC\u30B9\u3092\u8FFD\u52A0\u3057\u307E\u3059\u3002", aboutRegexp: { header: "\u6B63\u898F\u8868\u73FE\u306B\u3064\u3044\u3066\u306E\u8A73\u7D30\u306F\u4EE5\u4E0B\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\uFF1A", text: "\u6B63\u898F\u8868\u73FE\u306E\u7C21\u6F54\u306A\u30C1\u30E5\u30FC\u30C8\u30EA\u30A2\u30EB" }, customizeSelectionRule: "\u9078\u629E\u7F6E\u63DB\u30EB\u30FC\u30EB\u306E\u30AB\u30B9\u30BF\u30DE\u30A4\u30BA", customizeDeleteRule: "\u524A\u9664\u30EB\u30FC\u30EB\u306E\u30AB\u30B9\u30BF\u30DE\u30A4\u30BA", customizeConvertRule: "\u5909\u63DB\u30EB\u30FC\u30EB\u306E\u30AB\u30B9\u30BF\u30DE\u30A4\u30BA", editSelectionReplaceRule: "\u9078\u629E\u7F6E\u63DB\u30EB\u30FC\u30EB\u306E\u7DE8\u96C6", builtinRulesSection: "\u7D44\u307F\u8FBC\u307F\u30EB\u30FC\u30EB", userRulesSection: "\u30E6\u30FC\u30B6\u30FC\u30EB\u30FC\u30EB", deletedRulesSection: "\u524A\u9664\u3055\u308C\u305F\u7D44\u307F\u8FBC\u307F\u30EB\u30FC\u30EB", tabs: { editEnhance: "\u7DE8\u96C6\u5F37\u5316", autoFormat: "\u81EA\u52D5\u66F8\u5F0F", builtinRules: "\u7D44\u307F\u8FBC\u307F\u30EB\u30FC\u30EB", userRules: "\u30E6\u30FC\u30B6\u30FC\u30EB\u30FC\u30EB", other: "\u305D\u306E\u4ED6" } }, dropdownOptions: { enterTwice: "Enter 2\u56DE", twoSpace: "\u30B9\u30DA\u30FC\u30B92\u3064", mixMode: "\u30DF\u30C3\u30AF\u30B9\u30E2\u30FC\u30C9", noRequire: "\u4E0D\u8981", softSpace: "\u30BD\u30D5\u30C8\u30B9\u30DA\u30FC\u30B9", strictSpace: "\u53B3\u5BC6\u30B9\u30DA\u30FC\u30B9", dummy: "\u30C0\u30DF\u30FC", smart: "\u30B9\u30DE\u30FC\u30C8", scopeAll: "\u3059\u3079\u3066", scopeText: "\u30C6\u30AD\u30B9\u30C8", scopeFormula: "\u6570\u5F0F", scopeCode: "\u30B3\u30FC\u30C9", triggerModeAuto: "\u81EA\u52D5", triggerModeTab: "Tab", ruleTypeInput: "\u5165\u529B", ruleTypeDelete: "\u524A\u9664", ruleTypeSelectKey: "\u9078\u629E\u7F6E\u63DB" }, toolTip: { switch: "\u30B9\u30A4\u30C3\u30C1", editRule: "\u30EB\u30FC\u30EB\u3092\u7DE8\u96C6", removeRule: "\u30EB\u30FC\u30EB\u3092\u524A\u9664", addRule: "\u30EB\u30FC\u30EB\u3092\u8FFD\u52A0", enableRule: "\u30EB\u30FC\u30EB\u306E\u6709\u52B9\u5316/\u7121\u52B9\u5316", restoreRule: "\u3053\u306E\u30EB\u30FC\u30EB\u3092\u5FA9\u5143", resetAllRules: "\u3059\u3079\u3066\u306E\u7D44\u307F\u8FBC\u307F\u30EB\u30FC\u30EB\u3092\u30EA\u30BB\u30C3\u30C8", resetSuccess: "\u7D44\u307F\u8FBC\u307F\u30EB\u30FC\u30EB\u304C\u6B63\u5E38\u306B\u30EA\u30BB\u30C3\u30C8\u3055\u308C\u307E\u3057\u305F", exportRules: "\u30EB\u30FC\u30EB\u3092\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8", importRules: "\u30EB\u30FC\u30EB\u3092\u30A4\u30F3\u30DD\u30FC\u30C8", noRulesToExport: "\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u3059\u308B\u30E6\u30FC\u30B6\u30FC\u30EB\u30FC\u30EB\u304C\u3042\u308A\u307E\u305B\u3093", importSuccess: "%d\u4EF6\u306E\u30EB\u30FC\u30EB\u3092\u30A4\u30F3\u30DD\u30FC\u30C8\u3057\u3001%d\u4EF6\u306E\u91CD\u8907\u3092\u30B9\u30AD\u30C3\u30D7\u3057\u307E\u3057\u305F", importInvalidJson: "\u7121\u52B9\u306A\u30D5\u30A1\u30A4\u30EB\uFF1A\u6709\u52B9\u306AJSON\u3067\u306F\u3042\u308A\u307E\u305B\u3093", importNoRules: "\u30D5\u30A1\u30A4\u30EB\u306B\u30A4\u30F3\u30DD\u30FC\u30C8\u53EF\u80FD\u306A\u30EB\u30FC\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093" }, placeHolder: { triggerSymbol: "\u30C8\u30EA\u30AC\u30FC\u8A18\u53F7", newLeftSideString: "\u65B0\u3057\u3044\u5DE6\u5074\u6587\u5B57\u5217", newRightSideString: "\u65B0\u3057\u3044\u53F3\u5074\u6587\u5B57\u5217", addRule: "\u30EB\u30FC\u30EB\u3092\u8FFD\u52A0", noticeInvaidTrigger: "\u7121\u52B9\u306A\u30C8\u30EA\u30AC\u30FC\u3067\u3059\u3002\u30C8\u30EA\u30AC\u30FC\u306F\u9577\u30551\u306E\u8A18\u53F7\u307E\u305F\u306F \u2014\u2014\u3001\u2026\u2026 \u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059", noticeWarnTriggerExists: "\u8B66\u544A\uFF01\u30C8\u30EA\u30AC\u30FC %s \u306F\u65E2\u306B\u5B58\u5728\u3057\u307E\u3059\uFF01", noticeMissingInput: "\u5165\u529B\u304C\u4E0D\u8DB3\u3057\u3066\u3044\u307E\u3059", beforeDelete: "\u524A\u9664\u524D", newPattern: "\u65B0\u3057\u3044\u30D1\u30BF\u30FC\u30F3", noticeInvaidTriggerPatternContainSymbol: "\u7121\u52B9\u306A\u30C8\u30EA\u30AC\u30FC\u3067\u3059\u3002\u30D1\u30BF\u30FC\u30F3\u306B\u306F\u30AB\u30FC\u30BD\u30EB\u4F4D\u7F6E\u3092\u793A\u3059\u8A18\u53F7 | \u304C\u542B\u307E\u308C\u3066\u3044\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059", beforeConvert: "\u5909\u63DB\u524D", noticeInvalidPatternString: "\u7121\u52B9\u306A\u30D1\u30BF\u30FC\u30F3\u6587\u5B57\u5217\u3067\u3059\uFF01" }, button: { update: "\u66F4\u65B0" }, scriptCategoryLabels: { chinese: "\u4E2D\u56FD\u8A9E", japanese: "\u65E5\u672C\u8A9E", korean: "\u97D3\u56FD\u8A9E", cjk: "CJK", english: "\u82F1\u8A9E", digit: "\u6570\u5B57", russian: "\u30ED\u30B7\u30A2\u8A9E", unknown: "\u4E0D\u660E" }, builtinRuleDescriptions: { "builtin-autopair-input": "\u5168\u89D2\u62EC\u5F27/\u5F15\u7528\u7B26\u306E\u5165\u529B\u6642\u306B\u81EA\u52D5\u88DC\u5B8C", "builtin-autopair-jump": "\u9589\u3058\u30DA\u30A2\u8A18\u53F7\u306E\u5165\u529B\u6642\u306B\u81EA\u52D5\u30B9\u30AD\u30C3\u30D7\u3057\u3066\u91CD\u8907\u3092\u9632\u6B62", "builtin-autopair-delete": "\u5168\u89D2\u62EC\u5F27/\u5F15\u7528\u7B26\u306E\u524A\u9664\u6642\u306B\u30DA\u30A2\u3054\u3068\u524A\u9664", "builtin-conv-backtick": "\u4E2D\u70B9 \xB7\xB7 \u306E\u9023\u7D9A\u5165\u529B\u3067\u30A4\u30F3\u30E9\u30A4\u30F3\u30B3\u30FC\u30C9\u306B\u5909\u63DB", "builtin-conv-codeblock": "\u30A4\u30F3\u30E9\u30A4\u30F3\u30B3\u30FC\u30C9\u5185\u3067 \xB7 \u3092\u5165\u529B\u3059\u308B\u3068\u30B3\u30FC\u30C9\u30D6\u30ED\u30C3\u30AF\u306B\u30A2\u30C3\u30D7\u30B0\u30EC\u30FC\u30C9", "builtin-conv-formula": "\uFFE5/$ \u306E\u7D44\u307F\u5408\u308F\u305B\u3067\u30A4\u30F3\u30E9\u30A4\u30F3\u307E\u305F\u306F\u30D6\u30ED\u30C3\u30AF\u6570\u5F0F\u306B\u5909\u63DB", "builtin-conv-linestart": "\u884C\u982D\u306E \u300B \u2192 \u5F15\u7528\u30DE\u30FC\u30AB\u30FC\u3001\u3001 \u2192 \u30B9\u30E9\u30C3\u30B7\u30E5", "builtin-conv-hw2fw": "CJK\u6587\u5B57\u306E\u5F8C\u306E\u534A\u89D2\u53E5\u8AAD\u70B9\u3092\u5168\u89D2\u306B\u5909\u63DB", "builtin-fw2hw-double": "\u540C\u3058\u5168\u89D2\u53E5\u8AAD\u70B9\u30922\u56DE\u5165\u529B\u3059\u308B\u3068\u534A\u89D2\u306B\u5909\u63DB", "builtin-del-inline-formula": "\u30A4\u30F3\u30E9\u30A4\u30F3\u6570\u5F0F $...$ \u306E\u30DA\u30A2\u3092\u524A\u9664", "builtin-del-highlight": "\u30CF\u30A4\u30E9\u30A4\u30C8 ==...== \u306E\u30DA\u30A2\u3092\u524A\u9664", "builtin-del-block-formula": "\u30D6\u30ED\u30C3\u30AF\u6570\u5F0F $$...$$ \u306E\u30DA\u30A2\u3092\u524A\u9664", "builtin-del-codeblock": "\u7A7A\u306E\u30B3\u30FC\u30C9\u30D6\u30ED\u30C3\u30AF\u3092\u3059\u3070\u3084\u304F\u524A\u9664", "builtin-del-wikilink": "\u30A6\u30A3\u30AD\u30EA\u30F3\u30AF\u3068\u57CB\u3081\u8FBC\u307F(![[]])\u3092\u3059\u3070\u3084\u304F\u524A\u9664", "builtin-sel-wrap-backtick": "\xB7 \u3067\u9078\u629E\u30C6\u30AD\u30B9\u30C8\u3092\u30D0\u30C3\u30AF\u30AF\u30A9\u30FC\u30C8\u3067\u56F2\u3080", "builtin-sel-wrap-symbols": "\u9078\u629E\u30C6\u30AD\u30B9\u30C8\u3092\u3010/\xA5/\uFFE5\u3067 []/$$\u3067\u56F2\u3080", "builtin-sel-wrap-quotes": "\u9078\u629E\u30C6\u30AD\u30B9\u30C8\u3092\u5168\u89D2\u5F15\u7528\u7B26\u3067\u56F2\u3080", "builtin-sel-wrap-cjk-brackets": "\u9078\u629E\u30C6\u30AD\u30B9\u30C8\u3092\u300A\u300B\u307E\u305F\u306F\uFF08\uFF09\u62EC\u5F27\u3067\u56F2\u3080", "builtin-quote-convert": "> \u307E\u305F\u306F \u300B\u3092 Markdown \u5F15\u7528\u30DE\u30FC\u30AB\u30FC\u306B\u5909\u63DB", "builtin-quote-space": "\u5F15\u7528\u30DE\u30FC\u30AB\u30FC > \u306E\u5F8C\u306B\u30B9\u30DA\u30FC\u30B9\u3092\u81EA\u52D5\u633F\u5165" } }; var ja_JP_default = locale5; // src/lang/locale/ko-KR.ts var locale6 = { settings: { smartPaste: { name: "\uC2A4\uB9C8\uD2B8 \uBD99\uC5EC\uB123\uAE30", desc: "\uBAA9\uB85D\uC774\uB098 \uC778\uC6A9 \uBE14\uB85D\uC5D0\uC11C \uBD99\uC5EC\uB123\uC744 \uB54C \uC801\uC808\uD55C \uB4E4\uC5EC\uC4F0\uAE30\uC640 \uBAA9\uB85D/\uC778\uC6A9 \uAE30\uD638\uB97C \uC790\uB3D9\uC73C\uB85C \uCD94\uAC00\uD569\uB2C8\uB2E4." }, codeblockEdit: { name: "\uCF54\uB4DC \uBE14\uB85D \uD3B8\uC9D1 \uAC15\uD654", desc: "\uCF54\uB4DC \uBE14\uB85D \uB0B4 \uD3B8\uC9D1 \uAE30\uB2A5 \uAC15\uD654 (Tab, \uC0AD\uC81C, \uBD99\uC5EC\uB123\uAE30, Cmd/Ctrl+A \uC120\uD0DD)" }, backspaceEdit: { name: "\uC2A4\uB9C8\uD2B8 \uBC31\uC2A4\uD398\uC774\uC2A4", desc: "\uBE48 \uBAA9\uB85D \uD56D\uBAA9\uC774\uB098 \uBE48 \uC778\uC6A9 \uC904\uC5D0\uC11C \uBC31\uC2A4\uD398\uC774\uC2A4 \uAE30\uB2A5\uC744 \uD5A5\uC0C1\uC2DC\uD0B5\uB2C8\uB2E4." }, tabOut: { name: "Tab\uC73C\uB85C \uC30D \uAE30\uD638 \uBC16\uC73C\uB85C \uC774\uB3D9", desc: "Tab \uD0A4\uB97C \uB20C\uB7EC \u3010\u3011, \uFF08\uFF09, \u300A\u300B, \uB530\uC634\uD45C, \uC778\uB77C\uC778 \uCF54\uB4DC \uB4F1\uC758 \uC30D \uAE30\uD638 \uBC16\uC73C\uB85C \uCEE4\uC11C\uB97C \uC774\uB3D9\uD569\uB2C8\uB2E4." }, autoFormatting: { name: "\uC785\uB825 \uC2DC \uC790\uB3D9 \uC11C\uC2DD", desc: "\uBB38\uC11C \uD3B8\uC9D1 \uC911 \uD14D\uC2A4\uD2B8 \uC790\uB3D9 \uC11C\uC2DD \uC9C0\uC815\uC744 \uCF1C\uAC70\uB098 \uB055\uB2C8\uB2E4." }, autoFormatPaste: { name: "\uBD99\uC5EC\uB123\uAE30 \uC2DC \uC790\uB3D9 \uC11C\uC2DD", desc: "\uBD99\uC5EC\uB123\uAE30 \uC2DC \uC790\uB3D9 \uC11C\uC2DD\uC744 \uCF1C\uAC70\uB098 \uB055\uB2C8\uB2E4. CMD/CTRL+SHIFT+V(\uC11C\uC2DD \uC5C6\uC774 \uBD99\uC5EC\uB123\uAE30)\uC5D0\uC11C\uB294 \uC791\uB3D9\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4." }, languagePairSpacing: { name: "\uC5B8\uC5B4 \uC30D \uAC04\uACA9", desc: "\uC11C\uB85C \uB2E4\uB978 \uC5B8\uC5B4/\uAE30\uD638 \uC30D \uC0AC\uC774\uC758 \uC790\uB3D9 \uAC04\uACA9 \uADDC\uCE59\uC744 \uC815\uC758\uD569\uB2C8\uB2E4." }, prefixDictionary: { name: "\uC811\uB450\uC0AC \uC0AC\uC804", desc: "\uC27C\uD45C, \uACF5\uBC31 \uB610\uB294 \uC904\uBC14\uAFC8\uC73C\uB85C \uAD6C\uBD84\uD569\uB2C8\uB2E4. \uB2E8\uC5B4 \uB610\uB294 /\uC815\uADDC\uC2DD/\uC744 \uC9C0\uC6D0\uD569\uB2C8\uB2E4. \uB9E4\uCE6D\uB41C \uD1A0\uD070\uC5D0\uB294 \uACF5\uBC31\uC774 \uC0BD\uC785\uB418\uC9C0 \uC54A\uC73C\uBA70, \uC785\uB825 \uC911\uC778 \uC811\uB450\uC0AC\uB3C4 \uACF5\uBC31 \uC0BD\uC785\uC774 \uC5B5\uC81C\uB429\uB2C8\uB2E4." }, softSpaceSymbols: { leftName: "\uC0AC\uC6A9\uC790 \uC815\uC758 \uC67C\uCABD \uC18C\uD504\uD2B8 \uC2A4\uD398\uC774\uC2A4 \uAE30\uD638", leftDesc: `\uC77C\uBC18\uC801\uC778 \uC804\uAC01 \uBB38\uC7A5\uBD80\uD638, \uC601\uBB38 \uC778\uC6A9\uBD80\uD638(' "), \uC5EC\uB294 \uAD04\uD638([ ( {)\uAC00 \uB0B4\uC7A5\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4. \uC5EC\uAE30\uC5D0 \uCD94\uAC00 \uC67C\uCABD \uAE30\uD638\uB97C \uCD94\uAC00\uD558\uC138\uC694 (\uC608: -).`, rightName: "\uC0AC\uC6A9\uC790 \uC815\uC758 \uC624\uB978\uCABD \uC18C\uD504\uD2B8 \uC2A4\uD398\uC774\uC2A4 \uAE30\uD638", rightDesc: `\uC77C\uBC18\uC801\uC778 \uC804\uAC01 \uBB38\uC7A5\uBD80\uD638, \uC601\uBB38 \uC778\uC6A9\uBD80\uD638(' "), \uB2EB\uB294 \uAD04\uD638(] ) }), \uADF8\uB9AC\uACE0 \uC601\uBB38 \uBC18\uAC01 \uBB38\uC7A5\uBD80\uD638(. , ? ! : ;)\uAC00 \uC624\uB978\uCABD \uC18C\uD504\uD2B8 \uC2A4\uD398\uC774\uC2A4 \uAE30\uD638\uB85C \uB0B4\uC7A5\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4. \uC5EC\uAE30\uC5D0 \uCD94\uAC00 \uC624\uB978\uCABD \uAE30\uD638\uB97C \uCD94\uAC00\uD558\uC138\uC694 (\uC608: -).` }, customScriptCategories: { name: "\uC0AC\uC6A9\uC790 \uC815\uC758 \uBB38\uC790 \uBC94\uC8FC", desc: "\uAC04\uACA9 \uC804\uB7B5\uC744 \uC704\uD55C \uC0AC\uC6A9\uC790 \uC815\uC758 \uC5B8\uC5B4 \uB610\uB294 \uAE30\uD638 \uC9D1\uD569\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4.", namePlaceholder: "\uC774\uB984", patternPlaceholder: "\uBB38\uC790 \uD074\uB798\uC2A4 \uD328\uD134" }, capitalizeFirstLetter: { name: "\uBB38\uC7A5 \uCCAB \uAE00\uC790 \uB300\uBB38\uC790\uD654", desc: "\uC601\uC5B4 \uBB38\uC7A5\uC758 \uCCAB \uAE00\uC790\uB97C \uB300\uBB38\uC790\uB85C \uBCC0\uD658\uD569\uB2C8\uB2E4." }, spaceStrategyInlineCode: { name: "\uC778\uB77C\uC778 \uCF54\uB4DC\uC640 \uD14D\uC2A4\uD2B8 \uC0AC\uC774 \uAC04\uACA9 \uC804\uB7B5", desc: "\uC778\uB77C\uC778 \uCF54\uB4DC\uC640 \uD14D\uC2A4\uD2B8 \uC0AC\uC774\uC758 \uAC04\uACA9 \uC804\uB7B5\uC744 \uC815\uC758\uD569\uB2C8\uB2E4." }, spaceStrategyInlineFormula: { name: "\uC778\uB77C\uC778 \uC218\uC2DD\uACFC \uD14D\uC2A4\uD2B8 \uC0AC\uC774 \uAC04\uACA9 \uC804\uB7B5", desc: "\uC778\uB77C\uC778 \uC218\uC2DD\uACFC \uD14D\uC2A4\uD2B8 \uC0AC\uC774\uC758 \uAC04\uACA9 \uC804\uB7B5\uC744 \uC815\uC758\uD569\uB2C8\uB2E4." }, spaceStrategyLinkText: { name: "\uB9C1\uD06C\uC640 \uD14D\uC2A4\uD2B8 \uC0AC\uC774 \uAC04\uACA9 \uC804\uB7B5", desc: "[[\uC704\uD0A4\uB9C1\uD06C]] [\uB9C8\uD06C\uB2E4\uC6B4 \uB9C1\uD06C](...) \uC640 \uD14D\uC2A4\uD2B8 \uC0AC\uC774\uC758 \uAC04\uACA9 \uC804\uB7B5\uC744 \uC815\uC758\uD569\uB2C8\uB2E4." }, userDefinedRegexpSwitch: { name: "\uC0AC\uC6A9\uC790 \uC815\uC758 \uC815\uADDC\uC2DD \uC2A4\uC704\uCE58", desc: "\uC0AC\uC6A9\uC790 \uC815\uC758 \uC815\uADDC\uC2DD\uC744 \uD65C\uC131\uD654\uD558\uC5EC \uB9E4\uCE6D\uB41C \uCF58\uD150\uCE20\uC758 \uC11C\uC2DD\uC744 \uBC29\uC9C0\uD558\uACE0, \uB9E4\uCE6D\uB41C \uCF58\uD150\uCE20\uC640 \uB2E4\uB978 \uD14D\uC2A4\uD2B8 \uC0AC\uC774\uC758 \uAC04\uACA9 \uC804\uB7B5\uC744 \uC124\uC815\uD569\uB2C8\uB2E4." }, userDefinedRegexp: { name: "\uC0AC\uC6A9\uC790 \uC815\uC758 \uC815\uADDC\uC2DD, \uD55C \uC904\uC5D0 \uD558\uB098\uC529", desc: "\uC0AC\uC6A9\uC790 \uC815\uC758 \uC815\uADDC\uC2DD\uC73C\uB85C \uB9E4\uCE6D\uB41C \uCF58\uD150\uCE20\uB294 \uC11C\uC2DD\uC774 \uC801\uC6A9\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uD55C \uC904\uC5D0 \uD558\uB098\uC529 \uC791\uC131\uD558\uBA70, \uC904 \uB05D\uC5D0 \uACF5\uBC31\uC744 \uCD94\uAC00\uD558\uC9C0 \uB9C8\uC138\uC694.\uAC01 \uC904\uC758 \uB9C8\uC9C0\uB9C9 3\uC790\uB294 |\uC640 \uB450 \uAC1C\uC758 \uAC04\uACA9 \uC804\uB7B5 \uAE30\uD638\uB85C \uACE0\uC815\uB429\uB2C8\uB2E4. \uAC04\uACA9 \uC804\uB7B5 \uAE30\uD638\uB294 - = +\uC774\uBA70, \uAC01\uAC01 \uAC04\uACA9 \uBD88\uD544\uC694(-), \uC18C\uD504\uD2B8\uC6E8\uC5B4 \uC2A4\uD398\uC774\uC2A4(=), \uC5C4\uACA9\uD55C \uC2A4\uD398\uC774\uC2A4(+)\uB97C \uC758\uBBF8\uD569\uB2C8\uB2E4.\uC774 \uB450 \uAC04\uACA9 \uC804\uB7B5 \uAE30\uD638\uB294 \uB9E4\uCE6D \uBE14\uB85D\uC758 \uC67C\uCABD\uACFC \uC624\uB978\uCABD\uC758 \uAC04\uACA9 \uC804\uB7B5\uC785\uB2C8\uB2E4. // \uB85C \uC2DC\uC791\uD558\uB294 \uC904\uC740 \uC8FC\uC11D\uC73C\uB85C \uCC98\uB9AC\uB429\uB2C8\uB2E4." }, userRulesRespectUserDefinedRegexBlocks: { name: "\uC0AC\uC6A9\uC790 \uADDC\uCE59\uC774 \uCEE4\uC2A4\uD140 \uC815\uADDC\uC2DD \uBE14\uB85D\uC744 \uC900\uC218", desc: "\uD65C\uC131\uD654 \uC2DC \uCEE4\uC2A4\uD140 \uC815\uADDC\uC2DD \uBE14\uB85D\uC5D0 \uB9E4\uCE6D\uB41C \uD14D\uC2A4\uD2B8\uB294 \uC790\uB3D9 \uC0AC\uC6A9\uC790 \uADDC\uCE59\uC744 \uD2B8\uB9AC\uAC70\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4." }, excludeFoldersFiles: { name: "\uC81C\uC678 \uD3F4\uB354/\uD30C\uC77C", desc: "\uC774 \uD50C\uB7EC\uADF8\uC778\uC740 \uAC01 \uC904\uC744 \uC81C\uC678 \uD3F4\uB354 \uB610\uB294 \uD30C\uC77C\uB85C \uD30C\uC2F1\uD569\uB2C8\uB2E4. \uC608: DailyNote/, DailyNote/WeekNotes/, DailyNote/test.md" }, fixMacOSContextMenu: { name: "macOS \uCEE8\uD14D\uC2A4\uD2B8 \uBA54\uB274 \uCEE4\uC11C \uC704\uCE58 \uC218\uC815 (Obsidian \uC7AC\uC2DC\uC791 \uD544\uC694)", desc: "macOS\uC5D0\uC11C \uCEE8\uD14D\uC2A4\uD2B8 \uBA54\uB274 \uD638\uCD9C \uC2DC \uCEE4\uC11C\uAC00 \uB2E4\uC74C \uC904\uB85C \uC774\uB3D9\uD558\uB294 \uBB38\uC81C\uB97C \uC218\uC815\uD569\uB2C8\uB2E4 (Obsidian \uC7AC\uC2DC\uC791 \uD544\uC694)." }, fixMicrosoftIME: { name: "Microsoft \uC785\uB825\uAE30 \uBB38\uC81C \uC218\uC815", desc: "\uC774\uC804 \uBC84\uC804\uC758 Microsoft \uC785\uB825\uAE30\uC5D0 \uB300\uD55C \uD638\uD658\uC131 \uCC98\uB9AC." }, strictLineBreaks: { name: "\uC5C4\uACA9\uD55C \uC904\uBC14\uAFC8 \uBAA8\uB4DC", desc: "\uC5C4\uACA9\uD55C \uC904\uBC14\uAFC8 \uBAA8\uB4DC\uC5D0\uC11C \uC77C\uBC18 \uD14D\uC2A4\uD2B8 \uC904\uC5D0\uC11C Enter\uB97C \uD55C \uBC88 \uB204\uB974\uBA74 \uB450 \uBC88\uC758 \uC904\uBC14\uAFC8 \uB610\uB294 \uB450 \uAC1C\uC758 \uACF5\uBC31\uACFC Enter\uAC00 \uC0DD\uC131\uB429\uB2C8\uB2E4." }, enhanceModA: { name: "Ctrl/Cmd+A \uC120\uD0DD \uAC15\uD654", desc: "\uCCAB \uBC88\uC9F8: \uD604\uC7AC \uC904 \uC120\uD0DD, \uB450 \uBC88\uC9F8: \uD604\uC7AC \uD14D\uC2A4\uD2B8 \uBE14\uB85D \uC120\uD0DD, \uC138 \uBC88\uC9F8: \uC804\uCCB4 \uD14D\uC2A4\uD2B8 \uC120\uD0DD." }, collapsePersistentEnter: { name: "\uC811\uD78C \uC0C1\uD0DC\uC5D0\uC11C Enter \uC720\uC9C0", desc: "\uC811\uD78C \uC81C\uBAA9\uC5D0\uC11C Enter\uB97C \uB204\uB974\uBA74 \uC811\uD798\uC744 \uD3BC\uCE58\uC9C0 \uC54A\uACE0 \uC544\uB798\uC5D0 \uAC19\uC740 \uC218\uC900\uC758 \uC81C\uBAA9\uC744 \uC0BD\uC785\uD569\uB2C8\uB2E4." }, printDebugInfo: { name: "\uCF58\uC194\uC5D0 \uB514\uBC84\uADF8 \uC815\uBCF4 \uCD9C\uB825", desc: "\uCF58\uC194\uC5D0 \uB514\uBC84\uADF8 \uC815\uBCF4\uB97C \uCD9C\uB825\uD569\uB2C8\uB2E4." }, rulesStoragePath: { name: "\uADDC\uCE59 \uD30C\uC77C \uC800\uC7A5 \uACBD\uB85C", desc: "\uADDC\uCE59 \uD30C\uC77C\uC758 \uC800\uC7A5 \uACBD\uB85C\uB97C \uC124\uC815\uD569\uB2C8\uB2E4 (\uBCFC\uD2B8 \uB8E8\uD2B8 \uAE30\uC900 \uC0C1\uB300 \uACBD\uB85C). \uAE30\uBCF8\uAC12\uC744 \uC120\uD0DD\uD558\uBA74 \uD50C\uB7EC\uADF8\uC778 \uB514\uB809\uD130\uB9AC\uC5D0 \uC800\uC7A5\uB429\uB2C8\uB2E4", defaultOption: "\uAE30\uBCF8\uAC12 (\uD50C\uB7EC\uADF8\uC778 \uB514\uB809\uD130\uB9AC)", migrateButton: "\uB9C8\uC774\uADF8\uB808\uC774\uC158", migrateDesc: "\uC774\uC804\uC5D0 \uB85C\uB4DC\uD55C \uACBD\uB85C\uC5D0\uC11C \uD604\uC7AC \uACBD\uB85C\uB85C \uADDC\uCE59 \uD30C\uC77C\uC744 \uB9C8\uC774\uADF8\uB808\uC774\uC158\uD569\uB2C8\uB2E4", migrateSuccess: "\uADDC\uCE59 \uD30C\uC77C\uC774 \uC131\uACF5\uC801\uC73C\uB85C \uB9C8\uC774\uADF8\uB808\uC774\uC158\uB418\uC5C8\uC2B5\uB2C8\uB2E4" }, selectionReplaceRule: { name: "\uC120\uD0DD \uB300\uCCB4 \uADDC\uCE59", desc: "\uC0AC\uC6A9\uC790 \uC815\uC758 \uC120\uD0DD \uB300\uCCB4 \uADDC\uCE59" }, deleteRule: { name: "\uC0AD\uC81C \uADDC\uCE59", desc: "\uADDC\uCE59: |\uB85C \uCEE4\uC11C \uC704\uCE58\uB97C \uD45C\uC2DC\uD569\uB2C8\uB2E4. \uD301: |\uB97C \uC0AC\uC6A9\uD558\uC5EC \uCEE4\uC11C \uC704\uCE58\uB97C \uB098\uD0C0\uB0C5\uB2C8\uB2E4." }, convertRule: { name: "\uBCC0\uD658 \uADDC\uCE59", desc: "\uADDC\uCE59: |\uB85C \uCEE4\uC11C \uC704\uCE58\uB97C \uD45C\uC2DC\uD569\uB2C8\uB2E4. \uD301: |\uB97C \uC0AC\uC6A9\uD558\uC5EC \uCEE4\uC11C \uC704\uCE58\uB97C \uB098\uD0C0\uB0C5\uB2C8\uB2E4." }, trigger: { name: "\uD2B8\uB9AC\uAC70" }, left: { name: "\uC67C\uCABD" }, right: { name: "\uC624\uB978\uCABD" }, oldPattern: { name: "\uC774\uC804 \uD328\uD134" }, newPattern: { name: "\uC0C8 \uD328\uD134" }, ruleEditModal: { addTitle: "\uADDC\uCE59 \uCD94\uAC00", editTitle: "\uADDC\uCE59 \uD3B8\uC9D1", fieldType: "\uC720\uD615", fieldTrigger: "\uCEE4\uC11C \uC55E \uB9E4\uCE6D", fieldTriggerSelectKey: "\uD2B8\uB9AC\uAC70 \uD0A4", fieldTriggerRight: "\uCEE4\uC11C \uB4A4 \uB9E4\uCE6D", hintTriggerEscape: "\\\\: \uBC31\uC2AC\uB798\uC2DC, \\n: \uC904\uBC14\uAFC8, \\t: \uD0ED", fieldReplacement: "\uB300\uCCB4 \uB0B4\uC6A9", fieldReplacementDescSelectKey: "${SEL}: \uC120\uD0DD\uB41C \uD14D\uC2A4\uD2B8, ${0:${SEL}}: \uD14D\uC2A4\uD2B8\uB97C \uC120\uD0DD\uD569\uB2C8\uB2E4.", fieldReplacementDescInputDelete: "[[0]]: \uC67C\uCABD 0\uBC88\uC9F8 \uCEA1\uCC98 \uADF8\uB8F9, [[R1]]: \uC624\uB978\uCABD 1\uBC88\uC9F8 \uCEA1\uCC98 \uADF8\uB8F9.", fieldIsRegex: "\uC815\uADDC\uC2DD\uC73C\uB85C \uB9E4\uCE6D", fieldTriggerMode: "\uD2B8\uB9AC\uAC70 \uBC29\uC2DD", fieldScope: "\uBC94\uC704", fieldScopeLanguage: "\uC5B8\uC5B4 (\uC120\uD0DD\uC0AC\uD56D)", fieldRegexFlags: "\uC815\uADDC\uC2DD \uD50C\uB798\uADF8", fieldRegexFlagsDesc: "i / m / u \uB9CC \uC9C0\uC6D0, \uC608: im", fieldPriority: "\uC6B0\uC120\uC21C\uC704", fieldPriorityDesc: "\uC22B\uC790\uAC00 \uC791\uC744\uC218\uB85D \uC6B0\uC120\uC21C\uC704\uAC00 \uB192\uC74C, \uAE30\uBCF8\uAC12 100", fieldDescription: "\uC124\uBA85", buttonSave: "\uC800\uC7A5", invalidRegex: "\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uC815\uADDC\uC2DD", fieldIsFunction: "\uD568\uC218\uB85C \uB300\uCCB4", functionHintInputDelete: "\uC778\uC218: leftMatches (string[]), rightMatches (string[]). \uBB38\uC790\uC5F4 \uB610\uB294 undefined\uB97C \uBC18\uD658\uD558\uC5EC \uAC74\uB108\uB701\uB2C8\uB2E4.", functionHintSelectKey: "\uC778\uC218: selectionText (string), key (string). \uBB38\uC790\uC5F4 \uB610\uB294 undefined\uB97C \uBC18\uD658\uD558\uC5EC \uAC74\uB108\uB701\uB2C8\uB2E4.", hintTabstop: "$0: \uCEE4\uC11C \uC704\uCE58, $1/$2: Tab \uC810\uD504 \uC704\uCE58, ${1:text}: \uC810\uD504 \uD6C4 text \uC120\uD0DD.", functionPlaceholder: "// \uC608\uC2DC:\nconst d = new Date();\nreturn d.toISOString().slice(0,10) + '$0';", groupMatch: "\uB9E4\uCE6D \uC870\uAC74", groupReplacement: "\uB300\uCCB4", groupOther: "\uAE30\uD0C0" }, ruleType: { input: "\uC785\uB825", delete: "\uC0AD\uC81C", selectKey: "\uC120\uD0DD \uB300\uCCB4" } }, commands: { formatArticle: "\uD604\uC7AC \uBB38\uC11C \uC11C\uC2DD \uC9C0\uC815", formatSelection: "\uC120\uD0DD\uD55C \uD14D\uC2A4\uD2B8 \uB610\uB294 \uD604\uC7AC \uC904 \uC11C\uC2DD \uC9C0\uC815", deleteBlankLine: "\uC120\uD0DD \uC601\uC5ED \uB610\uB294 \uC804\uCCB4 \uBB38\uC11C\uC758 \uBE48 \uC904 \uC0AD\uC81C", insertCodeblock: "\uCF54\uB4DC \uBE14\uB85D \uC0BD\uC785", switchAutoformat: "\uC790\uB3D9 \uC11C\uC2DD \uC804\uD658", pasteWithoutFormat: "\uC11C\uC2DD \uC5C6\uC774 \uBD99\uC5EC\uB123\uAE30", toggleComment: "\uC8FC\uC11D \uC804\uD658", gotoNewLine: "\uD604\uC7AC \uC904 \uB2E4\uC74C\uC5D0 \uC0C8 \uC904\uB85C \uC774\uB3D9", selectBlock: "\uD604\uC7AC \uD14D\uC2A4\uD2B8 \uBE14\uB85D \uC120\uD0DD" }, headers: { main: "Obsidian EasyTyping \uD50C\uB7EC\uADF8\uC778", githubDetail: "\uC790\uC138\uD55C \uB0B4\uC6A9\uC740 Github\uB97C \uCC38\uC870\uD558\uC138\uC694: ", enhancedEditing: "\uD3B8\uC9D1 \uAC15\uD654 \uC124\uC815", customizeEditRule: "\uD3B8\uC9D1 \uBCC0\uD658 \uADDC\uCE59 \uC0AC\uC6A9\uC790 \uC815\uC758", autoformatSetting: "\uC790\uB3D9 \uC11C\uC2DD \uC124\uC815", detailedSetting: "\uC778\uB77C\uC778 \uC694\uC18C \uAC04 \uAC04\uACA9", customRegexpBlock: "\uC0AC\uC6A9\uC790 \uC815\uC758 \uC815\uADDC\uC2DD \uBE14\uB85D", excludeFoldersFiles: "\uC81C\uC678 \uD3F4\uB354/\uD30C\uC77C", experimentalFeatures: "\uC2E4\uD5D8\uC801 \uAE30\uB2A5", languagePairSection: "\uC5B8\uC5B4 \uC30D \uAC04\uACA9", addLanguagePair: "\uC0C8 \uC5B8\uC5B4/\uAE30\uD638 \uC30D \uCD94\uAC00:", prefixDictSection: "\uC811\uB450\uC0AC \uC0AC\uC804", softSpaceSection: "\uC18C\uD504\uD2B8 \uC2A4\uD398\uC774\uC2A4 \uAE30\uD638", customScriptSection: "\uC0AC\uC6A9\uC790 \uC815\uC758 \uBB38\uC790 \uBC94\uC8FC", spaceStrategyIntro: "\uAC04\uACA9 \uC804\uB7B5 \uC124\uBA85:\n\uBD88\uD544\uC694: \uC774 \uBC94\uC8FC \uBE14\uB85D\uACFC \uC8FC\uBCC0 \uD14D\uC2A4\uD2B8 \uC0AC\uC774\uC5D0 \uAC04\uACA9\uC774 \uD544\uC694 \uC5C6\uC2B5\uB2C8\uB2E4.\n\uC18C\uD504\uD2B8 \uC2A4\uD398\uC774\uC2A4: \uC774 \uBC94\uC8FC \uBE14\uB85D\uACFC \uC8FC\uBCC0 \uBE14\uB85D \uC0AC\uC774\uC5D0 \uC18C\uD504\uD2B8 \uC2A4\uD398\uC774\uC2A4\uB9CC \uD544\uC694\uD569\uB2C8\uB2E4 (\uC608: \uC778\uC811 \uD14D\uC2A4\uD2B8\uAC00 \uBB38\uC7A5\uBD80\uD638\uC778 \uACBD\uC6B0 \uC2E4\uC81C \uACF5\uBC31\uC774 \uCD94\uAC00\uB418\uC9C0 \uC54A\uC74C).\n\uC5C4\uACA9\uD55C \uC2A4\uD398\uC774\uC2A4: \uD604\uC7AC \uBE14\uB85D\uACFC \uC778\uC811 \uD14D\uC2A4\uD2B8 \uC0AC\uC774\uC5D0 \uC5C4\uACA9\uD558\uAC8C \uC2E4\uC81C \uACF5\uBC31\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4.", aboutRegexp: { header: "\uC815\uADDC\uC2DD\uC5D0 \uB300\uD55C \uC790\uC138\uD55C \uB0B4\uC6A9\uC740 \uB2E4\uC74C\uC744 \uCC38\uC870\uD558\uC138\uC694: ", text: "\uC815\uADDC\uC2DD \uAC04\uACB0 \uD29C\uD1A0\uB9AC\uC5BC" }, customizeSelectionRule: "\uC120\uD0DD \uB300\uCCB4 \uADDC\uCE59 \uC0AC\uC6A9\uC790 \uC815\uC758", customizeDeleteRule: "\uC0AD\uC81C \uADDC\uCE59 \uC0AC\uC6A9\uC790 \uC815\uC758", customizeConvertRule: "\uBCC0\uD658 \uADDC\uCE59 \uC0AC\uC6A9\uC790 \uC815\uC758", editSelectionReplaceRule: "\uC120\uD0DD \uB300\uCCB4 \uADDC\uCE59 \uD3B8\uC9D1", builtinRulesSection: "\uB0B4\uC7A5 \uADDC\uCE59", userRulesSection: "\uC0AC\uC6A9\uC790 \uADDC\uCE59", deletedRulesSection: "\uC0AD\uC81C\uB41C \uB0B4\uC7A5 \uADDC\uCE59", tabs: { editEnhance: "\uD3B8\uC9D1 \uAC15\uD654", autoFormat: "\uC790\uB3D9 \uC11C\uC2DD", builtinRules: "\uB0B4\uC7A5 \uADDC\uCE59", userRules: "\uC0AC\uC6A9\uC790 \uADDC\uCE59", other: "\uAE30\uD0C0" } }, dropdownOptions: { enterTwice: "Enter \uB450 \uBC88", twoSpace: "\uACF5\uBC31 \uB450 \uAC1C", mixMode: "\uD63C\uD569 \uBAA8\uB4DC", noRequire: "\uBD88\uD544\uC694", softSpace: "\uC18C\uD504\uD2B8 \uC2A4\uD398\uC774\uC2A4", strictSpace: "\uC5C4\uACA9\uD55C \uC2A4\uD398\uC774\uC2A4", dummy: "\uB354\uBBF8", smart: "\uC2A4\uB9C8\uD2B8", scopeAll: "\uC804\uCCB4", scopeText: "\uD14D\uC2A4\uD2B8", scopeFormula: "\uC218\uC2DD", scopeCode: "\uCF54\uB4DC", triggerModeAuto: "\uC790\uB3D9", triggerModeTab: "Tab", ruleTypeInput: "\uC785\uB825", ruleTypeDelete: "\uC0AD\uC81C", ruleTypeSelectKey: "\uC120\uD0DD \uB300\uCCB4" }, toolTip: { switch: "\uC2A4\uC704\uCE58", editRule: "\uADDC\uCE59 \uD3B8\uC9D1", removeRule: "\uADDC\uCE59 \uC0AD\uC81C", addRule: "\uADDC\uCE59 \uCD94\uAC00", enableRule: "\uADDC\uCE59 \uD65C\uC131\uD654/\uBE44\uD65C\uC131\uD654", restoreRule: "\uC774 \uADDC\uCE59 \uBCF5\uC6D0", resetAllRules: "\uBAA8\uB4E0 \uB0B4\uC7A5 \uADDC\uCE59 \uCD08\uAE30\uD654", resetSuccess: "\uB0B4\uC7A5 \uADDC\uCE59\uC774 \uC131\uACF5\uC801\uC73C\uB85C \uCD08\uAE30\uD654\uB418\uC5C8\uC2B5\uB2C8\uB2E4", exportRules: "\uADDC\uCE59 \uB0B4\uBCF4\uB0B4\uAE30", importRules: "\uADDC\uCE59 \uAC00\uC838\uC624\uAE30", noRulesToExport: "\uB0B4\uBCF4\uB0BC \uC0AC\uC6A9\uC790 \uADDC\uCE59\uC774 \uC5C6\uC2B5\uB2C8\uB2E4", importSuccess: "%d\uAC1C \uADDC\uCE59\uC744 \uAC00\uC838\uC654\uC73C\uBA70, %d\uAC1C \uC911\uBCF5 \uADDC\uCE59\uC744 \uAC74\uB108\uB6F0\uC5C8\uC2B5\uB2C8\uB2E4", importInvalidJson: "\uC798\uBABB\uB41C \uD30C\uC77C: \uC720\uD6A8\uD55C JSON\uC774 \uC544\uB2D9\uB2C8\uB2E4", importNoRules: "\uD30C\uC77C\uC5D0\uC11C \uAC00\uC838\uC62C \uC218 \uC788\uB294 \uADDC\uCE59\uC774 \uC5C6\uC2B5\uB2C8\uB2E4" }, placeHolder: { triggerSymbol: "\uD2B8\uB9AC\uAC70 \uAE30\uD638", newLeftSideString: "\uC0C8 \uC67C\uCABD \uBB38\uC790\uC5F4", newRightSideString: "\uC0C8 \uC624\uB978\uCABD \uBB38\uC790\uC5F4", addRule: "\uADDC\uCE59 \uCD94\uAC00", noticeInvaidTrigger: "\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uD2B8\uB9AC\uAC70, \uD2B8\uB9AC\uAC70\uB294 \uAE38\uC774 1\uC758 \uAE30\uD638 \uB610\uB294 \u2014\u2014, \u2026\u2026 \uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4", noticeWarnTriggerExists: "\uACBD\uACE0! \uD2B8\uB9AC\uAC70 %s \uC774(\uAC00) \uC774\uBBF8 \uC874\uC7AC\uD569\uB2C8\uB2E4!", noticeMissingInput: "\uC785\uB825\uC774 \uB204\uB77D\uB418\uC5C8\uC2B5\uB2C8\uB2E4", beforeDelete: "\uC0AD\uC81C \uC804", newPattern: "\uC0C8 \uD328\uD134", noticeInvaidTriggerPatternContainSymbol: "\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uD2B8\uB9AC\uAC70, \uD328\uD134\uC5D0 \uCEE4\uC11C \uC704\uCE58\uB97C \uB098\uD0C0\uB0B4\uB294 \uAE30\uD638 |\uAC00 \uD3EC\uD568\uB418\uC5B4\uC57C \uD569\uB2C8\uB2E4", beforeConvert: "\uBCC0\uD658 \uC804", noticeInvalidPatternString: "\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uD328\uD134 \uBB38\uC790\uC5F4\uC785\uB2C8\uB2E4!" }, button: { update: "\uC5C5\uB370\uC774\uD2B8" }, scriptCategoryLabels: { chinese: "\uC911\uAD6D\uC5B4", japanese: "\uC77C\uBCF8\uC5B4", korean: "\uD55C\uAD6D\uC5B4", cjk: "CJK", english: "\uC601\uC5B4", digit: "\uC22B\uC790", russian: "\uB7EC\uC2DC\uC544\uC5B4", unknown: "\uC54C \uC218 \uC5C6\uC74C" }, builtinRuleDescriptions: { "builtin-autopair-input": "\uC804\uAC01 \uAD04\uD638/\uB530\uC634\uD45C \uC785\uB825 \uC2DC \uC790\uB3D9 \uC644\uC131", "builtin-autopair-jump": "\uB2EB\uB294 \uC30D \uAE30\uD638\uB97C \uC785\uB825\uD560 \uB54C \uC790\uB3D9\uC73C\uB85C \uAC74\uB108\uB6F0\uC5B4 \uC911\uBCF5 \uBC29\uC9C0", "builtin-autopair-delete": "\uC804\uAC01 \uAD04\uD638/\uB530\uC634\uD45C \uC0AD\uC81C \uC2DC \uC30D\uC73C\uB85C \uC0AD\uC81C", "builtin-conv-backtick": "\uC911\uAC04\uC810 \xB7\xB7 \uC5F0\uC18D \uC785\uB825 \uC2DC \uC778\uB77C\uC778 \uCF54\uB4DC\uB85C \uBCC0\uD658", "builtin-conv-codeblock": "\uC778\uB77C\uC778 \uCF54\uB4DC \uB0B4\uC5D0\uC11C \xB7 \uC785\uB825 \uC2DC \uCF54\uB4DC \uBE14\uB85D\uC73C\uB85C \uC5C5\uADF8\uB808\uC774\uB4DC", "builtin-conv-formula": "\uFFE5/$ \uC870\uD569\uC73C\uB85C \uC778\uB77C\uC778 \uB610\uB294 \uBE14\uB85D \uC218\uC2DD\uC73C\uB85C \uBCC0\uD658", "builtin-conv-linestart": "\uC904 \uC2DC\uC791\uC5D0\uC11C \u300B \u2192 \uC778\uC6A9 \uD45C\uC2DC, \u3001 \u2192 \uC2AC\uB798\uC2DC", "builtin-conv-hw2fw": "CJK \uBB38\uC790 \uB4A4 \uBC18\uAC01 \uBB38\uC7A5\uBD80\uD638\uB97C \uC804\uAC01\uC73C\uB85C \uBCC0\uD658", "builtin-fw2hw-double": "\uB3D9\uC77C\uD55C \uC804\uAC01 \uBB38\uC7A5\uBD80\uD638 \uB450 \uBC88 \uC785\uB825 \uC2DC \uBC18\uAC01\uC73C\uB85C \uBCC0\uD658", "builtin-del-inline-formula": "\uC778\uB77C\uC778 \uC218\uC2DD $...$ \uC30D \uC0AD\uC81C", "builtin-del-highlight": "\uD558\uC774\uB77C\uC774\uD2B8 ==...== \uC30D \uC0AD\uC81C", "builtin-del-block-formula": "\uBE14\uB85D \uC218\uC2DD $$...$$ \uC30D \uC0AD\uC81C", "builtin-del-codeblock": "\uBE48 \uCF54\uB4DC \uBE14\uB85D \uBE60\uB978 \uC0AD\uC81C", "builtin-del-wikilink": "\uC704\uD0A4\uB9C1\uD06C \uBC0F \uC784\uBCA0\uB4DC(![[]]) \uBE60\uB978 \uC0AD\uC81C", "builtin-sel-wrap-backtick": "\xB7 \uB85C \uC120\uD0DD \uD14D\uC2A4\uD2B8\uB97C \uBC31\uD2F1\uC73C\uB85C \uAC10\uC2F8\uAE30", "builtin-sel-wrap-symbols": "\uC120\uD0DD\uD55C \uD14D\uC2A4\uD2B8\uB97C \u3010/\xA5/\uFFE5\uB85C []/$$\uB85C \uAC10\uC2F8\uAE30", "builtin-sel-wrap-quotes": "\uC120\uD0DD\uD55C \uD14D\uC2A4\uD2B8\uB97C \uC804\uAC01 \uB530\uC634\uD45C\uB85C \uAC10\uC2F8\uAE30", "builtin-sel-wrap-cjk-brackets": "\uC120\uD0DD\uD55C \uD14D\uC2A4\uD2B8\uB97C \u300A\u300B \uB610\uB294 \uFF08\uFF09 \uAD04\uD638\uB85C \uAC10\uC2F8\uAE30", "builtin-quote-convert": "> \uB610\uB294 \u300B\uB97C Markdown \uC778\uC6A9 \uD45C\uC2DC\uB85C \uBCC0\uD658", "builtin-quote-space": "\uC778\uC6A9 \uD45C\uC2DC > \uB4A4\uC5D0 \uC790\uB3D9\uC73C\uB85C \uACF5\uBC31 \uC0BD\uC785" } }; var ko_KR_default = locale6; // src/lang/locale/index.ts var localeMap = { "en": en_US_default, "zh": zh_CN_default, "zh-cn": zh_CN_default, "zh-tw": zh_TW_default, "ru": ru_RU_default, "ja": ja_JP_default, "ko": ko_KR_default }; var cached = null; function getLocale() { var _a; if (cached) return cached; const lang = import_obsidian2.moment.locale().toLowerCase(); cached = (_a = localeMap[lang]) != null ? _a : en_US_default; return cached; } // src/rule_engine.ts var import_obsidian3 = require("obsidian"); function escapeRegex(s) { return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } var RuleEngine = class { constructor() { this.rulesById = /* @__PURE__ */ new Map(); this.sortedRules = []; this.ruleIdCounter = 0; this.fnErrorLastNotify = /* @__PURE__ */ new Map(); this.regexCache = /* @__PURE__ */ new Map(); } static parseOptions(options = "") { const type = options.includes("d") ? "delete" /* Delete */ : options.includes("s") ? "selectKey" /* SelectKey */ : "input" /* Input */; const triggerMode = options.includes("T") ? "tab" /* Tab */ : "auto" /* Auto */; const isRegex = options.includes("r"); const isFunctionReplacement = options.includes("F"); const scope = []; if (options.includes("a") || !options.includes("t") && !options.includes("f") && !options.includes("c")) { scope.push("all" /* All */); } else { if (options.includes("t")) scope.push("text" /* Text */); if (options.includes("f")) scope.push("formula" /* Formula */); if (options.includes("c")) scope.push("code" /* Code */); } return { type, triggerMode, isRegex, isFunctionReplacement, scope }; } static normalizeRegexFlags(flags = "") { const normalized = flags.toLowerCase().replace(/[^imu]/g, ""); return Array.from(new Set(normalized.split(""))).sort((a, b) => "imu".indexOf(a) - "imu".indexOf(b)).join(""); } static validateRegex(rule) { var _a; const opts = RuleEngine.parseOptions(rule.options); if (!opts.isRegex) return null; const regexFlags = RuleEngine.normalizeRegexFlags(rule.regex_flags); const leftPattern = rule.trigger; const rightPattern = (_a = rule.trigger_right) != null ? _a : ""; if (leftPattern) { try { new RegExp("(?:" + leftPattern + ")", regexFlags); } catch (e) { return `trigger: ${e.message}`; } } if (rightPattern) { try { new RegExp("(?:" + rightPattern + ")", regexFlags); } catch (e) { return `trigger_right: ${e.message}`; } } return null; } static escapeText(text, preserveBackslashes = false) { let result = text; if (!preserveBackslashes) { result = result.replace(/\\/g, "\\\\"); } return result.replace(/\n/g, "\\n").replace(/\t/g, "\\t").replace(/\r/g, "\\r"); } static unescapeText(text) { let result = ""; for (let i = 0; i < text.length; i++) { if (text[i] === "\\" && i + 1 < text.length) { switch (text[i + 1]) { case "n": result += "\n"; i++; break; case "t": result += " "; i++; break; case "r": result += "\r"; i++; break; case "\\": result += "\\"; i++; break; default: result += text[i]; break; } } else { result += text[i]; } } return result; } static parseSelectKeyRuleTriggerKeys(pattern) { const keys = []; for (let i = 0; i < pattern.length; i++) { if (pattern[i] === "\\" && i + 1 < pattern.length) { keys.push(pattern[i + 1]); i++; } else { keys.push(pattern[i]); } } return keys; } static normalizeRule(simple) { var _a, _b, _c, _d, _e, _f, _g, _h, _i; const opts = RuleEngine.parseOptions(simple.options); let replacement = simple.replacement; if (opts.isFunctionReplacement && typeof simple.replacement === "string") { try { if (opts.type === "selectKey" /* SelectKey */) { replacement = new Function("selectionText", "key", simple.replacement); } else { replacement = new Function("leftMatches", "rightMatches", simple.replacement); } } catch (e) { console.error(`[RuleEngine] Failed to compile function for rule "${(_a = simple.id) != null ? _a : "?"}":`, e); replacement = () => void 0; new import_obsidian3.Notice(`[EasyTyping] Rule "${(_b = simple.id) != null ? _b : "?"}" has invalid function body: ${e.message}`); } } if (opts.type === "selectKey" /* SelectKey */) { return { description: (_c = simple.description) != null ? _c : "", enabled: (_d = simple.enabled) != null ? _d : true, type: "selectKey" /* SelectKey */, triggerMode: "auto" /* Auto */, triggerKeys: RuleEngine.parseSelectKeyRuleTriggerKeys(simple.trigger), scope: opts.scope, scopeLanguage: simple.scope_language, regexFlags: void 0, priority: (_e = simple.priority) != null ? _e : 100, match: { left: "", right: "", isRegex: false }, replacement }; } const triggerMode = opts.type === "input" /* Input */ ? opts.triggerMode : "auto" /* Auto */; return { description: (_f = simple.description) != null ? _f : "", enabled: (_g = simple.enabled) != null ? _g : true, type: opts.type, triggerMode, triggerKeys: void 0, scope: opts.scope, scopeLanguage: simple.scope_language, regexFlags: opts.isRegex ? RuleEngine.normalizeRegexFlags(simple.regex_flags) : void 0, priority: (_h = simple.priority) != null ? _h : 100, match: { left: simple.trigger, right: (_i = simple.trigger_right) != null ? _i : "", isRegex: opts.isRegex }, replacement }; } generateId() { return `rule-${++this.ruleIdCounter}`; } insertSorted(rule) { let lo = 0, hi = this.sortedRules.length; while (lo < hi) { const mid = lo + hi >>> 1; if (this.sortedRules[mid].priority <= rule.priority) lo = mid + 1; else hi = mid; } this.sortedRules.splice(lo, 0, rule); } addRule(rule) { var _a; const id = (_a = rule.id) != null ? _a : this.generateId(); const fullRule = { ...rule, id }; this.rulesById.set(id, fullRule); this.insertSorted(fullRule); return id; } addSimpleRule(simple) { const normalized = RuleEngine.normalizeRule(simple); return this.addRule({ ...normalized, id: simple.id }); } addSimpleRules(rules) { return rules.map((r) => this.addSimpleRule(r)); } removeRule(id) { if (!this.rulesById.has(id)) return false; this.rulesById.delete(id); this.regexCache.delete(id); const idx = this.sortedRules.findIndex((r) => r.id === id); if (idx !== -1) this.sortedRules.splice(idx, 1); return true; } updateRule(id, patch) { const existing = this.rulesById.get(id); if (!existing) return false; if (patch.match !== void 0 || patch.type !== void 0 || patch.regexFlags !== void 0) { this.regexCache.delete(id); } const priorityChanged = patch.priority !== void 0 && patch.priority !== existing.priority; Object.assign(existing, patch); if (priorityChanged) { const idx = this.sortedRules.findIndex((r) => r.id === id); if (idx !== -1) this.sortedRules.splice(idx, 1); this.insertSorted(existing); } return true; } setEnabled(id, enabled) { const rule = this.rulesById.get(id); if (rule) rule.enabled = enabled; } getRules() { return this.sortedRules; } getRulesByType(type) { return this.sortedRules.filter((r) => r.type === type); } getRule(id) { return this.rulesById.get(id); } clear() { this.rulesById.clear(); this.sortedRules = []; this.regexCache.clear(); } loadFromFiles(builtinRules, userRules) { this.clear(); this.addSimpleRules(builtinRules); this.addSimpleRules(userRules); } getCachedRegex(rule) { const existing = this.regexCache.get(rule.id); if (existing !== void 0) return existing; const leftPattern = rule.match.isRegex ? rule.match.left : escapeRegex(rule.match.left); const rightPattern = rule.match.isRegex ? rule.match.right : escapeRegex(rule.match.right); const regexFlags = rule.match.isRegex ? RuleEngine.normalizeRegexFlags(rule.regexFlags) : ""; try { const cached2 = { left: leftPattern ? new RegExp("(?:" + leftPattern + ")(?![\\s\\S])", regexFlags) : null, right: rightPattern ? new RegExp("(?:" + rightPattern + ")", regexFlags) : null }; this.regexCache.set(rule.id, cached2); return cached2; } catch (e) { console.error(`[RuleEngine] Invalid regex in rule "${rule.id}":`, e); new import_obsidian3.Notice(`[EasyTyping] Rule "${rule.id}" has invalid regex: ${e.message}`); this.regexCache.set(rule.id, null); return null; } } expandVariables(text, match) { text = text.replace(/\[\[R(\d+)\]\]/g, (_, n) => { var _a; const idx = parseInt(n); return (_a = match.rightMatches[idx]) != null ? _a : ""; }); text = text.replace(/\[\[(\d+)\]\]/g, (_, n) => { var _a, _b; const idx = parseInt(n); return (_b = (_a = match.leftMatches[idx]) != null ? _a : match.rightMatches[idx]) != null ? _b : ""; }); if (match.selectionText !== void 0) { text = text.replace(/\$\{SEL\}/g, match.selectionText); } if (match.key !== void 0) { text = text.replace(/\$\{KEY\}/g, match.key); } return text; } findMatchingBrace(text, openIdx) { let depth = 1; for (let i = openIdx + 1; i < text.length; i++) { if (text[i] === "{") depth++; else if (text[i] === "}") { depth--; if (depth === 0) return i; } } return -1; } parseTabstops(text, baseOffset, match) { const tabstops = []; let result = ""; let i = 0; while (i < text.length) { if (text[i] === "$") { if (i + 1 < text.length && text[i + 1] === "{") { const closeIdx = this.findMatchingBrace(text, i + 1); if (closeIdx === -1) { result += text[i]; i++; continue; } const inner = text.substring(i + 2, closeIdx); const colonIdx = inner.indexOf(":"); let num; let defaultVal; if (colonIdx > -1) { num = parseInt(inner.substring(0, colonIdx)); defaultVal = inner.substring(colonIdx + 1); if ((match == null ? void 0 : match.selectionText) !== void 0) defaultVal = defaultVal.replace(/\$\{SEL\}/g, match.selectionText); if ((match == null ? void 0 : match.key) !== void 0) defaultVal = defaultVal.replace(/\$\{KEY\}/g, match.key); } else { num = parseInt(inner); defaultVal = ""; } const from = baseOffset + result.length; result += defaultVal; const to = baseOffset + result.length; tabstops.push({ number: num, from, to }); i = closeIdx + 1; } else if (i + 1 < text.length && /\d/.test(text[i + 1])) { let numStr = ""; let j = i + 1; while (j < text.length && /\d/.test(text[j])) { numStr += text[j]; j++; } const num = parseInt(numStr); const pos = baseOffset + result.length; tabstops.push({ number: num, from: pos, to: pos }); i = j; } else { result += text[i]; i++; } } else { result += text[i]; i++; } } tabstops.sort((a, b) => a.number - b.number); return [result, tabstops]; } notifyFunctionError(ruleId, error) { var _a; const now = Date.now(); const last = (_a = this.fnErrorLastNotify.get(ruleId)) != null ? _a : 0; if (now - last > 5e3) { this.fnErrorLastNotify.set(ruleId, now); const msg = error instanceof Error ? error.message : String(error); new import_obsidian3.Notice(`[EasyTyping] Rule "${ruleId}" runtime error: ${msg}`); } console.error(`[RuleEngine] Runtime error in rule "${ruleId}":`, error); } process(ctx) { var _a; for (const rule of this.sortedRules) { if (!rule.enabled) continue; if (rule.type !== ctx.kind) continue; if (rule.triggerMode === "tab" /* Tab */ && ctx.changeType !== "tab") continue; if (rule.triggerMode === "auto" /* Auto */ && ctx.changeType === "tab") continue; if (ctx.scopeHint !== "all" /* All */ && !rule.scope.includes("all" /* All */) && !rule.scope.includes(ctx.scopeHint)) continue; if (rule.scopeLanguage && ctx.scopeHint === "code" /* Code */ && rule.scope.includes("code" /* Code */) && ctx.scopeLanguage !== rule.scopeLanguage) continue; switch (ctx.kind) { case "selectKey" /* SelectKey */: { if (!((_a = rule.triggerKeys) == null ? void 0 : _a.includes(ctx.key))) continue; const result = this.applySelectKeyRule(rule, ctx); if (result) { if (ctx.debug) console.log("[RuleEngine] hit:", rule.id, rule.description); return result; } break; } default: { const result = this.matchAndApplyTextRule(rule, ctx); if (result) { if (ctx.debug) console.log("[RuleEngine] hit:", rule.id, rule.description); return result; } break; } } } return null; } matchAndApplyTextRule(rule, ctx) { const { from, to } = ctx.selection; const leftDoc = ctx.docText.slice(0, from); const rightDoc = ctx.docText.slice(to); const cached2 = this.getCachedRegex(rule); if (!cached2) return null; const leftRegex = cached2.left; const rightRegex = cached2.right; const leftMatch = leftRegex ? leftRegex.exec(leftDoc) : [""]; const rightMatch = rightRegex ? this.matchAtStart(rightDoc, rightRegex) : [""]; if (!leftMatch || !rightMatch) return null; const matchFrom = from - leftMatch[0].length; const matchTo = to + rightMatch[0].length; return this.applyReplacement(rule, { leftMatches: [...leftMatch], rightMatches: [...rightMatch], matchRange: { from: matchFrom, to: matchTo } }, ctx); } matchAtStart(doc, regex) { regex.lastIndex = 0; const match = regex.exec(doc); if (!match || match.index !== 0) return null; return match; } applySelectKeyRule(rule, ctx) { const selectionText = ctx.docText.slice(ctx.selection.from, ctx.selection.to); return this.applyReplacement(rule, { leftMatches: [], rightMatches: [], matchRange: ctx.selection, selectionText, key: ctx.key }, ctx); } applyReplacement(rule, match, ctx) { let text; if (typeof rule.replacement === "function") { try { if (rule.type === "selectKey" /* SelectKey */) { const fn = rule.replacement; const result = fn(match.selectionText, match.key); if (result === void 0) return null; text = result; } else { const fn = rule.replacement; const result = fn(match.leftMatches, match.rightMatches); if (result === void 0) return null; text = result; } } catch (e) { this.notifyFunctionError(rule.id, e); return null; } } else { text = rule.replacement; } text = RuleEngine.unescapeText(text); text = this.expandVariables(text, match); const [finalText, tabstops] = this.parseTabstops(text, match.matchRange.from, match); const cursor = tabstops.length > 0 ? tabstops[0].from : match.matchRange.from + finalText.length; return { newText: finalText, cursor, tabstops, matchRange: match.matchRange }; } }; // src/default_rules.ts var DEFAULT_BUILTIN_RULES = [ { id: "builtin-autopair-input", trigger: "[\uFF08\u300A\u300C\u300E\u201C\u201D\u2018\u2019\u300A]", replacement: "const p={'\u3010':'\u3010$0\u3011','\uFF08':'\uFF08$0\uFF09','\u300A':'\u300A$0\u300B','\u300C':'\u300C$0\u300D','\u300E':'\u300E$0\u300F','\u201C':'\u201C$0\u201D','\u201D':'\u201C$0\u201D','\u2018':'\u2018$0\u2019','\u2019':'\u2018$0\u2019','\u300A':'\u300A$0\u300B'}; return p[leftMatches[0]];", options: "rF", priority: 10, description: "\u8F93\u5165\u5168\u89D2\u62EC\u53F7/\u5F15\u53F7\u65F6\u81EA\u52A8\u8865\u5168\u914D\u5BF9" }, { id: "builtin-autopair-jump", trigger: "\u300A\u300B|\u201C\u201D|\u201C\u201C|\u2018\u2019|\u2018\u2018|\uFF08\uFF09", trigger_right: "\u300B|\u201D|\u2019|\uFF09", replacement: 'const map = {\n "\u300A\u300B": ["\u300B", "\u300A\u300B"],\n "\uFF08\uFF09": ["\uFF09", "\uFF08\uFF09"],\n "\u201C\u201D": ["\u201D", "\u201C\u201D"],\n "\u201C\u201C": ["\u201D", "\u201C\u201D"],\n "\u2018\u2019": ["\u2019", "\u2018\u2019"],\n "\u2018\u2018": ["\u2019", "\u2018\u2019"]\n}\nif(map[leftMatches[0]][0]==rightMatches[0]){\n return map[leftMatches[0]][1];\n}\nreturn undefined;', options: "rF", priority: 5, description: "\u8F93\u5165\u53F3\u4FA7\u914D\u5BF9\u7B26\u53F7\u65F6\u81EA\u52A8\u8DF3\u8FC7\uFF0C\u907F\u514D\u91CD\u590D\u63D2\u5165" }, { id: "builtin-autopair-delete", trigger: "[\u3010\uFF08\u300A\u300C\u300E\u201C\u2018]", trigger_right: "[\u3011\uFF09\u300B\u300D\u300F\u201D\u2019]", replacement: "const p={'\u3010':'\u3011','\uFF08':'\uFF09','\u300A':'\u300B','\u300C':'\u300D','\u300E':'\u300F','\u201C':'\u201D','\u2018':'\u2019'}; return p[leftMatches[0]]===rightMatches[0] ? '' : undefined;", options: "drF", priority: 10, description: "\u5220\u9664\u5168\u89D2\u62EC\u53F7/\u5F15\u53F7\u65F6\u540C\u65F6\u5220\u9664\u914D\u5BF9" }, { id: "builtin-conv-backtick", trigger: "\xB7\xB7", replacement: "`$0`", priority: 10, description: "\u8FDE\u7EED\u4E2D\u6587\u95F4\u9694\u53F7 \xB7\xB7 \u8F6C\u884C\u5185\u4EE3\u7801" }, { id: "builtin-conv-codeblock", trigger: "(?<=^|\\n)([ \\t]*)`\xB7", trigger_right: "`", replacement: "[[1]]```$0\n[[1]]```", options: "r", priority: 10, description: "\u884C\u5185\u4EE3\u7801\u4E2D\u7EE7\u7EED\u8F93\u5165 \xB7 \u5347\u7EA7\u4E3A\u4EE3\u7801\u5757" }, { id: "builtin-conv-formula", trigger: "(\uFFE5\uFFE5|\xA5\xA5|\\$\uFFE5|\\$\xA5|\\$\\$)", trigger_right: "\\$?", replacement: "return rightMatches[0] === '$' ? '$$\\n$0\\n$$' : '$$0$';", options: "rF", priority: 10, description: "\uFFE5/$ \u7B26\u53F7\u7EC4\u5408\u8F6C\u884C\u5185\u6216\u5757\u7EA7\u516C\u5F0F" }, { id: "builtin-conv-linestart", trigger: "(^|\\n)([\u300B\u3001])", replacement: "const m = {'\u300B': '[[1]]> $0', '\u3001': '[[1]]/$0'}; return m[leftMatches[2]];", options: "rF", priority: 10, description: "\u884C\u9996 \u300B \u8F6C\u5F15\u7528\u6807\u8BB0\u3001\u884C\u9996 \u3001 \u8F6C\u659C\u6760" }, { id: "builtin-conv-hw2fw", trigger: "([\u4E00-\u9FA5\u3040-\u309F\u30A0-\u30FF\uAC00-\uD7AF])([,.:?!;(])", trigger_right: "\\)?", replacement: "const m={',':'\uFF0C','.':'\u3002','?':'\uFF1F','!':'\uFF01',':':'\uFF1A',';':'\uFF1B','(':'\uFF08$0\uFF09'}; return leftMatches[1] + m[leftMatches[2]];", options: "rF", priority: 15, enabled: false, description: "CJK\u5B57\u7B26\u540E\u534A\u89D2\u6807\u70B9\u8F6C\u5168\u89D2" }, { id: "builtin-fw2hw-double", trigger: "([\u3002\uFF01\uFF1B\uFF0C\uFF1A\uFF1F\u300B\uFF5C\uFF08\u300A])\\1", trigger_right: "[\uFF09\u300B]?", replacement: "const p={'\uFF08':['\uFF09','($0)'],'\u300A':['\u300B','<$0']};\nconst m={'\u3002':'.$0','\uFF01':'!$0','\uFF1B':';$0','\uFF0C':',$0','\uFF1A':':$0','\uFF1F':'?$0','\u300B':'>$0','\uFF5C':'|$0','\uFF08':'($0)','\u300A':'<$0'};\nconst c=leftMatches[1],r=rightMatches[0]||'',e=p[c]; \nreturn e&&e[0]===r?e[1]:m[c];", options: "rF", priority: 3, description: "\u8FDE\u7EED\u8F93\u5165\u4E24\u4E2A\u76F8\u540C\u5168\u89D2\u6807\u70B9\u8F6C\u5BF9\u5E94\u534A\u89D2" }, { id: "builtin-del-inline-formula", trigger: "$", trigger_right: "$", replacement: "", options: "d", priority: 30, description: "\u5220\u9664\u884C\u5185\u516C\u5F0F $...$ \u914D\u5BF9" }, { id: "builtin-del-highlight", trigger: "==", trigger_right: "==", replacement: "", options: "d", priority: 30, description: "\u5220\u9664\u9AD8\u4EAE ==...== \u914D\u5BF9" }, { id: "builtin-del-block-formula", trigger: "$$\n", trigger_right: "\n$$", replacement: "", options: "d", priority: 30, description: "\u5220\u9664\u5757\u7EA7\u516C\u5F0F $$...$$ \u914D\u5BF9" }, { id: "builtin-del-codeblock", trigger: "(?<=^|\\n)([ \\t]*)```", trigger_right: "[ \\t]*\\n([ \\t]*)```", replacement: "[[1]]", options: "dr", priority: 30, description: "\u5FEB\u901F\u5220\u9664\u7A7A\u4EE3\u7801\u5757" }, { id: "builtin-del-wikilink", trigger: " ?!?\\[\\[[^\\n\\[\\]]*\\]\\]", replacement: "", options: "dr", priority: 30, description: "\u5FEB\u901F\u5220\u9664\u53CC\u94FE\u53CA\u5D4C\u5165\uFF08![[]]\uFF09" }, { id: "builtin-sel-wrap-backtick", trigger: "\xB7", replacement: "`${0:${SEL}}`", options: "s", priority: 40, description: "\u9009\u4E2D\u6587\u5B57\u540E\u8F93\u5165 \xB7 \u5305\u88F9\u4E3A\u884C\u5185\u4EE3\u7801" }, { id: "builtin-sel-wrap-symbols", trigger: `\u3010\xA5\uFFE5`, replacement: "const m={'\xA5': ['$', '$'], '\uFFE5': ['$', '$'], '\u3010': ['[', ']']}; \nreturn m[key][0] + '${0:${SEL}}' + m[key][1];", options: "sF", priority: 40, description: "\u9009\u4E2D\u6587\u5B57\u540E\u8F93\u5165 \u3010/\xA5/\uFFE5 \u5305\u88F9\u4E3A []/$$" }, { id: "builtin-sel-wrap-quotes", trigger: `\u201C\u201D\u2018\u2019`, replacement: "const m={'\u201C': ['\u201C','\u201D'], '\u201D': ['\u201C','\u201D'], '\u2018': ['\u2018','\u2019'], '\u2019': ['\u2018','\u2019']}; return m[key][0] + '${0:${SEL}}' + m[key][1];", options: "sF", priority: 40, description: "\u9009\u4E2D\u6587\u5B57\u540E\u8F93\u5165\u5168\u89D2\u5F15\u53F7\uFF0C\u914D\u5BF9\u5F15\u53F7\u5305\u88F9" }, { id: "builtin-sel-wrap-cjk-brackets", trigger: `\u300A\uFF08`, replacement: "const m={'\u300A': ['\u300A','\u300B'], '\uFF08': ['\uFF08','\uFF09']}; return m[key][0] + '${0:${SEL}}' + m[key][1];", options: "sF", priority: 40, description: "\u9009\u4E2D\u6587\u5B57\u540E\u8F93\u5165\u300A\uFF08\uFF0C\u914D\u5BF9\u62EC\u53F7\u5305\u88F9" }, { id: "builtin-quote-convert", trigger: "((?:^|\\n)\\s*>*) ?[>\u300B]", replacement: "[[1]]> $0", options: "r", priority: 50, description: "\u8F93\u5165 > \u6216 \u300B \u8F6C\u4E3A Markdown \u5F15\u7528\u6807\u8BB0" }, { id: "builtin-quote-space", trigger: "((?:^|\\n)\\s*>+)([^ >\u300B]+)", replacement: "[[1]] [[2]]$0", options: "r", priority: 50, description: "\u5F15\u7528\u6807\u8BB0 > \u540E\u81EA\u52A8\u8865\u7A7A\u683C" } ]; // src/settings/rule_edit_modal.ts var import_obsidian4 = require("obsidian"); var import_view = require("@codemirror/view"); var import_state2 = require("@codemirror/state"); var import_commands = require("@codemirror/commands"); var JS_KEYWORDS = /* @__PURE__ */ new Set([ "const", "let", "var", "function", "return", "if", "else", "for", "while", "do", "switch", "case", "break", "continue", "new", "this", "true", "false", "null", "undefined", "typeof", "instanceof", "in", "of", "try", "catch", "finally", "throw", "async", "await" ]); function tokenizeJS(text) { const tokens = []; let i = 0; while (i < text.length) { if (text[i] === "/" && text[i + 1] === "/") { const start = i; while (i < text.length && text[i] !== "\n") i++; tokens.push({ from: start, to: i, cls: "et-hl-comment" }); continue; } if (text[i] === "/" && text[i + 1] === "*") { const start = i; i += 2; while (i < text.length - 1 && !(text[i] === "*" && text[i + 1] === "/")) i++; if (i < text.length - 1) i += 2; else i = text.length; tokens.push({ from: start, to: i, cls: "et-hl-comment" }); continue; } if (text[i] === '"' || text[i] === "'" || text[i] === "`") { const quote = text[i]; const start = i; i++; while (i < text.length && text[i] !== quote) { if (text[i] === "\\") i++; i++; } if (i < text.length) i++; tokens.push({ from: start, to: i, cls: "et-hl-string" }); continue; } if (/\d/.test(text[i]) && (i === 0 || /[^a-zA-Z_$]/.test(text[i - 1]))) { const start = i; if (text[i] === "0" && (text[i + 1] === "x" || text[i + 1] === "X")) { i += 2; while (i < text.length && /[0-9a-fA-F]/.test(text[i])) i++; } else { while (i < text.length && /\d/.test(text[i])) i++; if (i < text.length && text[i] === ".") { i++; while (i < text.length && /\d/.test(text[i])) i++; } } tokens.push({ from: start, to: i, cls: "et-hl-number" }); continue; } if (/[a-zA-Z_$]/.test(text[i])) { const start = i; while (i < text.length && /[a-zA-Z0-9_$]/.test(text[i])) i++; if (JS_KEYWORDS.has(text.slice(start, i))) { tokens.push({ from: start, to: i, cls: "et-hl-keyword" }); } continue; } i++; } return tokens; } var jsHighlightPlugin = import_view.ViewPlugin.fromClass(class { constructor(view) { this.decorations = this.buildDecorations(view); } update(update) { if (update.docChanged || update.viewportChanged) { this.decorations = this.buildDecorations(update.view); } } buildDecorations(view) { const text = view.state.doc.toString(); const tokens = tokenizeJS(text); const ranges = tokens.map((t) => import_view.Decoration.mark({ class: t.cls }).range(t.from, t.to)); return import_view.Decoration.set(ranges, true); } }, { decorations: (v) => v.decorations }); var fnEditorTheme = import_view.EditorView.theme({ "&": { fontSize: "13px", backgroundColor: "var(--background-primary)" }, ".cm-content": { fontFamily: "var(--font-monospace)", padding: "8px", minHeight: "120px" }, "&.cm-focused": { outline: "none" }, ".cm-gutters": { display: "none" }, ".cm-activeLine": { backgroundColor: "transparent" } }); function createJSEditorView(container, initialValue, onChange) { const state = import_state2.EditorState.create({ doc: initialValue, extensions: [ jsHighlightPlugin, fnEditorTheme, import_view.keymap.of([import_commands.indentWithTab]), import_state2.EditorState.tabSize.of(4), import_view.EditorView.updateListener.of((update) => { if (update.docChanged) { onChange(update.state.doc.toString()); } }) ] }); return new import_view.EditorView({ state, parent: container }); } var RuleEditModal = class extends import_obsidian4.Modal { constructor(app, mode, initial, onSubmit) { super(app); this.ruleType = "input" /* Input */; this.triggerMode = "auto" /* Auto */; this.trigger = ""; this.triggerRight = ""; this.replacement = ""; this.isRegex = false; this.regexFlags = ""; this.scopeLanguage = ""; this.priority = 100; this.description = ""; this.enabled = true; this.isFunction = false; this.ruleScopes = ["all" /* All */]; this.cmEditor = null; this.mode = mode; this.initial = initial; this.onSubmit = onSubmit; if (initial.options !== void 0 || initial.trigger !== void 0) { const opts = RuleEngine.parseOptions(initial.options); this.ruleType = opts.type; this.triggerMode = opts.triggerMode; this.isRegex = opts.isRegex; this.isFunction = opts.isFunctionReplacement; this.ruleScopes = opts.scope.length > 0 ? [...opts.scope] : ["all" /* All */]; } if (initial.trigger !== void 0) this.trigger = RuleEngine.escapeText(initial.trigger, this.isRegex); if (initial.trigger_right !== void 0) this.triggerRight = RuleEngine.escapeText(initial.trigger_right, this.isRegex); if (typeof initial.replacement === "string") this.replacement = initial.replacement; if (initial.regex_flags !== void 0) this.regexFlags = RuleEngine.normalizeRegexFlags(initial.regex_flags); if (initial.priority !== void 0) this.priority = initial.priority; if (initial.description !== void 0) this.description = initial.description; if (initial.enabled !== void 0) this.enabled = initial.enabled; if (initial.scope_language !== void 0) this.scopeLanguage = initial.scope_language; } onOpen() { const { contentEl } = this; this.modalEl.addClass("et-rule-edit-modal"); contentEl.addClass("et-rule-edit-modal-content"); const locale7 = getLocale(); const title = this.mode === "create" ? locale7.settings.ruleEditModal.addTitle : locale7.settings.ruleEditModal.editTitle; const headerEl = contentEl.createDiv({ cls: "et-rule-edit-header" }); const titleEl = headerEl.createEl("h2", { text: title, cls: "et-rule-edit-title" }); const pillBar = contentEl.createDiv({ cls: "et-pill-bar" }); const typeSection = pillBar.createDiv({ cls: "et-pill-section" }); typeSection.createEl("span", { cls: "et-pill-group-label", text: locale7.settings.ruleEditModal.fieldType }); const typeOptions = typeSection.createDiv({ cls: "et-pill-options" }); const typePills = [ { value: "input" /* Input */, label: locale7.dropdownOptions.ruleTypeInput }, { value: "delete" /* Delete */, label: locale7.dropdownOptions.ruleTypeDelete }, { value: "selectKey" /* SelectKey */, label: locale7.dropdownOptions.ruleTypeSelectKey } ]; for (const { value, label } of typePills) { const pill = typeOptions.createEl("button", { cls: `et-pill${this.ruleType === value ? " et-pill-active" : ""}`, text: label }); pill.dataset.pillGroup = "ruleType"; pill.dataset.pillValue = value; pill.addEventListener("click", () => { this.ruleType = value; this.refreshVisibility(contentEl); }); } const triggerModeSection = pillBar.createDiv({ cls: "et-pill-section" }); triggerModeSection.dataset.field = "triggerModeSection"; const triggerModeLabel = triggerModeSection.createEl("span", { cls: "et-pill-group-label", text: locale7.settings.ruleEditModal.fieldTriggerMode }); triggerModeLabel.dataset.field = "triggerModeLabel"; const triggerModeOptions = triggerModeSection.createDiv({ cls: "et-pill-options" }); const triggerModePills = [ { value: "auto" /* Auto */, label: locale7.dropdownOptions.triggerModeAuto }, { value: "tab" /* Tab */, label: locale7.dropdownOptions.triggerModeTab } ]; for (const { value, label } of triggerModePills) { const pill = triggerModeOptions.createEl("button", { cls: `et-pill${this.triggerMode === value ? " et-pill-active" : ""}`, text: label }); pill.dataset.pillGroup = "triggerMode"; pill.dataset.pillValue = value; pill.addEventListener("click", () => { this.triggerMode = value; this.refreshVisibility(contentEl); }); } const matchGroup = contentEl.createDiv({ cls: "et-modal-group" }); const matchHeader = matchGroup.createDiv({ cls: "et-modal-group-header" }); matchHeader.createEl("span", { cls: "et-modal-group-title", text: locale7.settings.ruleEditModal.groupMatch }); const regexChip = matchHeader.createEl("button", { cls: `et-pill-chip${this.isRegex ? " et-pill-chip-active" : ""}`, text: locale7.settings.ruleEditModal.fieldIsRegex }); regexChip.dataset.field = "isRegexChip"; regexChip.addEventListener("click", () => { this.isRegex = !this.isRegex; this.refreshVisibility(contentEl); }); const triggerSetting = new import_obsidian4.Setting(matchGroup).setName(locale7.settings.ruleEditModal.fieldTrigger).setDesc("").addText((text) => { text.setValue(this.trigger); text.onChange((v) => this.trigger = v); }); triggerSetting.settingEl.dataset.field = "trigger"; const triggerRightSetting = new import_obsidian4.Setting(matchGroup).setName(locale7.settings.ruleEditModal.fieldTriggerRight).addText((text) => { text.setValue(this.triggerRight); text.onChange((v) => this.triggerRight = v); }); triggerRightSetting.settingEl.dataset.field = "triggerRight"; const regexFlagsSetting = new import_obsidian4.Setting(matchGroup).setName(locale7.settings.ruleEditModal.fieldRegexFlags).setDesc(locale7.settings.ruleEditModal.fieldRegexFlagsDesc).addText((text) => { text.setPlaceholder("imu"); text.setValue(this.regexFlags); text.onChange((v) => this.regexFlags = RuleEngine.normalizeRegexFlags(v)); }); regexFlagsSetting.settingEl.dataset.field = "regexFlags"; const replacementGroup = contentEl.createDiv({ cls: "et-modal-group" }); const replHeader = replacementGroup.createDiv({ cls: "et-modal-group-header" }); replHeader.createEl("span", { cls: "et-modal-group-title", text: locale7.settings.ruleEditModal.groupReplacement }); const fnChip = replHeader.createEl("button", { cls: `et-pill-chip${this.isFunction ? " et-pill-chip-active" : ""}`, text: locale7.settings.ruleEditModal.fieldIsFunction }); fnChip.dataset.field = "isFunctionChip"; fnChip.addEventListener("click", () => { this.isFunction = !this.isFunction; this.refreshVisibility(contentEl); }); const replacementSetting = new import_obsidian4.Setting(replacementGroup); replacementSetting.settingEl.addClass("et-replacement-setting"); replacementSetting.settingEl.dataset.field = "replacementTextarea"; const replacementArea = new import_obsidian4.TextAreaComponent(replacementSetting.controlEl); replacementArea.inputEl.addClass("et-replacement-textarea"); replacementArea.inputEl.setAttribute("aria-label", locale7.settings.ruleEditModal.fieldReplacement); replacementArea.setValue(this.replacement); replacementArea.onChange((v) => this.replacement = v); const replacementHint = replacementGroup.createEl("div", { cls: "setting-item-description et-replacement-hint", text: "" }); replacementHint.dataset.field = "replacementHint"; const editorWrapper = replacementGroup.createDiv(); editorWrapper.dataset.field = "fnEditor"; const editorContainer = editorWrapper.createDiv({ cls: "et-fn-editor-container" }); editorContainer.setAttribute("aria-label", locale7.settings.ruleEditModal.fieldReplacement); this.cmEditor = createJSEditorView(editorContainer, this.replacement, (value) => { this.replacement = value; }); const fnHint = replacementGroup.createEl("div", { cls: "setting-item-description et-fn-hint", text: "" }); fnHint.dataset.field = "fnHint"; const otherGroup = contentEl.createDiv({ cls: "et-modal-group" }); const otherHeader = otherGroup.createDiv({ cls: "et-modal-group-header" }); otherHeader.createEl("span", { cls: "et-modal-group-title", text: locale7.settings.ruleEditModal.groupOther }); const scopeSetting = new import_obsidian4.Setting(otherGroup).setName(locale7.settings.ruleEditModal.fieldScope); scopeSetting.settingEl.dataset.field = "scopeSetting"; scopeSetting.settingEl.addClass("et-scope-setting"); const scopeControls = scopeSetting.controlEl.createDiv({ cls: "et-scope-options" }); const scopeOptions = [ { value: "all" /* All */, label: locale7.dropdownOptions.scopeAll }, { value: "text" /* Text */, label: locale7.dropdownOptions.scopeText }, { value: "formula" /* Formula */, label: locale7.dropdownOptions.scopeFormula }, { value: "code" /* Code */, label: locale7.dropdownOptions.scopeCode } ]; for (const { value, label } of scopeOptions) { const chip = scopeControls.createEl("button", { cls: `et-pill-chip${this.ruleScopes.includes(value) ? " et-pill-chip-active" : ""}`, text: label, attr: { type: "button" } }); chip.dataset.scopeValue = value; chip.addEventListener("click", () => { this.toggleRuleScope(value); this.refreshVisibility(contentEl); }); } const scopeLangSetting = new import_obsidian4.Setting(otherGroup).setName(locale7.settings.ruleEditModal.fieldScopeLanguage).addText((text) => { text.setPlaceholder("e.g. python, javascript"); text.setValue(this.scopeLanguage); text.onChange((v) => this.scopeLanguage = v.trim().toLowerCase()); }); scopeLangSetting.settingEl.dataset.field = "scopeLanguage"; new import_obsidian4.Setting(otherGroup).setName(locale7.settings.ruleEditModal.fieldPriority).setDesc(locale7.settings.ruleEditModal.fieldPriorityDesc).addText((text) => { text.setValue(String(this.priority)); text.inputEl.type = "number"; text.onChange((v) => { const n = parseInt(v); if (!isNaN(n)) this.priority = n; }); }); new import_obsidian4.Setting(otherGroup).setName(locale7.settings.ruleEditModal.fieldDescription).addText((text) => { text.setValue(this.description); text.onChange((v) => this.description = v); }); const footerEl = contentEl.createDiv({ cls: "et-rule-edit-footer" }); const saveButton = footerEl.createEl("button", { cls: "mod-cta et-rule-edit-save", text: locale7.settings.ruleEditModal.buttonSave }); saveButton.addEventListener("click", () => { const rule = this.buildSimpleRule(); const regexError = RuleEngine.validateRegex(rule); if (regexError) { new import_obsidian4.Notice(`[EasyTyping] ${locale7.settings.ruleEditModal.invalidRegex}: ${regexError}`); return; } this.close(); this.onSubmit(rule); }); this.refreshVisibility(contentEl); this.setInitialFocus(contentEl, titleEl); } setInitialFocus(contentEl, titleEl) { window.requestAnimationFrame(() => { if (this.mode === "create") { const triggerInput = contentEl.querySelector('[data-field="trigger"] input'); if (!triggerInput) return; triggerInput.focus(); triggerInput.setSelectionRange(triggerInput.value.length, triggerInput.value.length); return; } titleEl.tabIndex = -1; titleEl.focus(); }); } refreshVisibility(contentEl) { const locale7 = getLocale(); const triggerRightEl = contentEl.querySelector('[data-field="triggerRight"]'); if (triggerRightEl) { triggerRightEl.classList.toggle("et-hidden", this.ruleType === "selectKey" /* SelectKey */); } const regexFlagsEl = contentEl.querySelector('[data-field="regexFlags"]'); if (regexFlagsEl) { regexFlagsEl.classList.toggle("et-hidden", this.ruleType === "selectKey" /* SelectKey */ || !this.isRegex); } const triggerEl = contentEl.querySelector('[data-field="trigger"]'); if (triggerEl) { const nameEl = triggerEl.querySelector(".setting-item-name"); if (nameEl) { nameEl.textContent = this.ruleType === "selectKey" /* SelectKey */ ? locale7.settings.ruleEditModal.fieldTriggerSelectKey : locale7.settings.ruleEditModal.fieldTrigger; } const descEl = triggerEl.querySelector(".setting-item-description"); if (descEl) { descEl.textContent = this.isRegex ? "" : locale7.settings.ruleEditModal.hintTriggerEscape; } } contentEl.querySelectorAll('[data-pill-group="ruleType"]').forEach((el) => { el.classList.toggle("et-pill-active", el.dataset.pillValue === this.ruleType); }); const triggerModeSection = contentEl.querySelector('[data-field="triggerModeSection"]'); if (triggerModeSection) triggerModeSection.classList.toggle("et-hidden", this.ruleType !== "input" /* Input */); contentEl.querySelectorAll('[data-pill-group="triggerMode"]').forEach((el) => { const htmlEl = el; htmlEl.classList.toggle("et-hidden", this.ruleType !== "input" /* Input */); htmlEl.classList.toggle("et-pill-active", htmlEl.dataset.pillValue === this.triggerMode); }); const regexChip = contentEl.querySelector('[data-field="isRegexChip"]'); if (regexChip) { regexChip.classList.toggle("et-pill-chip-active", this.isRegex); regexChip.classList.toggle("et-hidden", this.ruleType === "selectKey" /* SelectKey */); } const fnChip = contentEl.querySelector('[data-field="isFunctionChip"]'); if (fnChip) fnChip.classList.toggle("et-pill-chip-active", this.isFunction); const replacementHintEl = contentEl.querySelector('[data-field="replacementHint"]'); if (replacementHintEl) { const parts = []; if (this.ruleType === "selectKey" /* SelectKey */) { parts.push(locale7.settings.ruleEditModal.fieldReplacementDescSelectKey); } else if (this.isRegex) { parts.push(locale7.settings.ruleEditModal.fieldReplacementDescInputDelete); } parts.push(locale7.settings.ruleEditModal.hintTabstop); replacementHintEl.textContent = parts.join("\n"); replacementHintEl.classList.toggle("et-hidden", this.isFunction); } const fnHint = contentEl.querySelector('[data-field="fnHint"]'); if (fnHint) { fnHint.classList.toggle("et-hidden", !this.isFunction); const parts = []; if (this.ruleType === "selectKey" /* SelectKey */) { parts.push(locale7.settings.ruleEditModal.functionHintSelectKey); } else { parts.push(locale7.settings.ruleEditModal.functionHintInputDelete); if (this.isRegex) { parts.push(locale7.settings.ruleEditModal.fieldReplacementDescInputDelete); } } parts.push(locale7.settings.ruleEditModal.hintTabstop); fnHint.textContent = parts.join("\n"); } const textareaSetting = contentEl.querySelector('[data-field="replacementTextarea"]'); const editorSetting = contentEl.querySelector('[data-field="fnEditor"]'); if (textareaSetting && editorSetting) { textareaSetting.classList.toggle("et-hidden", this.isFunction); editorSetting.classList.toggle("et-hidden", !this.isFunction); if (this.isFunction) { if (this.cmEditor) { const current = this.cmEditor.state.doc.toString(); if (current !== this.replacement) { this.cmEditor.dispatch({ changes: { from: 0, to: current.length, insert: this.replacement } }); } } } else { const textarea = textareaSetting.querySelector("textarea"); if (textarea && textarea.value !== this.replacement) { textarea.value = this.replacement; } } } const scopeLangEl = contentEl.querySelector('[data-field="scopeLanguage"]'); if (scopeLangEl) { scopeLangEl.classList.toggle("et-hidden", !this.ruleScopes.includes("code" /* Code */)); } contentEl.querySelectorAll("[data-scope-value]").forEach((el) => { const htmlEl = el; htmlEl.classList.toggle("et-pill-chip-active", this.ruleScopes.includes(htmlEl.dataset.scopeValue)); }); } buildSimpleRule() { let options = ""; if (this.ruleType === "delete" /* Delete */) options += "d"; else if (this.ruleType === "selectKey" /* SelectKey */) options += "s"; if (this.ruleType === "input" /* Input */ && this.triggerMode === "tab" /* Tab */) options += "T"; if (this.isRegex) options += "r"; if (this.isFunction) options += "F"; const normalizedScopes = this.getNormalizedRuleScopes(); if (!normalizedScopes.includes("all" /* All */)) { if (normalizedScopes.includes("text" /* Text */)) options += "t"; if (normalizedScopes.includes("formula" /* Formula */)) options += "f"; if (normalizedScopes.includes("code" /* Code */)) options += "c"; } return { trigger: this.isRegex ? this.trigger : RuleEngine.unescapeText(this.trigger), trigger_right: (this.isRegex ? this.triggerRight : RuleEngine.unescapeText(this.triggerRight)) || void 0, replacement: this.replacement, options: options || void 0, priority: this.priority, description: this.description || void 0, enabled: this.enabled, scope_language: normalizedScopes.includes("code" /* Code */) && this.scopeLanguage ? this.scopeLanguage : void 0, regex_flags: this.isRegex ? RuleEngine.normalizeRegexFlags(this.regexFlags) || void 0 : void 0 }; } toggleRuleScope(scope) { if (scope === "all" /* All */) { this.ruleScopes = ["all" /* All */]; return; } const nextScopes = this.ruleScopes.filter((item) => item !== "all" /* All */); const hasScope = nextScopes.includes(scope); this.ruleScopes = hasScope ? nextScopes.filter((item) => item !== scope) : [...nextScopes, scope]; if (this.ruleScopes.length === 0) { this.ruleScopes = ["all" /* All */]; } } getNormalizedRuleScopes() { return this.ruleScopes.length > 0 ? this.ruleScopes : ["all" /* All */]; } onClose() { if (this.cmEditor) { this.cmEditor.destroy(); this.cmEditor = null; } this.contentEl.empty(); } }; // src/settings/easy_typing_settings_tab.ts var import_sprintf_js = __toESM(require_sprintf()); var DEFAULT_PATH_VALUE = ""; var FolderSuggest = class extends import_obsidian5.AbstractInputSuggest { constructor(app, inputEl, defaultLabel, onSelect) { super(app, inputEl); this.defaultLabel = defaultLabel; this.onSelectCb = onSelect; } getSuggestions(query) { const lowerQuery = query.toLowerCase(); const folders = this.app.vault.getAllFolders().map((f) => f.path).filter((p) => p.toLowerCase().includes(lowerQuery)); return [DEFAULT_PATH_VALUE, ...folders]; } renderSuggestion(path, el) { el.setText(path || this.defaultLabel); } selectSuggestion(path, _evt) { this.setValue(path); this.close(); this.onSelectCb(path); } }; var EasyTypingSettingTab = class extends import_obsidian5.PluginSettingTab { constructor(app, plugin) { super(app, plugin); this.activeTab = "edit-enhance"; this.dragSourceIndex = null; this.plugin = plugin; } display() { const { containerEl } = this; const locale7 = getLocale(); containerEl.empty(); const shellEl = containerEl.createDiv({ cls: "et-settings-shell" }); const heroEl = shellEl.createDiv({ cls: "et-settings-hero" }); const heroMainEl = heroEl.createDiv({ cls: "et-settings-hero-main" }); heroMainEl.createEl("h1", { text: locale7.headers.main }); const heroMetaEl = heroMainEl.createDiv({ cls: "et-settings-hero-meta" }); heroMetaEl.createSpan({ text: locale7.headers.githubDetail, cls: "et-settings-hero-label" }); heroMetaEl.createEl("a", { text: "easy-typing-obsidian", href: "https://github.com/Yaozhuwa/easy-typing-obsidian", cls: "et-settings-hero-link" }); const navEl = shellEl.createEl("nav", { cls: "et-settings-nav", attr: { role: "tablist", "aria-orientation": "horizontal" } }); const contentEl = shellEl.createEl("div", { cls: "et-settings-content" }); const tabs = [ { id: "edit-enhance", label: locale7.headers.tabs.editEnhance }, { id: "auto-format", label: locale7.headers.tabs.autoFormat }, { id: "builtin-rules", label: locale7.headers.tabs.builtinRules }, { id: "user-rules", label: locale7.headers.tabs.userRules }, { id: "other", label: locale7.headers.tabs.other } ]; const tabPanels = {}; const tabButtons = []; const activateTab = (tabId, focusButton = false) => { this.activeTab = tabId; tabs.forEach((tab, index) => { const button = tabButtons[index]; const panel = tabPanels[tab.id]; const isActive = tab.id === tabId; button.toggleClass("et-settings-tab-active", isActive); button.setAttribute("aria-selected", isActive ? "true" : "false"); button.tabIndex = isActive ? 0 : -1; panel.toggleClass("et-settings-tab-hidden", !isActive); panel.setAttribute("aria-hidden", isActive ? "false" : "true"); if (focusButton && isActive) { button.focus(); } }); }; tabs.forEach((tab) => { const isActive = tab.id === this.activeTab; const buttonId = `easy-typing-settings-tab-${tab.id}`; const panelId = `easy-typing-settings-panel-${tab.id}`; const btn = navEl.createEl("button", { cls: `et-settings-tab-btn ${isActive ? "et-settings-tab-active" : ""}`, attr: { id: buttonId, role: "tab", type: "button", "aria-selected": isActive ? "true" : "false", "aria-controls": panelId } }); btn.tabIndex = isActive ? 0 : -1; btn.setText(tab.label); tabButtons.push(btn); const panel = contentEl.createEl("section", { cls: `et-settings-tab-panel ${isActive ? "" : "et-settings-tab-hidden"}`, attr: { id: panelId, role: "tabpanel", "data-tab-id": tab.id, "aria-labelledby": buttonId, "aria-hidden": isActive ? "false" : "true" } }); tabPanels[tab.id] = panel; btn.addEventListener("click", () => { activateTab(tab.id); }); btn.addEventListener("keydown", (evt) => { const currentIndex = tabs.findIndex((item) => item.id === tab.id); if (currentIndex === -1) return; let targetIndex = null; switch (evt.key) { case "ArrowRight": case "ArrowDown": targetIndex = (currentIndex + 1) % tabs.length; break; case "ArrowLeft": case "ArrowUp": targetIndex = (currentIndex - 1 + tabs.length) % tabs.length; break; case "Home": targetIndex = 0; break; case "End": targetIndex = tabs.length - 1; break; } if (targetIndex !== null) { evt.preventDefault(); activateTab(tabs[targetIndex].id, true); } }); }); this.buildEditEnhanceTab(tabPanels["edit-enhance"]); this.buildAutoFormatTab(tabPanels["auto-format"]); this.buildBuiltinRulesSection(tabPanels["builtin-rules"]); this.buildUserRulesSection(tabPanels["user-rules"]); this.buildOtherTab(tabPanels["other"]); } createSection(container, title, description, actionsBuilder, extraCls = "") { const sectionEl = container.createDiv({ cls: `et-settings-section ${extraCls}`.trim() }); if (title || description || actionsBuilder) { const headerEl = sectionEl.createDiv({ cls: "et-settings-section-header" }); const headingEl = headerEl.createDiv({ cls: "et-settings-section-heading" }); if (title) { headingEl.createEl("h3", { text: title }); } if (description) { headingEl.createDiv({ text: description, cls: "et-settings-section-desc setting-item-description" }); } if (actionsBuilder) { const actionsEl = headerEl.createDiv({ cls: "et-settings-section-actions" }); actionsBuilder(actionsEl); } } const bodyEl = sectionEl.createDiv({ cls: "et-settings-section-body" }); return { sectionEl, bodyEl }; } setInteractiveDisabled(element, disabled) { element.toggleClass("et-settings-disabled", disabled); element.setAttribute("aria-disabled", disabled ? "true" : "false"); element.querySelectorAll("button, input, textarea, select").forEach((node) => { node.disabled = disabled; }); } buildEditEnhanceTab(el) { const locale7 = getLocale(); const section = this.createSection(el, locale7.headers.enhancedEditing); new import_obsidian5.Setting(section.bodyEl).setName(locale7.settings.codeblockEdit.name).setDesc(locale7.settings.codeblockEdit.desc).addToggle((toggle) => { toggle.setValue(this.plugin.settings.BetterCodeEdit).onChange(async (value) => { this.plugin.settings.BetterCodeEdit = value; await this.plugin.saveSettings(); }); }); new import_obsidian5.Setting(section.bodyEl).setName(locale7.settings.backspaceEdit.name).setDesc(locale7.settings.backspaceEdit.desc).addToggle((toggle) => { toggle.setValue(this.plugin.settings.BetterBackspace).onChange(async (value) => { this.plugin.settings.BetterBackspace = value; await this.plugin.saveSettings(); }); }); new import_obsidian5.Setting(section.bodyEl).setName(locale7.settings.tabOut.name).setDesc(locale7.settings.tabOut.desc).addToggle((toggle) => { toggle.setValue(this.plugin.settings.Tabout).onChange(async (value) => { this.plugin.settings.Tabout = value; await this.plugin.saveSettings(); }); }); new import_obsidian5.Setting(section.bodyEl).setName(locale7.settings.enhanceModA.name).setDesc(locale7.settings.enhanceModA.desc).addToggle((toggle) => { toggle.setValue(this.plugin.settings.EnhanceModA).onChange(async (value) => { this.plugin.settings.EnhanceModA = value; await this.plugin.saveSettings(); }); }); new import_obsidian5.Setting(section.bodyEl).setName(locale7.settings.smartPaste.name).setDesc(locale7.settings.smartPaste.desc).addToggle((toggle) => { toggle.setValue(this.plugin.settings.SmartPaste).onChange(async (value) => { this.plugin.settings.SmartPaste = value; await this.plugin.saveSettings(); }); }); } buildAutoFormatTab(el) { const locale7 = getLocale(); const overviewSection = this.createSection(el, locale7.headers.autoformatSetting); new import_obsidian5.Setting(overviewSection.bodyEl).setName(locale7.settings.autoFormatting.name).setDesc(locale7.settings.autoFormatting.desc).addToggle((toggle) => { toggle.setValue(this.plugin.settings.AutoFormat).onChange(async (value) => { this.plugin.settings.AutoFormat = value; await this.plugin.saveSettings(); syncAutoFormatState(value); }); }); const pasteSetting = new import_obsidian5.Setting(overviewSection.bodyEl).setName(locale7.settings.autoFormatPaste.name).setDesc(locale7.settings.autoFormatPaste.desc).addToggle((toggle) => { toggle.setValue(this.plugin.settings.AutoFormatPaste).onChange(async (value) => { this.plugin.settings.AutoFormatPaste = value; await this.plugin.saveSettings(); }); }); const autoCapitalSetting = new import_obsidian5.Setting(overviewSection.bodyEl).setName(locale7.settings.capitalizeFirstLetter.name).setDesc(locale7.settings.capitalizeFirstLetter.desc).addToggle((toggle) => { toggle.setTooltip(locale7.toolTip.switch); toggle.setValue(this.plugin.settings.AutoCapital).onChange(async (value) => { this.plugin.settings.AutoCapital = value; await this.plugin.saveSettings(); }); }); const languageSection = this.createSection(el, locale7.headers.languagePairSection, locale7.settings.languagePairSpacing.desc); const scriptListContainer = languageSection.bodyEl.createDiv({ cls: "et-custom-scripts" }); const capsuleContainer = languageSection.bodyEl.createDiv({ cls: "et-lang-pair-capsules" }); const renderCapsules = () => { capsuleContainer.empty(); for (let idx = 0; idx < this.plugin.settings.languagePairs.length; idx++) { const pair = this.plugin.settings.languagePairs[idx]; const capsule = capsuleContainer.createSpan({ cls: "et-lang-pair-capsule" }); const labelA = locale7.scriptCategoryLabels[pair.a] || pair.a; const labelB = locale7.scriptCategoryLabels[pair.b] || pair.b; capsule.createSpan({ text: `${labelA} \u2194 ${labelB}` }); const removeBtn = capsule.createEl("button", { cls: "et-capsule-remove", text: "\xD7", attr: { type: "button", "aria-label": locale7.toolTip.removeRule } }); removeBtn.addEventListener("click", async () => { this.plugin.settings.languagePairs.splice(idx, 1); await this.plugin.saveSettings(); renderCapsules(); }); } }; const renderScripts = () => { scriptListContainer.empty(); for (let i = 0; i < this.plugin.settings.customScriptCategories.length; i++) { const cat = this.plugin.settings.customScriptCategories[i]; const item = new import_obsidian5.Setting(scriptListContainer); item.setName(`${cat.name} [${cat.pattern}]`); item.addExtraButton((btn) => { btn.setIcon("trash").setTooltip(locale7.toolTip.removeRule).onClick(async () => { this.plugin.settings.languagePairs = this.plugin.settings.languagePairs.filter((p) => p.a !== cat.name && p.b !== cat.name); this.plugin.settings.customScriptCategories.splice(i, 1); await this.plugin.saveSettings(); renderScripts(); renderCapsules(); }); }); } }; renderScripts(); renderCapsules(); const addScriptRow = new import_obsidian5.Setting(languageSection.bodyEl); addScriptRow.settingEl.addClass("et-inline-form-setting"); let newScriptName = ""; let newScriptPattern = ""; addScriptRow.setName(locale7.headers.customScriptSection).addText((text) => { text.setPlaceholder(locale7.settings.customScriptCategories.namePlaceholder).onChange((v) => { newScriptName = v; }); }).addText((text) => { text.setPlaceholder(locale7.settings.customScriptCategories.patternPlaceholder).onChange((v) => { newScriptPattern = v; }); }).addButton((btn) => { btn.setButtonText("+").onClick(async () => { if (!newScriptName.trim() || !newScriptPattern.trim()) return; try { new RegExp(`[${newScriptPattern}]`); } catch (e) { return; } this.plugin.settings.customScriptCategories.push({ name: newScriptName.trim(), pattern: newScriptPattern.trim() }); await this.plugin.saveSettings(); renderScripts(); this.display(); }); }); const addRow = languageSection.bodyEl.createDiv({ cls: "et-pair-selector-row" }); const allCategories = this.getAllScriptCategories(); let selectedA = allCategories[0] || ""; let selectedB = allCategories[1] || ""; const selectorSetting = new import_obsidian5.Setting(addRow); selectorSetting.settingEl.addClass("et-inline-form-setting"); selectorSetting.setName(locale7.headers.addLanguagePair).addDropdown((dd) => { for (const cat of allCategories) { dd.addOption(cat, locale7.scriptCategoryLabels[cat] || cat); } dd.setValue(selectedA); dd.onChange((v) => { selectedA = v; }); }).addDropdown((dd) => { for (const cat of allCategories) { dd.addOption(cat, locale7.scriptCategoryLabels[cat] || cat); } dd.setValue(selectedB); dd.onChange((v) => { selectedB = v; }); }).addButton((btn) => { btn.setButtonText("+").onClick(async () => { if (selectedA === selectedB) return; const exists = this.plugin.settings.languagePairs.some((p) => p.a === selectedA && p.b === selectedB || p.a === selectedB && p.b === selectedA); if (exists) return; this.plugin.settings.languagePairs.push({ a: selectedA, b: selectedB }); await this.plugin.saveSettings(); renderCapsules(); }); }); const detailSection = this.createSection(el, locale7.headers.detailedSetting); const introDiv = detailSection.bodyEl.createDiv({ cls: "et-settings-note et-space-strategy-intro setting-item-description" }); introDiv.innerText = locale7.headers.spaceStrategyIntro || "\u7A7A\u683C\u7B56\u7565\u8BF4\u660E\uFF1A\n\u65E0\u8981\u6C42\uFF1A\u5BF9\u76F8\u5173\u533A\u5757\u4E0E\u5DE6\u53F3\u6587\u672C\u6CA1\u6709\u7A7A\u683C\u8981\u6C42\u3002\n\u8F6F\u7A7A\u683C\uFF1A\u53EA\u8981\u6C42\u6709\u8F6F\u7A7A\u683C\u3002\n\u4E25\u683C\u7A7A\u683C\uFF1A\u4E25\u683C\u6DFB\u52A0\u771F\u5B9E\u7A7A\u683C\u3002"; new import_obsidian5.Setting(detailSection.bodyEl).setName(locale7.settings.spaceStrategyInlineCode.name).setDesc(locale7.settings.spaceStrategyInlineCode.desc).addDropdown((dropdown) => { dropdown.addOption(String(0 /* none */), locale7.dropdownOptions.noRequire); dropdown.addOption(String(1 /* soft */), locale7.dropdownOptions.softSpace); dropdown.addOption(String(2 /* strict */), locale7.dropdownOptions.strictSpace); dropdown.setValue(String(this.plugin.settings.InlineCodeSpaceMode)); dropdown.onChange(async (v) => { this.plugin.settings.InlineCodeSpaceMode = string2SpaceState(v); await this.plugin.saveSettings(); }); }); new import_obsidian5.Setting(detailSection.bodyEl).setName(locale7.settings.spaceStrategyInlineFormula.name).setDesc(locale7.settings.spaceStrategyInlineFormula.desc).addDropdown((dropdown) => { dropdown.addOption(String(0 /* none */), locale7.dropdownOptions.noRequire); dropdown.addOption(String(1 /* soft */), locale7.dropdownOptions.softSpace); dropdown.addOption(String(2 /* strict */), locale7.dropdownOptions.strictSpace); dropdown.setValue(String(this.plugin.settings.InlineFormulaSpaceMode)); dropdown.onChange(async (v) => { this.plugin.settings.InlineFormulaSpaceMode = string2SpaceState(v); await this.plugin.saveSettings(); }); }); new import_obsidian5.Setting(detailSection.bodyEl).setName(locale7.settings.spaceStrategyLinkText.name).setDesc(locale7.settings.spaceStrategyLinkText.desc).addDropdown((dropdown) => { dropdown.addOption("dummy", locale7.dropdownOptions.dummy); dropdown.addOption("smart", locale7.dropdownOptions.smart); dropdown.setValue(this.plugin.settings.InlineLinkSmartSpace ? "smart" : "dummy"); dropdown.onChange(async (v) => { this.plugin.settings.InlineLinkSmartSpace = v == "smart" ? true : false; await this.plugin.saveSettings(); }); }).addDropdown((dropdown) => { dropdown.addOption(String(0 /* none */), locale7.dropdownOptions.noRequire); dropdown.addOption(String(1 /* soft */), locale7.dropdownOptions.softSpace); dropdown.addOption(String(2 /* strict */), locale7.dropdownOptions.strictSpace); dropdown.setValue(String(this.plugin.settings.InlineLinkSpaceMode)); dropdown.onChange(async (v) => { this.plugin.settings.InlineLinkSpaceMode = string2SpaceState(v); await this.plugin.saveSettings(); }); }); new import_obsidian5.Setting(detailSection.bodyEl).setName(locale7.settings.softSpaceSymbols.leftName).setDesc(locale7.settings.softSpaceSymbols.leftDesc).addText((text) => { text.setValue(this.plugin.settings.SoftSpaceLeftSymbols).onChange(async (value) => { this.plugin.settings.SoftSpaceLeftSymbols = value; await this.plugin.saveSettings(); }); }); new import_obsidian5.Setting(detailSection.bodyEl).setName(locale7.settings.softSpaceSymbols.rightName).setDesc(locale7.settings.softSpaceSymbols.rightDesc).addText((text) => { text.setValue(this.plugin.settings.SoftSpaceRightSymbols).onChange(async (value) => { this.plugin.settings.SoftSpaceRightSymbols = value; await this.plugin.saveSettings(); }); }); const prefixSection = this.createSection(el, locale7.headers.prefixDictSection, locale7.settings.prefixDictionary.desc); const prefixSetting = new import_obsidian5.Setting(prefixSection.bodyEl); prefixSetting.settingEl.addClass("et-setting-full-width"); const prefixArea = new import_obsidian5.TextAreaComponent(prefixSetting.controlEl); prefixArea.inputEl.addClass("et-settings-textarea", "et-settings-textarea-compact"); prefixArea.setValue(this.plugin.settings.PrefixDictionary).onChange(async (value) => { this.plugin.settings.PrefixDictionary = value; this.plugin.saveSettings(); }); const regexSection = this.createSection(el, locale7.headers.customRegexpBlock); const regexInfoDiv = regexSection.bodyEl.createDiv({ cls: "setting-item-description et-settings-section-desc" }); regexInfoDiv.appendChild(createFragment((frag) => { frag.appendText(locale7.headers.aboutRegexp.header); frag.createEl("a", { text: locale7.headers.aboutRegexp.text, href: "https://javascript.ruanyifeng.com/stdlib/regexp.html#" }); })); const regSwitchSetting = new import_obsidian5.Setting(regexSection.bodyEl).setName(locale7.settings.userDefinedRegexpSwitch.name).setDesc(locale7.settings.userDefinedRegexpSwitch.desc).addToggle((toggle) => { toggle.setValue(this.plugin.settings.UserDefinedRegSwitch).onChange(async (value) => { this.plugin.settings.UserDefinedRegSwitch = value; await this.plugin.saveSettings(); syncRegexContentState(); }); }); const regContentAreaSetting = new import_obsidian5.Setting(regexSection.bodyEl); regContentAreaSetting.settingEl.addClass("et-setting-full-width"); regContentAreaSetting.setName(locale7.settings.userDefinedRegexp.name).setDesc(locale7.settings.userDefinedRegexp.desc); const regContentArea = new import_obsidian5.TextAreaComponent(regContentAreaSetting.controlEl); regContentArea.inputEl.addClass("et-settings-textarea", "et-settings-textarea-tall"); regContentArea.setValue(this.plugin.settings.UserDefinedRegExp).onChange(async (value) => { this.plugin.settings.UserDefinedRegExp = value; this.plugin.saveSettings(); }); new import_obsidian5.Setting(regexSection.bodyEl).setName(locale7.settings.userRulesRespectUserDefinedRegexBlocks.name).setDesc(locale7.settings.userRulesRespectUserDefinedRegexBlocks.desc).addToggle((toggle) => { toggle.setValue(this.plugin.settings.UserRulesRespectUserDefinedRegexBlocks).onChange(async (value) => { this.plugin.settings.UserRulesRespectUserDefinedRegexBlocks = value; await this.plugin.saveSettings(); }); }); const excludeSection = this.createSection(el, locale7.headers.excludeFoldersFiles, locale7.settings.excludeFoldersFiles.desc); const excludeSetting = new import_obsidian5.Setting(excludeSection.bodyEl); excludeSetting.settingEl.addClass("et-setting-full-width"); excludeSetting.addTextArea((text) => { text.setValue(this.plugin.settings.ExcludeFiles); text.inputEl.addClass("et-settings-textarea"); text.onChange(async (value) => { this.plugin.settings.ExcludeFiles = value; this.plugin.saveSettings(); }); }); const advancedSections = [ languageSection.sectionEl, detailSection.sectionEl, prefixSection.sectionEl, regexSection.sectionEl, excludeSection.sectionEl ]; const syncRegexContentState = () => { this.setInteractiveDisabled(regContentAreaSetting.settingEl, !this.plugin.settings.AutoFormat || !this.plugin.settings.UserDefinedRegSwitch); }; const syncAutoFormatState = (enabled) => { this.setInteractiveDisabled(pasteSetting.settingEl, !enabled); this.setInteractiveDisabled(autoCapitalSetting.settingEl, !enabled); advancedSections.forEach((sectionEl) => this.setInteractiveDisabled(sectionEl, !enabled)); this.setInteractiveDisabled(regSwitchSetting.settingEl, !enabled); syncRegexContentState(); }; syncAutoFormatState(this.plugin.settings.AutoFormat); } getAllScriptCategories() { const builtin = [ "chinese" /* Chinese */, "japanese" /* Japanese */, "korean" /* Korean */, "cjk" /* CJK */, "english" /* English */, "digit" /* Digit */, "russian" /* Russian */ ]; const custom = (this.plugin.settings.customScriptCategories || []).map((c) => c.name); return [...builtin, ...custom]; } buildBuiltinRulesSection(el) { const locale7 = getLocale(); const section = this.createSection(el, locale7.headers.builtinRulesSection, void 0, (actionsEl) => { const resetBtn = actionsEl.createEl("button", { text: locale7.toolTip.resetAllRules, cls: "et-reset-btn et-section-action-btn" }); resetBtn.addEventListener("click", async () => { await this.plugin.ruleManager.resetAllBuiltinRules(); new import_obsidian5.Notice(locale7.toolTip.resetSuccess); this.display(); }); }, "et-builtin-rules-section"); for (const rule of this.plugin.ruleManager.cachedBuiltinRules) { this.buildRuleItem(section.bodyEl, rule, true); } const deletedIds = this.plugin.settings.deletedBuiltinRuleIds || []; if (deletedIds.length > 0) { const details = section.bodyEl.createEl("details", { cls: "et-deleted-rules" }); details.createEl("summary", { text: `${locale7.headers.deletedRulesSection} (${deletedIds.length})` }); for (const id of deletedIds) { const defaultRule = DEFAULT_BUILTIN_RULES.find((r) => r.id === id); if (!defaultRule) continue; const opts = RuleEngine.parseOptions(defaultRule.options); const typeLabel = this.getRuleTypeLabel(opts.type); const typeCls = this.getRuleTypeCls(opts.type); const preview = defaultRule.id && locale7.builtinRuleDescriptions[defaultRule.id] || defaultRule.description || `${RuleEngine.escapeText(defaultRule.trigger, opts.isRegex)} \u2192 ${typeof defaultRule.replacement === "string" ? defaultRule.replacement : "(fn)"}`; new import_obsidian5.Setting(details).setName(createFragment((f) => { f.createSpan({ cls: `et-rule-type-tag ${typeCls}`, text: typeLabel }); f.createSpan({ text: preview }); })).addButton((button) => { button.setButtonText(locale7.toolTip.restoreRule).onClick(async () => { await this.plugin.ruleManager.restoreBuiltinRule(id); this.display(); }); }); } } } buildUserRulesSection(el) { const locale7 = getLocale(); const section = this.createSection(el, locale7.headers.userRulesSection, void 0, (actionsEl) => { const addBtn = actionsEl.createEl("button", { text: "+", cls: "mod-cta et-section-action-btn" }); addBtn.addEventListener("click", () => { new RuleEditModal(this.app, "create", {}, async (rule) => { await this.plugin.ruleManager.addUserRule(rule); this.display(); }).open(); }); const exportBtn = actionsEl.createEl("button", { cls: "clickable-icon et-section-icon-btn" }); exportBtn.setAttribute("aria-label", locale7.toolTip.exportRules); (0, import_obsidian5.setIcon)(exportBtn, "arrow-up-from-line"); exportBtn.addEventListener("click", () => { const rules = this.plugin.ruleManager.cachedUserRules; if (rules.length === 0) { new import_obsidian5.Notice(locale7.toolTip.noRulesToExport); return; } const json = JSON.stringify(rules, null, 2); const blob = new Blob([json], { type: "application/json" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = "easy-typing-user-rules.json"; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); }); const importBtn = actionsEl.createEl("button", { cls: "clickable-icon et-section-icon-btn" }); importBtn.setAttribute("aria-label", locale7.toolTip.importRules); (0, import_obsidian5.setIcon)(importBtn, "arrow-down-to-line"); importBtn.addEventListener("click", () => { const input = document.createElement("input"); input.type = "file"; input.accept = ".json"; input.style.display = "none"; input.addEventListener("change", async () => { var _a; const file = (_a = input.files) == null ? void 0 : _a[0]; if (!file) return; try { const text = await file.text(); let parsed; try { parsed = JSON.parse(text); } catch (e) { new import_obsidian5.Notice(`[EasyTyping] ${locale7.toolTip.importInvalidJson}`); return; } if (!Array.isArray(parsed) || parsed.length === 0) { new import_obsidian5.Notice(`[EasyTyping] ${locale7.toolTip.importNoRules}`); return; } const { imported, skipped } = await this.plugin.ruleManager.importUserRules(parsed); if (imported === 0 && skipped > 0) { new import_obsidian5.Notice(`[EasyTyping] ${locale7.toolTip.importNoRules}`); } else { new import_obsidian5.Notice(`[EasyTyping] ${(0, import_sprintf_js.sprintf)(locale7.toolTip.importSuccess, imported, skipped)}`); } this.display(); } finally { input.remove(); } }); document.body.appendChild(input); input.click(); }); }, "et-user-rules-section"); this.plugin.ruleManager.cachedUserRules.forEach((rule, index) => { this.buildRuleItem(section.bodyEl, rule, false, index); }); } buildRuleItem(container, rule, isBuiltin, ruleIndex) { const locale7 = getLocale(); const opts = RuleEngine.parseOptions(rule.options); const typeLabel = this.getRuleTypeLabel(opts.type); const typeCls = this.getRuleTypeCls(opts.type); const enabled = rule.enabled !== false; const isTab = opts.triggerMode === "tab" /* Tab */; const isFn = opts.isFunctionReplacement; const scopeBadges = this.getRuleScopeBadges(opts.scope, rule.scope_language, locale7); let preview; if (rule.description) { preview = rule.description; } else { const repl = typeof rule.replacement === "string" ? rule.replacement : "(fn)"; const renderMatch = (text) => RuleEngine.escapeText(text, opts.isRegex); preview = `${renderMatch(rule.trigger)}${rule.trigger_right ? " \u2026 " + renderMatch(rule.trigger_right) : ""} \u2192 ${repl}`; } const setting = new import_obsidian5.Setting(container).setClass("et-rule-item").setName(createFragment((f) => { f.createSpan({ cls: `et-rule-type-tag ${typeCls}`, text: typeLabel }); scopeBadges.forEach((badge) => { f.createSpan({ cls: `et-rule-scope-tag ${badge.cls}`, text: badge.text }); }); if (opts.type === "input" /* Input */) { const modeTag = f.createSpan({ cls: `et-rule-trigger-mode ${isTab ? "et-trigger-mode-tab" : "et-trigger-mode-auto"}`, text: isTab ? "Tab" : "Auto" }); modeTag.setAttribute("aria-label", locale7.settings.ruleEditModal.fieldTriggerMode); modeTag.addEventListener("click", async (e) => { e.stopPropagation(); const newIsTab = !isTab; await this.plugin.ruleManager.updateRuleTriggerMode(rule.id, isBuiltin, newIsTab); this.display(); }); } if (isFn) { f.createSpan({ cls: "et-rule-type-tag et-rule-type-fn", text: "Fn" }); } f.createSpan({ cls: "et-rule-preview-text", text: preview }); })).addToggle((toggle) => { toggle.setValue(enabled).setTooltip(locale7.toolTip.enableRule).onChange(async (value) => { setting.settingEl.style.opacity = value ? "" : "0.5"; await this.plugin.ruleManager.toggleRuleEnabled(rule.id, isBuiltin, value); }); }).addExtraButton((button) => { button.setIcon("gear").setTooltip(locale7.toolTip.editRule).onClick(() => { new RuleEditModal(this.app, "edit", rule, async (updated) => { if (isBuiltin) { await this.plugin.ruleManager.updateBuiltinRule(rule.id, updated); } else { await this.plugin.ruleManager.updateUserRule(rule.id, updated); } this.display(); }).open(); }); }).addExtraButton((button) => { button.setIcon("trash").setTooltip(locale7.toolTip.removeRule).onClick(async () => { if (isBuiltin) { await this.plugin.ruleManager.deleteBuiltinRule(rule.id); } else { await this.plugin.ruleManager.deleteUserRule(rule.id); } this.display(); }); }); if (!enabled) { setting.settingEl.style.opacity = "0.5"; } if (!isBuiltin && ruleIndex !== void 0) { const el = setting.settingEl; el.dataset.ruleIndex = String(ruleIndex); const handle = el.createDiv({ cls: "et-rule-drag-handle" }); (0, import_obsidian5.setIcon)(handle, "grip-vertical"); el.prepend(handle); handle.draggable = true; let cachedMidY = 0; handle.addEventListener("dragstart", (e) => { this.dragSourceIndex = parseInt(el.dataset.ruleIndex); el.addClass("et-rule-dragging"); e.dataTransfer.effectAllowed = "move"; }); handle.addEventListener("dragend", () => { var _a; this.dragSourceIndex = null; el.removeClass("et-rule-dragging"); (_a = el.parentElement) == null ? void 0 : _a.querySelectorAll(".et-rule-drag-over-top, .et-rule-drag-over-bottom").forEach((item) => item.removeClass("et-rule-drag-over-top", "et-rule-drag-over-bottom")); }); el.addEventListener("dragenter", () => { const rect = el.getBoundingClientRect(); cachedMidY = rect.top + rect.height / 2; }); el.addEventListener("dragover", (e) => { if (this.dragSourceIndex === null) return; e.preventDefault(); e.dataTransfer.dropEffect = "move"; const isTop = e.clientY < cachedMidY; const targetCls = isTop ? "et-rule-drag-over-top" : "et-rule-drag-over-bottom"; if (!el.hasClass(targetCls)) { el.removeClass("et-rule-drag-over-top", "et-rule-drag-over-bottom"); el.addClass(targetCls); } }); el.addEventListener("dragleave", () => { el.removeClass("et-rule-drag-over-top", "et-rule-drag-over-bottom"); }); el.addEventListener("drop", async (e) => { e.preventDefault(); el.removeClass("et-rule-drag-over-top", "et-rule-drag-over-bottom"); const fromIndex = this.dragSourceIndex; if (fromIndex === null) return; const currentIndex = parseInt(el.dataset.ruleIndex); const dropOnBottom = e.clientY >= cachedMidY; let toIndex; if (fromIndex < currentIndex) { toIndex = dropOnBottom ? currentIndex : currentIndex - 1; } else { toIndex = dropOnBottom ? currentIndex + 1 : currentIndex; } if (fromIndex === toIndex) return; await this.plugin.ruleManager.reorderUserRule(fromIndex, toIndex); const parent = el.parentElement; const ruleItems = Array.from(parent.querySelectorAll(".et-rule-item[data-rule-index]")); const sourceEl = ruleItems[fromIndex]; if (!sourceEl) return; if (toIndex < fromIndex) { parent.insertBefore(sourceEl, ruleItems[toIndex]); } else { const ref = ruleItems[toIndex]; if (ref.nextSibling) { parent.insertBefore(sourceEl, ref.nextSibling); } else { parent.appendChild(sourceEl); } } ruleItems.splice(fromIndex, 1); ruleItems.splice(toIndex, 0, sourceEl); ruleItems.forEach((item, i) => item.dataset.ruleIndex = String(i)); }); } } getRuleScopeBadges(scopes, scopeLanguage, locale7 = getLocale()) { const badges = []; if (scopes.includes("code" /* Code */)) { badges.push({ text: `<${scopeLanguage || locale7.dropdownOptions.scopeCode}>`, cls: "et-rule-scope-code" }); } if (scopes.includes("formula" /* Formula */)) { badges.push({ text: "\u0192x", cls: "et-rule-scope-formula" }); } return badges; } getRuleTypeLabel(type) { const locale7 = getLocale(); switch (type) { case "input" /* Input */: return locale7.settings.ruleType.input; case "delete" /* Delete */: return locale7.settings.ruleType.delete; case "selectKey" /* SelectKey */: return locale7.settings.ruleType.selectKey; } } getRuleTypeCls(type) { switch (type) { case "input" /* Input */: return "et-rule-type-input"; case "delete" /* Delete */: return "et-rule-type-delete"; case "selectKey" /* SelectKey */: return "et-rule-type-selectkey"; } } buildOtherTab(el) { const locale7 = getLocale(); const experimentalSection = this.createSection(el, locale7.headers.experimentalFeatures); new import_obsidian5.Setting(experimentalSection.bodyEl).setName(locale7.settings.strictLineBreaks.name).setDesc(locale7.settings.strictLineBreaks.desc).addDropdown((dropdown) => { dropdown.addOption("enter_twice" /* EnterTwice */, locale7.dropdownOptions.enterTwice); dropdown.addOption("two_space" /* TwoSpace */, locale7.dropdownOptions.twoSpace); dropdown.addOption("mix_mode" /* Mix */, locale7.dropdownOptions.mixMode); dropdown.setValue(this.plugin.settings.StrictLineMode); dropdown.onChange(async (v) => { this.plugin.settings.StrictLineMode = v; await this.plugin.saveSettings(); }); }).addToggle((toggle) => { toggle.setValue(this.plugin.settings.StrictModeEnter).onChange(async (value) => { this.plugin.settings.StrictModeEnter = value; await this.plugin.saveSettings(); }); }); new import_obsidian5.Setting(experimentalSection.bodyEl).setName(locale7.settings.collapsePersistentEnter.name).setDesc(locale7.settings.collapsePersistentEnter.desc).addToggle((toggle) => { toggle.setValue(this.plugin.settings.CollapsePersistentEnter).onChange(async (value) => { this.plugin.settings.CollapsePersistentEnter = value; await this.plugin.saveSettings(); }); }); new import_obsidian5.Setting(experimentalSection.bodyEl).setName(locale7.settings.fixMicrosoftIME.name).setDesc(locale7.settings.fixMicrosoftIME.desc).addToggle((toggle) => { toggle.setValue(this.plugin.settings.TryFixMSIME).onChange(async (value) => { this.plugin.settings.TryFixMSIME = value; await this.plugin.saveSettings(); }); }); new import_obsidian5.Setting(experimentalSection.bodyEl).setName(locale7.settings.fixMacOSContextMenu.name).setDesc(locale7.settings.fixMacOSContextMenu.desc).addToggle((toggle) => { toggle.setValue(this.plugin.settings.FixMacOSContextMenu).onChange(async (value) => { this.plugin.settings.FixMacOSContextMenu = value; await this.plugin.saveSettings(); }); }); const miscSection = this.createSection(el); new import_obsidian5.Setting(miscSection.bodyEl).setName(locale7.settings.rulesStoragePath.name).setDesc(locale7.settings.rulesStoragePath.desc).addText((text) => { text.setPlaceholder(locale7.settings.rulesStoragePath.defaultOption).setValue(this.plugin.settings.rulesStoragePath); new FolderSuggest(this.app, text.inputEl, locale7.settings.rulesStoragePath.defaultOption, async (path) => { this.plugin.settings.rulesStoragePath = path; await this.plugin.saveSettings(); await this.plugin.ruleManager.initRuleEngine(); this.display(); }); }).addButton((btn) => { btn.setButtonText(locale7.settings.rulesStoragePath.migrateButton).setTooltip(locale7.settings.rulesStoragePath.migrateDesc).onClick(async () => { const oldPath = this.plugin.ruleManager.previousStoragePath; const newPath = this.plugin.settings.rulesStoragePath; await this.plugin.ruleManager.migrateRulesFiles(oldPath, newPath); await this.plugin.ruleManager.initRuleEngine(); new import_obsidian5.Notice(locale7.settings.rulesStoragePath.migrateSuccess); this.display(); }); }); new import_obsidian5.Setting(miscSection.bodyEl).setName(locale7.settings.printDebugInfo.name).setDesc(locale7.settings.printDebugInfo.desc).addToggle((toggle) => { toggle.setValue(this.plugin.settings.debug).onChange(async (value) => { this.plugin.settings.debug = value; setDebug(value); await this.plugin.saveSettings(); }); }); } }; // src/main.ts var import_view5 = require("@codemirror/view"); // src/tabstops_state_field.ts var import_view2 = require("@codemirror/view"); var import_state3 = require("@codemirror/state"); var addTabstopsEffect = import_state3.StateEffect.define(); var removeTabstopEffect = import_state3.StateEffect.define(); var removeAllTabstopsEffect = import_state3.StateEffect.define(); var tabstopsStateField = import_state3.StateField.define({ create() { return []; }, update(value, transaction) { let tabstopGroups = value; tabstopGroups.forEach((grp) => grp.map(transaction.changes)); for (const effect of transaction.effects) { if (effect.is(addTabstopsEffect)) { tabstopGroups = []; tabstopGroups.unshift(...effect.value); } else if (effect.is(removeTabstopEffect)) { tabstopGroups.shift(); } else if (effect.is(removeAllTabstopsEffect)) { tabstopGroups = []; } } return tabstopGroups; }, provide: (field) => { return import_view2.EditorView.decorations.of((view) => { const tabstopGroups = view.state.field(field); const decos = []; if (tabstopGroups.length >= 2) { decos.push(...tabstopGroups[1].getDecoRanges()); } return import_view2.Decoration.set(decos, true); }); } }); function getTabstopGroupsFromView(view) { const currentTabstopGroups = view.state.field(tabstopsStateField, false); return currentTabstopGroups != null ? currentTabstopGroups : []; } function hasTabstops(view) { return getTabstopGroupsFromView(view).length > 0; } function removeTabstop(view) { view.dispatch({ effects: [removeTabstopEffect.of(null)] }); } function removeAllTabstops(view) { view.dispatch({ effects: [removeAllTabstopsEffect.of(null)] }); } function tidyTabstops(view) { const currentTabstopGroups = getTabstopGroupsFromView(view); if (currentTabstopGroups.length === 1) { removeAllTabstops(view); } } function isInsideCurTabstop(view) { const currentTabstopGroups = getTabstopGroupsFromView(view); if (currentTabstopGroups.length > 1 && currentTabstopGroups[0].containsSelection(view.state.selection)) { return true; } return false; } function consumeAndGotoNextTabstop(view) { if (getTabstopGroupsFromView(view).length === 0) return false; removeTabstop(view); const oldSel = view.state.selection; const nextGrp = getTabstopGroupsFromView(view)[0]; if (!nextGrp) return false; const shouldMoveToEndpoints = nextGrp.containsSelection(oldSel); nextGrp.select(view, shouldMoveToEndpoints); const newSel = view.state.selection; if (oldSel.eq(newSel)) return consumeAndGotoNextTabstop(view); tidyTabstops(view); return true; } // src/rule_manager.ts var RuleManager = class { constructor(app, manifest, settings, savePluginSettings) { this.app = app; this.manifest = manifest; this.settings = settings; this.savePluginSettings = savePluginSettings; this.cachedBuiltinRules = []; this.cachedUserRules = []; this.previousStoragePath = ""; this.lastSaveTime = 0; this.BUILTIN_RULES_FILE = "builtin-rules.json"; this.USER_RULES_FILE = "user-rules.json"; this.previousStoragePath = settings.rulesStoragePath; } getLocalizedBuiltinRules(rules = DEFAULT_BUILTIN_RULES) { const localeDescMap = getLocale().builtinRuleDescriptions; return rules.map((rule) => { var _a; return { ...rule, description: (_a = localeDescMap[rule.id]) != null ? _a : rule.description }; }); } getImportDedupKey(rule) { var _a, _b; const isRegex = ((_a = rule.options) != null ? _a : "").includes("r"); const normalizedFlags = isRegex ? RuleEngine.normalizeRegexFlags(rule.regex_flags) : ""; return `${rule.trigger}\0${(_b = rule.trigger_right) != null ? _b : ""}\0${isRegex}\0${normalizedFlags}`; } pluginPath(filename) { const base = this.settings.rulesStoragePath ? this.settings.rulesStoragePath : this.manifest.dir; return `${base}/${filename}`.replace(/\/+/g, "/"); } async loadRulesFile(filename) { const path = this.pluginPath(filename); try { const content = await this.app.vault.adapter.read(path); return JSON.parse(content); } catch (e) { return []; } } async saveRulesFile(filename, rules) { const path = this.pluginPath(filename); this.lastSaveTime = Date.now(); await this.app.vault.adapter.write(path, JSON.stringify(rules, null, 2)); } async mergeBuiltinRules() { const currentRules = await this.loadRulesFile(this.BUILTIN_RULES_FILE); const existingIds = new Set(currentRules.map((r) => r.id).filter(Boolean)); const deletedIds = new Set(this.settings.deletedBuiltinRuleIds); const newRules = DEFAULT_BUILTIN_RULES.filter((r) => !existingIds.has(r.id) && !deletedIds.has(r.id)); if (newRules.length === 0) return; await this.saveRulesFile(this.BUILTIN_RULES_FILE, [...currentRules, ...this.getLocalizedBuiltinRules(newRules)]); } async initRuleEngine() { this.ruleEngine = new RuleEngine(); if (this.settings.rulesStoragePath) { await this.app.vault.adapter.mkdir(this.settings.rulesStoragePath); } const builtinPath = this.pluginPath(this.BUILTIN_RULES_FILE); const userPath = this.pluginPath(this.USER_RULES_FILE); if (!await this.app.vault.adapter.exists(builtinPath)) { await this.saveRulesFile(this.BUILTIN_RULES_FILE, this.getLocalizedBuiltinRules()); } else { await this.mergeBuiltinRules(); } if (!await this.app.vault.adapter.exists(userPath)) { await this.saveRulesFile(this.USER_RULES_FILE, []); } const builtinRules = await this.loadRulesFile(this.BUILTIN_RULES_FILE); const userRules = await this.loadRulesFile(this.USER_RULES_FILE); this.cachedBuiltinRules = builtinRules; this.cachedUserRules = userRules; this.ruleEngine.loadFromFiles(builtinRules, userRules); } async deleteBuiltinRule(id) { this.ruleEngine.removeRule(id); this.cachedBuiltinRules = this.cachedBuiltinRules.filter((r) => r.id !== id); await this.saveRulesFile(this.BUILTIN_RULES_FILE, this.cachedBuiltinRules); this.settings.deletedBuiltinRuleIds.push(id); await this.savePluginSettings(); } async restoreBuiltinRule(id) { const defaultRule = DEFAULT_BUILTIN_RULES.find((r) => r.id === id); if (!defaultRule) return; const localizedRule = this.getLocalizedBuiltinRules([defaultRule])[0]; this.ruleEngine.addSimpleRule(localizedRule); this.cachedBuiltinRules.push(localizedRule); await this.saveRulesFile(this.BUILTIN_RULES_FILE, this.cachedBuiltinRules); this.settings.deletedBuiltinRuleIds = this.settings.deletedBuiltinRuleIds.filter((i) => i !== id); await this.savePluginSettings(); } async resetAllBuiltinRules() { this.cachedBuiltinRules = this.getLocalizedBuiltinRules(); await this.saveRulesFile(this.BUILTIN_RULES_FILE, this.cachedBuiltinRules); this.settings.deletedBuiltinRuleIds = []; await this.savePluginSettings(); this.ruleEngine.loadFromFiles(this.cachedBuiltinRules, this.cachedUserRules); } async addUserRule(rule) { const id = `user-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`; rule.id = id; this.cachedUserRules.push(rule); await this.saveRulesFile(this.USER_RULES_FILE, this.cachedUserRules); this.ruleEngine.addSimpleRule(rule); return id; } async importUserRules(incoming) { var _a; const existingSet = new Set(this.cachedUserRules.map((r) => this.getImportDedupKey(r))); let imported = 0; let skipped = 0; for (const rule of incoming) { if (!rule.trigger || rule.replacement === void 0) { skipped++; continue; } const key = this.getImportDedupKey(rule); if (existingSet.has(key)) { skipped++; continue; } existingSet.add(key); const id = `user-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`; rule.id = id; rule.enabled = (_a = rule.enabled) != null ? _a : true; this.cachedUserRules.push(rule); this.ruleEngine.addSimpleRule(rule); imported++; } if (imported > 0) { await this.saveRulesFile(this.USER_RULES_FILE, this.cachedUserRules); } return { imported, skipped }; } async updateUserRule(id, rule) { const idx = this.cachedUserRules.findIndex((r) => r.id === id); if (idx === -1) return; rule.id = id; this.cachedUserRules[idx] = rule; await this.saveRulesFile(this.USER_RULES_FILE, this.cachedUserRules); this.ruleEngine.removeRule(id); this.ruleEngine.addSimpleRule(rule); } async deleteUserRule(id) { this.cachedUserRules = this.cachedUserRules.filter((r) => r.id !== id); await this.saveRulesFile(this.USER_RULES_FILE, this.cachedUserRules); this.ruleEngine.removeRule(id); } async updateBuiltinRule(id, rule) { const idx = this.cachedBuiltinRules.findIndex((r) => r.id === id); if (idx === -1) return; rule.id = id; this.cachedBuiltinRules[idx] = rule; await this.saveRulesFile(this.BUILTIN_RULES_FILE, this.cachedBuiltinRules); this.ruleEngine.removeRule(id); this.ruleEngine.addSimpleRule(rule); } async toggleRuleEnabled(id, isBuiltin, enabled) { const cache = isBuiltin ? this.cachedBuiltinRules : this.cachedUserRules; const file = isBuiltin ? this.BUILTIN_RULES_FILE : this.USER_RULES_FILE; const rule = cache.find((r) => r.id === id); if (!rule) return; rule.enabled = enabled; await this.saveRulesFile(file, cache); this.ruleEngine.setEnabled(id, enabled); } async reorderUserRule(fromIndex, toIndex) { if (fromIndex === toIndex) return; if (fromIndex < 0 || fromIndex >= this.cachedUserRules.length) return; if (toIndex < 0 || toIndex >= this.cachedUserRules.length) return; const [rule] = this.cachedUserRules.splice(fromIndex, 1); this.cachedUserRules.splice(toIndex, 0, rule); await this.saveRulesFile(this.USER_RULES_FILE, this.cachedUserRules); } async updateRuleTriggerMode(id, isBuiltin, tabMode) { var _a; const cache = isBuiltin ? this.cachedBuiltinRules : this.cachedUserRules; const file = isBuiltin ? this.BUILTIN_RULES_FILE : this.USER_RULES_FILE; const rule = cache.find((r) => r.id === id); if (!rule) return; let opts = (_a = rule.options) != null ? _a : ""; if (tabMode && !opts.includes("T")) opts += "T"; else if (!tabMode) opts = opts.replace(/T/g, ""); rule.options = opts || void 0; await this.saveRulesFile(file, cache); this.ruleEngine.updateRule(id, { triggerMode: tabMode ? "tab" /* Tab */ : "auto" /* Auto */ }); } async migrateRulesFiles(oldPath, newPath) { const oldBase = oldPath || this.manifest.dir; const newBase = newPath || this.manifest.dir; if (oldBase === newBase) return; if (newPath) { await this.app.vault.adapter.mkdir(newPath); } for (const filename of [this.BUILTIN_RULES_FILE, this.USER_RULES_FILE]) { const src = `${oldBase}/${filename}`; try { const content = await this.app.vault.adapter.read(src); await this.app.vault.adapter.write(`${newBase}/${filename}`, content); } catch (e) { } } this.previousStoragePath = newPath; } }; // src/syntax.ts var import_language2 = require("@codemirror/language"); function isCodeBlockInPos(state, pos) { let codeBlockInfos = getCodeBlocksInfos(state); for (let i = 0; i < codeBlockInfos.length; i++) { if (pos >= codeBlockInfos[i].start_pos && pos <= codeBlockInfos[i].end_pos) { return true; } } return false; } function getCodeBlockInfoInPos(state, pos) { let codeBlockInfos = getCodeBlocksInfos(state); for (let i = 0; i < codeBlockInfos.length; i++) { if (pos >= codeBlockInfos[i].start_pos && pos <= codeBlockInfos[i].end_pos) { return codeBlockInfos[i]; } } return null; } function selectCodeBlockInPos(view, selection) { let pos = selection.anchor; let codeBlockInfos = getCodeBlocksInfos(view.state); for (let i = 0; i < codeBlockInfos.length; i++) { if (pos >= codeBlockInfos[i].start_pos && pos <= codeBlockInfos[i].end_pos) { if (codeBlockInfos[i].code_start_pos == codeBlockInfos[i].code_end_pos) { view.dispatch({ selection: { anchor: codeBlockInfos[i].start_pos, head: codeBlockInfos[i].end_pos } }); return true; } let code_line_start = view.state.doc.lineAt(codeBlockInfos[i].code_start_pos); let isCodeSelected = selection.anchor == code_line_start.from && selection.head == codeBlockInfos[i].code_end_pos; let isCodeBlockSelected = selection.anchor == codeBlockInfos[i].start_pos && selection.head == codeBlockInfos[i].end_pos; if (isCodeSelected) { view.dispatch({ selection: { anchor: codeBlockInfos[i].start_pos, head: codeBlockInfos[i].end_pos } }); return true; } if (isCodeBlockSelected) return false; view.dispatch({ selection: { anchor: code_line_start.from, head: codeBlockInfos[i].code_end_pos } }); return true; } } return false; } function getCodeBlocksInfos(state) { let isCodeBlockBegin = false; let codeBlockInfos = []; let curCodeBlockInfo = null; const doc = state.doc; (0, import_language2.syntaxTree)(state).iterate({ enter(node) { var _a; const nodeName = node.name; const nodeFrom = node.from; const nodeTo = node.to; const nodeText = state.sliceDoc(nodeFrom, nodeTo); if (nodeName.includes("codeblock-begin")) { isCodeBlockBegin = true; const fenceMatch = nodeText.match(/[`~]{3,}/); let start_pos = nodeFrom + ((_a = fenceMatch == null ? void 0 : fenceMatch.index) != null ? _a : 0); let indent = start_pos - state.doc.lineAt(start_pos).from; let language = nodeText.trim().replace(/^[`~]{3,}/, "").trim(); curCodeBlockInfo = { start_pos, end_pos: -1, code_start_pos: -1, code_end_pos: -1, language: language.toLowerCase(), indent }; } else if (nodeName.includes("codeblock-end")) { isCodeBlockBegin = false; if (curCodeBlockInfo != null) { curCodeBlockInfo.end_pos = nodeTo; if (doc.lineAt(curCodeBlockInfo.start_pos).number == doc.lineAt(curCodeBlockInfo.end_pos).number - 1) { curCodeBlockInfo.code_start_pos = doc.lineAt(curCodeBlockInfo.start_pos).to; curCodeBlockInfo.code_end_pos = doc.lineAt(curCodeBlockInfo.start_pos).to; } else { let code_start_line = doc.lineAt(curCodeBlockInfo.start_pos).number + 1; let code_end_line = doc.lineAt(curCodeBlockInfo.end_pos).number - 1; curCodeBlockInfo.code_start_pos = doc.line(code_start_line).from + curCodeBlockInfo.indent; curCodeBlockInfo.code_end_pos = doc.line(code_end_line).to; } codeBlockInfos.push(curCodeBlockInfo); curCodeBlockInfo = null; } } } }); if (isCodeBlockBegin && curCodeBlockInfo) { curCodeBlockInfo.end_pos = doc.length; curCodeBlockInfo.code_end_pos = doc.length; if (doc.lines > doc.lineAt(curCodeBlockInfo.start_pos).number) { let start_line = doc.lineAt(curCodeBlockInfo.start_pos).number + 1; let code_start_pos = doc.line(start_line).from + curCodeBlockInfo.indent; curCodeBlockInfo.code_start_pos = code_start_pos < doc.length ? code_start_pos : doc.lineAt(curCodeBlockInfo.start_pos + 1).from; } else { curCodeBlockInfo.code_start_pos = doc.lineAt(curCodeBlockInfo.start_pos).to; } codeBlockInfos.push(curCodeBlockInfo); curCodeBlockInfo = null; } return codeBlockInfos; } function getQuoteInfoInPos(state, pos) { let quote_regex = /^(\s*)(>+) ?/; let callout_regex = /^(\s*)(>)+ \[![^\s]+\][+-]? ?/; let cur_line = state.doc.lineAt(pos); let match = cur_line.text.match(quote_regex); let is_callout = false; let cur_start_pos = -1; let cur_end_pos = -1; if (match) { let match_callout = cur_line.text.match(callout_regex); cur_start_pos = cur_line.from + (match_callout ? match_callout[0].length : match[0].length); cur_end_pos = cur_line.to; let quote_start_line = cur_line.number; let quote_end_line = quote_start_line; for (let i = quote_start_line + 1; i <= state.doc.lines; i += 1) { let line = state.doc.line(i); if (line.text.match(quote_regex)) { quote_end_line = i; } else break; } for (let i = quote_start_line; i >= 1; i -= 1) { let line = state.doc.line(i); let match_callout2 = line.text.match(callout_regex); let match_quote = line.text.match(quote_regex); if (match_callout2) { is_callout = true; quote_start_line = i; } else if (match_quote) { quote_start_line = i; } else break; } return { start_pos: state.doc.line(quote_start_line).from, end_pos: state.doc.line(quote_end_line).to, is_callout, cur_start_pos, cur_end_pos }; } else { return null; } } function detectRuleScope(state, pos) { const tree = (0, import_language2.syntaxTree)(state); const node = tree.resolveInner(pos, -1); const name = node.name; if (name.contains("math")) { return { scope: "formula" /* Formula */ }; } if (name.contains("code") && !name.contains("link")) { const codeBlockInfo = getCodeBlockInfoInPos(state, pos); return { scope: "code" /* Code */, language: (codeBlockInfo == null ? void 0 : codeBlockInfo.language) || void 0 }; } return { scope: "text" /* Text */ }; } // src/comment_toggle.ts function toggleComment(view) { const state = view.state; const selection = state.selection.main; const codeBlockInfo = getCodeBlockInfoInPos(state, selection.from); if (codeBlockInfo) { return toggleCodeBlockComment(view); } return toggleMarkdownComment(selection.from, selection.to, view); } function toggleCodeBlockComment(view) { const state = view.state; const selection = state.selection.main; const codeBlockInfo = getCodeBlockInfoInPos(state, selection.from); if (!codeBlockInfo) return false; const language = codeBlockInfo.language; const commentSymbol = getCommentSymbol(language.toLowerCase()); if (!commentSymbol) return false; let changes = []; if (selection.from === selection.to) { const line = state.doc.lineAt(selection.from); let change = toggleCodeBlockLineComment(line.from, line.to, state.doc.sliceString(line.from, line.to), commentSymbol, selection.from); if (change && change.selection) { changes.push(change); view.dispatch({ changes, selection: change.selection, userEvent: "EasyTyping.toggleComment" }); return true; } else if (change) { changes.push(change); } } else { const fromLine = state.doc.lineAt(selection.from); const toLine = state.doc.lineAt(selection.to); for (let i = fromLine.number; i <= toLine.number; i++) { const line = state.doc.line(i); let change = toggleCodeBlockLineComment(line.from, line.to, state.doc.sliceString(line.from, line.to), commentSymbol); if (change) { changes.push(change); } } } view.dispatch({ changes, userEvent: "EasyTyping.toggleComment" }); return true; } function toggleCodeBlockLineComment(from, to, text, commentSymbol, cursor_pos) { if (text.trim() == "" && cursor_pos) { if (typeof commentSymbol === "string") { let new_pos = cursor_pos + commentSymbol.length + 1; return { from: cursor_pos, to: cursor_pos, insert: commentSymbol + " ", selection: { anchor: new_pos, head: new_pos } }; } else { let new_pos = cursor_pos + commentSymbol.start.length + 1; return { from: cursor_pos, to: cursor_pos, insert: commentSymbol.start + " " + commentSymbol.end, selection: { anchor: new_pos, head: new_pos } }; } } if (text.trim() == "") return null; if (typeof commentSymbol === "string") { const trimmedText = text.trimStart(); if (trimmedText.startsWith(commentSymbol)) { const commentIndex = text.indexOf(commentSymbol); return { from: from + commentIndex, to: from + commentIndex + commentSymbol.length + (trimmedText.startsWith(commentSymbol + " ") ? 1 : 0), insert: "" }; } else { const indent = text.length - trimmedText.length; return { from: from + indent, to: from + indent, insert: commentSymbol + " " }; } } else { const trimmedText = text.trim(); if (trimmedText.startsWith(commentSymbol.start) && trimmedText.endsWith(commentSymbol.end)) { const commentStartIndex = text.indexOf(commentSymbol.start); return { from: from + commentStartIndex, to, insert: trimmedText.slice(commentSymbol.start.length + 1, -commentSymbol.end.length - 1) }; } else { const indent = text.length - text.trimStart().length; return { from: from + indent, to, insert: `${commentSymbol.start} ${trimmedText} ${commentSymbol.end}` }; } } } function toggleMarkdownComment(from, to, view) { const state = view.state; const doc = state.doc; const changes = []; if (from === to) { const currentText = doc.sliceString(from - 3, to + 3); if (currentText === "%% %%") { changes.push({ from: from - 3, to: to + 3, insert: "" }); view.dispatch({ changes, selection: { anchor: from - 3, head: from - 3 }, userEvent: "EasyTyping.toggleComment" }); return true; } changes.push({ from, to, insert: "%% %%" }); const newPos = from + 3; view.dispatch({ changes, selection: { anchor: newPos, head: newPos }, userEvent: "EasyTyping.toggleComment" }); } else { const selectedText = doc.sliceString(from, to); if (selectedText.startsWith("%%") && selectedText.endsWith("%%")) { changes.push({ from, to, insert: selectedText.slice(2, -2) }); } else { changes.push({ from, to, insert: `%%${selectedText}%%` }); } view.dispatch({ changes, userEvent: "EasyTyping.toggleComment" }); } return true; } function getCommentSymbol(language) { const commentSymbols = { "js": "//", "javascript": "//", "ts": "//", "typescript": "//", "py": "#", "python": "#", "rb": "#", "ruby": "#", "java": "//", "c": "//", "cpp": "//", "cs": "//", "go": "//", "rust": "//", "swift": "//", "kotlin": "//", "php": "//", "css": { start: "/*", end: "*/" }, "scss": { start: "/*", end: "*/" }, "sql": "--", "shell": "#", "bash": "#", "powershell": "#", "html": { start: "" }, "matlab": "%", "markdown": { start: "%%", end: "%%" } }; return commentSymbols[language] || null; } // src/formatting_commands.ts var import_obsidian6 = require("obsidian"); var import_language3 = require("@codemirror/language"); function isCurrentFileExclude(ctx) { if (ctx.CurActiveMarkdown == "") { let file = ctx.app.workspace.getActiveFile(); if (file != null && ctx.CurActiveMarkdown != file.path) { ctx.CurActiveMarkdown = file.path; } else { return true; } } let excludePaths = ctx.settings.ExcludeFiles.split("\n"); for (let epath of excludePaths) { if (epath.charAt(0) == "/") epath = epath.substring(1); if (ctx.CurActiveMarkdown == epath) return true; let len = epath.length; if (ctx.CurActiveMarkdown.substring(0, len) == epath && (ctx.CurActiveMarkdown.charAt(len) == "/" || ctx.CurActiveMarkdown.charAt(len) == "\\" || epath.charAt(len - 1) == "/" || epath.charAt(len - 1) == "\\")) { return true; } } return false; } function formatArticle(ctx, editor, view) { const editorView = editor.cm; const tree = (0, import_language3.ensureSyntaxTree)(editorView.state, editorView.state.doc.length); if (!tree) { new import_obsidian6.Notice("EasyTyping: Syntax tree is not ready yet, please wait a moment and try again later!", 5e3); return; } ctx.onFormatArticle = true; let lineCount = editor.lineCount(); let new_article = ""; let cs = editor.getCursor(); let ch = 0; for (let i = 0; i < lineCount; i++) { if (i != 0) new_article += "\n"; if (i != cs.line) { new_article += preFormatOneLine(ctx, editor, i + 1)[0]; } else { let newData = preFormatOneLine(ctx, editor, i + 1, cs.ch); new_article += newData[0]; ch = newData[1]; } } editor.setValue(new_article); editor.setCursor({ line: cs.line, ch }); ctx.onFormatArticle = false; new import_obsidian6.Notice("EasyTyping: Format Article Done!"); } function formatSelectionOrCurLine(ctx, editor, view) { if (!editor.somethingSelected() || editor.getSelection() === "") { let lineNumber = editor.getCursor().line; let newLineData = preFormatOneLine(ctx, editor, lineNumber + 1, editor.getCursor().ch); editor.replaceRange(newLineData[0], { line: lineNumber, ch: 0 }, { line: lineNumber, ch: editor.getLine(lineNumber).length }); editor.setSelection({ line: lineNumber, ch: newLineData[1] }); return; } let selection = editor.listSelections()[0]; let begin = selection.anchor.line; let end = selection.head.line; if (begin > end) { let temp = begin; begin = end; end = temp; } let new_lines = ""; for (let i = begin; i <= end; i++) { if (i != begin) new_lines += "\n"; new_lines += preFormatOneLine(ctx, editor, i + 1)[0]; } editor.replaceRange(new_lines, { line: begin, ch: 0 }, { line: end, ch: editor.getLine(end).length }); if (selection.anchor.line < selection.head.line) { editor.setSelection({ line: selection.anchor.line, ch: 0 }, { line: selection.head.line, ch: editor.getLine(selection.head.line).length }); } else { editor.setSelection({ line: selection.anchor.line, ch: editor.getLine(selection.anchor.line).length }, { line: selection.head.line, ch: 0 }); } } function preFormatOneLine(ctx, editor, lineNumber, ch = -1) { const editorView = editor.cm; let state = editorView.state; let line = state.doc.line(lineNumber); let newLine = line.text; let newCh = 0; let curCh = line.text.length; if (ch != -1) { curCh = ch; } const lineType = getPosLineType(state, line.from); if (lineType == "text" /* text */ || lineType == "table" /* table */) { let newLineData = ctx.Formater.formatLine(state, lineNumber, { ...ctx.settings, AutoCapital: false }, curCh, 0); newLine = newLineData[0]; newCh = newLineData[1]; } return [newLine, newCh]; } function deleteBlankLines(ctx, editor) { var _a; if ((_a = ctx.settings) == null ? void 0 : _a.debug) { console.log("config.strictLineBreaks", ctx.app.vault.getConfig("strictLineBreaks")); } let strictLineBreaks = ctx.app.vault.config.strictLineBreaks || false; const editorView = editor.cm; let state = editorView.state; let doc = state.doc; const RE_BLANK = /^\s*$/; const RE_LIST = /^\s*(?:[-*+]|\d+[.)]) /; const RE_QUOTE = /^\s*>/; const RE_BLOCKID = /\s\^[\w-]+\s*$/; const RE_HR = /^\s*(?:---+|\*\*\*+|___+)\s*$/; const getTrailingBlankType = (text) => { if (RE_LIST.test(text)) return "list"; if (RE_QUOTE.test(text)) return "quote"; if (RE_BLOCKID.test(text)) return "blockid"; return null; }; const needsTrailingBlank = (text) => getTrailingBlankType(text) !== null; let start_line = 1; let end_line = doc.lines; let line_num = doc.lines; const selected = editor.somethingSelected() && editor.getSelection() != ""; if (selected) { let selection = editor.listSelections()[0]; let begin = selection.anchor.line + 1; let end = selection.head.line + 1; if (begin > end) { let temp = begin; begin = end; end = temp; } start_line = begin; end_line = end; } let delete_index = []; let remain_next_blank = false; let remain_next_blank_type = null; let consecutiveBlanks = 0; if (start_line != 1) { const prevText = doc.line(start_line - 1).text; const prevType = getTrailingBlankType(prevText); if (prevType) { remain_next_blank = true; remain_next_blank_type = prevType; } } if (end_line != line_num && !RE_BLANK.test(doc.line(end_line + 1).text)) { end_line += 1; } for (let i = start_line; i <= end_line; i++) { let line = doc.line(i); let text = line.text; if (RE_BLANK.test(text)) { consecutiveBlanks++; if (remain_next_blank) { let nextNonBlankType = null; for (let j = i + 1; j <= end_line; j++) { const jText = doc.line(j).text; if (!RE_BLANK.test(jText)) { nextNonBlankType = getTrailingBlankType(jText); break; } } if (remain_next_blank_type && nextNonBlankType === remain_next_blank_type) { delete_index.push(i); } remain_next_blank = false; remain_next_blank_type = null; continue; } if (strictLineBreaks && consecutiveBlanks === 1) { continue; } delete_index.push(i); continue; } consecutiveBlanks = 0; if (RE_HR.test(text) && delete_index[delete_index.length - 1] == i - 1) { delete_index.pop(); } else if (needsTrailingBlank(text)) { remain_next_blank = true; remain_next_blank_type = getTrailingBlankType(text); } else { remain_next_blank = false; remain_next_blank_type = null; } } let newContent = ""; for (let i = 1; i < line_num; i++) { if (!delete_index.contains(i)) { newContent += doc.line(i).text + "\n"; } } if (!delete_index.contains(line_num)) { newContent += doc.line(line_num).text; } editor.setValue(newContent); } function switchAutoFormatting(ctx) { ctx.settings.AutoFormat = !ctx.settings.AutoFormat; let status = ctx.settings.AutoFormat ? "on" : "off"; new import_obsidian6.Notice("EasyTyping: Autoformat is " + status + "!"); } function convert2CodeBlock(ctx, editor) { var _a; if ((_a = ctx.settings) == null ? void 0 : _a.debug) console.log("----- EasyTyping: insert code block-----"); if (editor.somethingSelected && editor.getSelection() != "") { let selected = editor.getSelection(); let selectedRange = editor.listSelections()[0]; let anchor = selectedRange.anchor; let head = selectedRange.head; let replacement = "```\n" + selected + "\n```"; if (anchor.line > head.line || anchor.line == head.line && anchor.ch > head.ch) { let temp = anchor; anchor = head; head = temp; } let dstLine = anchor.line; if (anchor.ch != 0) { replacement = "\n" + replacement; dstLine += 1; } if (head.ch != editor.getLine(head.line).length) { replacement = replacement + "\n"; } editor.replaceSelection(replacement); editor.setCursor({ line: dstLine, ch: 3 }); } else { let cs = editor.getCursor(); let replace = "```\n```"; let dstLine = cs.line; if (cs.ch != 0) { replace = "\n" + replace; dstLine += 1; } if (cs.ch != editor.getLine(cs.line).length) { replace = replace + "\n"; } editor.replaceRange(replace, cs); editor.setCursor({ line: dstLine, ch: 3 }); } } // src/keyboard_handlers.ts var import_language4 = require("@codemirror/language"); var import_obsidian7 = require("obsidian"); // src/tabstop.ts var import_state4 = require("@codemirror/state"); var import_view3 = require("@codemirror/view"); var TABSTOP_DECO_CLASS = "easy-typing-tabstops"; var CURSOR_WIDGET_CLASS = "easy-typing-cursor-widget"; function getMarkerDecoration(from, to) { const className = `${TABSTOP_DECO_CLASS}`; if (from == to) { return import_view3.Decoration.widget({ widget: new CursorWidget(), side: 0 }).range(from); } return import_view3.Decoration.mark({ inclusive: true, class: className }).range(from, to); } var TabstopGroup = class { constructor(tabstopSpecs) { const decos = tabstopSpecs.map((spec) => getMarkerDecoration(spec.from, spec.to)); this.selections = tabstopSpecs.map((spec) => import_state4.EditorSelection.range(spec.from, spec.to)); this.decos = import_view3.Decoration.set(decos, true); } select(view, selectEndpoints) { const sel = this.toEditorSelection(); const toSelect = selectEndpoints ? getEditorSelectionEndpoints(sel) : sel; view.dispatch({ selection: toSelect }); } toSelectionRanges() { return this.selections; } toEditorSelection() { return import_state4.EditorSelection.create(this.toSelectionRanges()); } containsSelection(selection) { function rangeLiesWithinSelection(range, sel) { for (const selRange of sel) { if (selRange.from <= range.from && selRange.to >= range.to) { return true; } } return false; } const tabstopRanges = this.toSelectionRanges(); let result = true; for (const range of selection.ranges) { if (!rangeLiesWithinSelection(range, tabstopRanges)) { result = false; break; } } return result; } map(changes) { this.decos = this.decos.map(changes); this.selections = this.selections.map((range) => { let rangeFrom = changes.mapPos(range.from, -1); let rangeTo = changes.mapPos(range.to, 1); return import_state4.EditorSelection.range(rangeFrom, rangeTo); }); } getDecoRanges() { const ranges = []; const cur = this.decos.iter(); while (cur.value != null) { if (cur.from != cur.to) { ranges.push(cur.value.range(cur.from, cur.to)); } else { ranges.push(cur.value.range(cur.from)); } cur.next(); } return ranges; } }; function tabstopSpecsToTabstopGroups(tabstops) { const tabstopsByNumber = {}; for (const tabstop of tabstops) { const n = String(tabstop.number); if (tabstopsByNumber[n]) { tabstopsByNumber[n].push(tabstop); } else { tabstopsByNumber[n] = [tabstop]; } } const result = []; const numbers = Object.keys(tabstopsByNumber); numbers.sort((a, b) => parseInt(a) - parseInt(b)); for (const number of numbers) { const grp = new TabstopGroup(tabstopsByNumber[number]); result.push(grp); } return result; } function getEditorSelectionEndpoints(sel) { const endpoints = sel.ranges.map((range) => import_state4.EditorSelection.range(range.to, range.to)); return import_state4.EditorSelection.create(endpoints); } var CursorWidget = class extends import_view3.WidgetType { eq(widget) { return true; } toDOM(view) { const cursorEl = document.createElement("span"); cursorEl.className = `${CURSOR_WIDGET_CLASS}`; cursorEl.textContent = ""; return cursorEl; } }; // src/rule_processor.ts function triggerCvtRule(ctx, view, cursor_pos, changeType = "input.type") { var _a, _b, _c; const inputScope = detectRuleScope(view.state, cursor_pos); const cvtCtx = { kind: "input" /* Input */, docText: view.state.doc.toString(), selection: { from: cursor_pos, to: cursor_pos }, inserted: "", changeType, scopeHint: inputScope.scope, scopeLanguage: inputScope.language, debug: (_a = ctx.settings) == null ? void 0 : _a.debug }; if (((_b = ctx.settings) == null ? void 0 : _b.UserDefinedRegSwitch) && ((_c = ctx.settings) == null ? void 0 : _c.UserRulesRespectUserDefinedRegexBlocks)) { const line = view.state.doc.lineAt(cursor_pos); const column = cursor_pos - line.from; const checkColumn = changeType.startsWith("input") ? Math.max(0, column - 1) : column; if (isCursorInUserDefinedRegexBlock(line.text, checkColumn, ctx.settings.UserDefinedRegExp)) { return false; } } const cvtResult = ctx.ruleEngine.process(cvtCtx); if (cvtResult) { const tabstopGroups = tabstopSpecsToTabstopGroups(cvtResult.tabstops); if (tabstopGroups.length > 0) { view.dispatch({ changes: { from: cvtResult.matchRange.from, to: cvtResult.matchRange.to, insert: cvtResult.newText }, selection: tabstopGroups[0].toEditorSelection(), effects: [addTabstopsEffect.of(tabstopGroups)], userEvent: "EasyTyping.change" }); } else { view.dispatch({ changes: { from: cvtResult.matchRange.from, to: cvtResult.matchRange.to, insert: cvtResult.newText }, selection: { anchor: cvtResult.cursor }, userEvent: "EasyTyping.change" }); } return true; } return false; } // src/keyboard_handlers.ts function tabTabstopJump(view) { if (consumeAndGotoNextTabstop(view)) { return true; } return false; } function tabTriggerRule(ctx, view) { const sel = view.state.selection; if (sel.ranges.length === 1 && sel.main.from === sel.main.to) { if (triggerCvtRule(ctx, view, sel.main.to, "tab")) return true; } return false; } function tabCodeBlockIndent(ctx, view) { if (!ctx.settings.Tabout) return false; const state = view.state; const s = view.state.selection; if (s.ranges.length > 1) return false; const pos = s.main.to; if (s.main.from == s.main.to && isCodeBlockInPos(state, pos)) { const default_indent = ctx.getDefaultIndentChar(); view.dispatch({ changes: { from: s.main.from, insert: default_indent }, selection: { anchor: s.main.from + default_indent.length } }); return true; } return false; } function tabInlineCodeEscape(ctx, view) { if (!ctx.settings.Tabout) return false; if (!ctx.settings.BetterCodeEdit) return false; const state = view.state; const doc = state.doc; const tree = (0, import_language4.syntaxTree)(state); const s = view.state.selection; if (s.ranges.length > 1) return false; const pos = s.main.to; const line = doc.lineAt(pos); if (pos - line.from != 0 && tree.resolve(pos - 1, 1).name.contains("inline-code")) { if (tree.resolve(pos, 1).name.contains("formatting-code_inline-code")) { view.dispatch({ selection: { anchor: pos + 1, head: pos + 1 } }); return true; } for (let p = pos + 1; p < line.to && tree.resolve(p, 1).name.contains("inline-code"); p += 1) { if (tree.resolve(p, 1).name.contains("formatting-code_inline-code")) { view.dispatch({ selection: { anchor: p, head: p } }); return true; } if (p == line.to - 1 && tree.resolve(p, 1).name.contains("inline-code")) { view.dispatch({ selection: { anchor: p + 1, head: p + 1 } }); return true; } } } return false; } function tabPairStringTabout(ctx, view) { if (!ctx.settings.Tabout) return false; const state = view.state; const doc = state.doc; const s = view.state.selection; if (s.ranges.length > 1) return false; const pos = s.main.to; const line = doc.lineAt(pos); let selection = view.state.selection.asSingle().main; let selected = selection.anchor != selection.head; if (selected) { let new_anchor = selection.anchor < selection.head ? selection.anchor : selection.head; let new_head = selection.anchor > selection.head ? selection.anchor : selection.head; for (let pstr of ctx.TaboutPairStrs) { if (doc.sliceString(new_anchor - pstr.left.length, new_anchor) == pstr.left && doc.sliceString(new_head, new_head + pstr.right.length) == pstr.right) { view.dispatch({ selection: { anchor: new_head + pstr.right.length, head: new_head + pstr.right.length } }); return true; } } } else { let taboutRes = taboutCursorInPairedString(line.text, pos - line.from, ctx.TaboutPairStrs); if (taboutRes.isSuccess) { view.dispatch({ selection: { anchor: taboutRes.newPosition + line.from } }); return true; } } return false; } function handleTabDown(ctx, view) { return tabTabstopJump(view) || tabTriggerRule(ctx, view) || tabCodeBlockIndent(ctx, view) || tabInlineCodeEscape(ctx, view) || tabPairStringTabout(ctx, view); } function enterCollapsedHeading(ctx, view) { var _a; if (!ctx.settings.CollapsePersistentEnter) return false; const state = view.state; const doc = state.doc; const s = view.state.selection; const pos = s.main.to; const editor = ctx.app.workspace.getActiveViewOfType(import_obsidian7.MarkdownView).editor; let fold_offsets = editor.getFoldOffsets(); let all_foldable_lines = editor.getAllFoldableLines(); let folded_lines = []; for (let offset of fold_offsets) { let folded = all_foldable_lines.find((l) => l.from == offset); if (folded) { folded_lines.push(folded); } } let folded_line = folded_lines.find((l) => pos >= l.from && pos <= l.to); if (folded_line) { let folded_first_line = doc.lineAt(folded_line.from).text; let reg_headings = /^#+ /; if (reg_headings.test(folded_first_line)) { let heading_level = (_a = folded_first_line.match(/^#+/)) == null ? void 0 : _a[0].length; let new_heading_level = heading_level; let new_heading_line = "\n" + "#".repeat(new_heading_level) + " "; let folded_last_line = doc.lineAt(folded_line.to).text; let folded_last_line_is_blank = /^\s*$/.test(folded_last_line); let new_heading_line_pos = editor.offsetToPos(folded_line.to); let new_cursor_pos = { line: new_heading_line_pos.line + 1, ch: new_heading_level + 1 }; if (ctx.settings.StrictModeEnter && !folded_last_line_is_blank && (ctx.app.vault.config.strictLineBreaks || false)) { new_heading_line = "\n\n" + "#".repeat(new_heading_level) + " "; new_cursor_pos = { line: new_heading_line_pos.line + 2, ch: new_heading_level + 1 }; } editor.replaceRange(new_heading_line, new_heading_line_pos); editor.setCursor(editor.offsetToPos(folded_line.from)); editor.exec("toggleFold"); editor.setCursor(new_cursor_pos); return true; } } return false; } function enterCodeBlockIndent(ctx, view) { var _a; if (!ctx.settings.BetterCodeEdit) return false; const state = view.state; const doc = state.doc; const s = view.state.selection; const pos = s.main.to; const line = doc.lineAt(pos); const codeBlockInfo = getCodeBlockInfoInPos(state, pos); if (codeBlockInfo && codeBlockInfo.code_start_pos !== doc.lineAt(codeBlockInfo.start_pos).to && pos >= codeBlockInfo.code_start_pos && pos <= codeBlockInfo.code_end_pos) { let line_indent_str = ((_a = line.text.match(/^\s*/)) == null ? void 0 : _a[0]) || ""; view.dispatch({ changes: { from: pos, to: pos, insert: "\n" + line_indent_str }, selection: { anchor: pos + line_indent_str.length + 1, head: pos + line_indent_str.length + 1 }, userEvent: "EasyTyping.handleEnter" }); return true; } return false; } function enterStrictLineBreak(ctx, view) { if (!ctx.settings.StrictModeEnter) return false; let strictLineBreaks = ctx.app.vault.config.strictLineBreaks || false; if (!strictLineBreaks) return false; const state = view.state; const doc = state.doc; const s = view.state.selection; const pos = s.main.to; const line = doc.lineAt(pos); const codeBlockInfo = getCodeBlockInfoInPos(state, pos); const lineType = getPosLineType2(state, pos); if (/^\s*$/.test(line.text)) return false; if (pos == line.from) return false; if (lineType == "quote" /* quote */) { let reg_quote = /^(\s*)(>+ ?)/; let quote_match = line.text.match(reg_quote); if (!quote_match) return false; let quote_content = line.text.slice(quote_match[0].length); if (quote_content.trim() == "") return false; else { let space_str2 = " "; if (quote_content.endsWith(" ")) space_str2 = ""; let inserted_str = space_str2 + "\n" + quote_match[0]; if (ctx.settings.StrictLineMode == "enter_twice" /* EnterTwice */) { inserted_str = "\n" + quote_match[0] + "\n" + quote_match[0]; } view.dispatch({ changes: { from: pos, to: pos, insert: inserted_str }, selection: { anchor: pos + inserted_str.length }, userEvent: "EasyTyping.handleEnter" }); return true; } } let space_str = " "; if (line.text.endsWith(" ")) space_str = ""; if (line.number < doc.lines && !/^\s*$/.test(doc.line(line.number + 1).text)) { if (ctx.settings.StrictLineMode != "two_space" /* TwoSpace */) return false; } if (ctx.settings.StrictLineMode == "two_space" /* TwoSpace */ && lineType == "text" /* text */) { let inserted_str = space_str + "\n"; view.dispatch({ changes: { from: pos, to: pos, insert: inserted_str }, selection: { anchor: pos + inserted_str.length, head: pos + inserted_str.length }, userEvent: "EasyTyping.handleEnter" }); return true; } if (lineType == "text" /* text */ || codeBlockInfo && pos == codeBlockInfo.end_pos && codeBlockInfo.indent == 0) { view.dispatch({ changes: { from: pos, to: pos, insert: "\n\n" }, selection: { anchor: pos + 2 }, userEvent: "EasyTyping.handleEnter" }); return true; } return false; } function handleEnter(ctx, view) { const s = view.state.selection; if (s.ranges.length > 1) return false; return enterCollapsedHeading(ctx, view) || enterCodeBlockIndent(ctx, view) || enterStrictLineBreak(ctx, view); } function backspaceEmptyQuote(view, state, doc, line, lineContent, quoteMatchEmpty) { let changes = []; let newCursorPos; const quote_indent_str = quoteMatchEmpty[1]; const quoteLevel = quoteMatchEmpty[2].length; if (quoteLevel > 1) { if (line.number > 1) { const prevLine = doc.line(line.number - 1); const prevLineContent = prevLine.text; const prevQuoteMatchEmpty = prevLineContent.match(/^(\s*)(>+) ?$/); if (prevQuoteMatchEmpty && prevQuoteMatchEmpty[1] == quote_indent_str && prevQuoteMatchEmpty[2].length == quoteLevel) { let temp_line = quote_indent_str + ">".repeat(quoteLevel - 1) + " "; let inseted = temp_line + "\n" + temp_line; changes = [{ from: prevLine.from, to: line.to, insert: inseted }]; newCursorPos = prevLine.from + inseted.length; } else { const newQuotePrefix = ">".repeat(quoteLevel - 1) + " "; changes = [{ from: line.from, to: line.to, insert: newQuotePrefix }]; newCursorPos = line.from + newQuotePrefix.length; } } else { const newQuotePrefix = ">".repeat(quoteLevel - 1) + " "; changes = [{ from: line.from, to: line.to, insert: newQuotePrefix }]; newCursorPos = line.from + newQuotePrefix.length; } } else { if (line.number > 1) { const prevLine = doc.line(line.number - 1); const prevLineContent = prevLine.text; const prevQuoteMatch = prevLineContent.match(/^\s*(>+)/); if (prevQuoteMatch) { changes = [{ from: prevLine.to, to: line.to, insert: "" }]; newCursorPos = prevLine.to; } else { changes = [{ from: line.from, to: line.to, insert: "" }]; newCursorPos = line.from; } } else { changes = [{ from: line.from, to: line.to, insert: "" }]; newCursorPos = line.from; } } return { changes, newCursorPos }; } function backspaceEmptyListItem(view, state, doc, line, lineContent) { let changes = []; let newCursorPos; if (line.number > 1) { const prevLine = doc.line(line.number - 1); const prevLineContent = prevLine.text; const prevListMatch = prevLineContent.match(/^\s*([-*+]|\d+\.)\s/); if (prevListMatch) { changes = [{ from: prevLine.to, to: line.to, insert: "" }]; newCursorPos = prevLine.to; } else { changes = [{ from: line.from, to: line.to, insert: "" }]; newCursorPos = line.from; } } else { changes = [{ from: line.from, to: line.to, insert: "" }]; newCursorPos = line.from; } let nextLineNumber = line.number + 1; const currentIndent = lineContent.match(/^\s*/)[0]; const currentListMatch = lineContent.match(/^\s*(\d+)\.\s/); let expectedNextNumber = currentListMatch ? parseInt(currentListMatch[1], 10) + 1 : null; while (nextLineNumber <= doc.lines && expectedNextNumber !== null) { const nextLine = doc.line(nextLineNumber); const nextLineContent = nextLine.text; const nextListMatch = nextLineContent.match(/^\s*(\d+)\.\s/); if (nextListMatch) { const nextIndent = nextLineContent.match(/^\s*/)[0]; if (nextIndent !== currentIndent) { break; } const nextListNumber = parseInt(nextListMatch[1], 10); if (nextListNumber === expectedNextNumber) { const newNextLineContent = nextLineContent.replace(/^\s*\d+\.\s/, `${nextIndent}${nextListNumber - 1}. `); changes.push({ from: nextLine.from, to: nextLine.to, insert: newNextLineContent }); expectedNextNumber++; } else { break; } } else { break; } nextLineNumber++; } return { changes, newCursorPos }; } function handleBackspace(view) { const state = view.state; const doc = state.doc; const selection = state.selection.main; if (selection.anchor != selection.head) return false; const line = doc.lineAt(selection.from); const lineContent = line.text; const listMatchEmpty = lineContent.match(/^\s*([-*+]|\d+\.) $/); const quoteMatchEmpty = lineContent.match(/^(\s*)(>+) ?$/); if ((listMatchEmpty || quoteMatchEmpty) && selection.anchor == line.to) { let result; if (quoteMatchEmpty) { result = backspaceEmptyQuote(view, state, doc, line, lineContent, quoteMatchEmpty); } else { result = backspaceEmptyListItem(view, state, doc, line, lineContent); } const tr = state.update({ changes: result.changes, selection: { anchor: result.newCursorPos, head: result.newCursorPos }, userEvent: "EasyTyping.handleBackspace" }); view.dispatch(tr); return true; } return false; } function handleShiftEnter(ctx, view) { const state = view.state; const doc = state.doc; const selection = state.selection.main; if (selection.anchor != selection.head) return false; const line = doc.lineAt(selection.head); const lineContent = line.text; const taskListMatch = lineContent.match(/^(\s*)([-*+] \[.\])\s/); if (taskListMatch) { const [, indent, listMarker] = taskListMatch; let inserted = "\n" + indent + " "; view.dispatch({ changes: [{ from: selection.anchor, insert: inserted }], selection: { anchor: selection.anchor + inserted.length, head: selection.anchor + inserted.length }, userEvent: "EasyTyping.handleShiftEnter" }); return true; } return false; } function handleModA(ctx, view) { var _a; let selection = view.state.selection.main; let line = view.state.doc.lineAt(selection.anchor); let line_type = getPosLineType2(view.state, selection.anchor); let is_in_code_block = isCodeBlockInPos(view.state, selection.anchor); if (ctx.settings.EnhanceModA && line_type == "text" /* text */ && !is_in_code_block) { let [block_start, block_end] = getBlockLinesInPos(ctx, view.state, selection.head); if (selection.anchor <= view.state.doc.line(block_start).from && selection.head >= view.state.doc.line(block_end).to) { return false; } if (selection.anchor == line.from && selection.head == line.to) { if (block_start != block_end) { view.dispatch({ selection: { anchor: view.state.doc.line(block_start).from, head: view.state.doc.line(block_end).to }, userEvent: "EasyTyping.handleModA" }); return true; } return false; } view.dispatch({ selection: { anchor: line.from, head: line.to }, userEvent: "EasyTyping.handleModA" }); return true; } let quote_info = getQuoteInfoInPos(view.state, selection.head); if (ctx.settings.EnhanceModA && quote_info) { if (selection.anchor == quote_info.start_pos && selection.head == quote_info.end_pos) { return false; } else if (selection.anchor == quote_info.cur_start_pos && selection.head == quote_info.cur_end_pos) { view.dispatch({ selection: { anchor: quote_info.start_pos, head: quote_info.end_pos }, userEvent: "EasyTyping.handleModA" }); return true; } else { view.dispatch({ selection: { anchor: quote_info.cur_start_pos, head: quote_info.cur_end_pos }, userEvent: "EasyTyping.handleModA" }); return true; } } if (ctx.settings.EnhanceModA && line_type == "list" /* list */) { const reg_list = /^(\s*)([-*+] \[[^\]]\]|[-*+]|\d+\.)\s/; let reg_code_block = /^\s+```/; const listMatch = line.text.match(reg_list); if (!listMatch) { if (!reg_code_block.test(line.text)) { let cur_indent = ((_a = line.text.match(/^\s*/)) == null ? void 0 : _a[0].length) || 0; let selection_list = []; selection_list.push({ anchor: line.from + cur_indent, head: line.to }); let list_start_line = line.number; for (let i = line.number - 1; i >= 1; i--) { const prevLine = view.state.doc.line(i); if (getPosLineType2(view.state, prevLine.from) == "list" /* list */) { list_start_line = i; break; } } let list_s_match = view.state.doc.line(list_start_line).text.match(reg_list); let list_s_start_idx = (list_s_match == null ? void 0 : list_s_match[0].length) || 0; selection_list.push({ anchor: view.state.doc.line(list_start_line).from + list_s_start_idx, head: line.to }); if (selection.anchor <= selection_list[0].anchor && selection.head >= selection_list[0].head) { view.dispatch({ selection: selection_list[1], userEvent: "EasyTyping.handleModA" }); return true; } else { view.dispatch({ selection: selection_list[0], userEvent: "EasyTyping.handleModA" }); return true; } } } else { const cur_indent = listMatch[1].length; let selection_list = []; const contentStart = line.from + listMatch[0].length; selection_list.push({ anchor: contentStart, head: line.to }); let endLine = line.number; for (let i = line.number + 1; i <= view.state.doc.lines; i++) { const nextLine = view.state.doc.line(i); const nextMatch = nextLine.text.match(/^(\s*)/); if (!nextMatch || nextMatch[0].length <= cur_indent) break; endLine = i; } let list_block_selection = { anchor: line.from, head: view.state.doc.line(endLine).to }; selection_list.push(list_block_selection); let list_start_line = line.number; for (let i = line.number - 1; i >= 1; i--) { const prevLine = view.state.doc.line(i); const prevMatch = prevLine.text.match(/^(\s*)/); if (getPosLineType2(view.state, prevLine.from) == "list" /* list */ || prevMatch && prevMatch[0].length >= 2) { list_start_line = i; } else { break; } } let list_end_line = line.number; for (let i = line.number + 1; i <= view.state.doc.lines; i++) { const nextLine = view.state.doc.line(i); const nextMatch = nextLine.text.match(/^(\s*)/); if (getPosLineType2(view.state, nextLine.from) == "list" /* list */ || nextMatch && nextMatch[0].length >= 2) { list_end_line = i; } else { break; } } let list_all_selection = { anchor: view.state.doc.line(list_start_line).from, head: view.state.doc.line(list_end_line).to }; if (list_all_selection.anchor != list_block_selection.anchor || list_all_selection.head != list_block_selection.head) { selection_list.push(list_all_selection); } selection_list.push({ anchor: 0, head: view.state.doc.length }); let hit_idx = -1; for (let i = selection_list.length - 1; i >= 0; i--) { const sel = selection_list[i]; if (selection.anchor <= sel.anchor && selection.head >= sel.head) { hit_idx = i; break; } } hit_idx += 1; if (hit_idx < selection_list.length) { view.dispatch({ selection: selection_list[hit_idx], userEvent: "EasyTyping.handleModA" }); return true; } return false; } } if (!ctx.settings.BetterCodeEdit) return false; let mainSelection = view.state.selection.asSingle().main; return selectCodeBlockInPos(view, mainSelection); } function goNewLineAfterCurLine(ctx, view) { const state = view.state; const doc = state.doc; const selection = state.selection.main; const line = doc.lineAt(selection.head); const lineContent = line.text; if (/^\s*$/.test(lineContent)) { const insertStr2 = "\n"; view.dispatch({ changes: { from: line.to, insert: insertStr2 }, selection: { anchor: line.to + insertStr2.length }, userEvent: "EasyTyping.goNewLineAfterCurLine" }); return true; } const listMatch = lineContent.match(/^(\s*)([-*+] \[.\]|[-*+]|\d+\.)\s/); const quoteMatch = lineContent.match(/^(\s*)(>+ ?)/); let changes; let newCursorPos; let prefix = ""; if (listMatch) { const [, indent, listMarker] = listMatch; if (["-", "*", "+"].includes(listMarker)) { prefix = indent + listMarker + " "; } else if (listMarker.match(/[-*+] \[.\]/)) { prefix = indent + listMarker.replace(/\[.\]/g, "[ ]") + " "; } else { prefix = indent + (parseInt(listMarker) + 1) + ". "; } } else if (quoteMatch) { prefix = quoteMatch[1] + quoteMatch[2]; } const strictLineBreaks = ctx.app.vault.config.strictLineBreaks || false; let useStrictBreak = ctx.settings.StrictModeEnter && strictLineBreaks; if (useStrictBreak) { const lineType = getPosLineType2(state, line.from); if (lineType === "codeblock" /* codeblock */ || lineType === "formula" /* formula */ || lineType === "code_block_start" /* code_start */ || lineType === "code_block_end" /* code_end */) { useStrictBreak = false; } } let insertStr; if (!useStrictBreak) { insertStr = "\n" + prefix; } else { const mode = ctx.settings.StrictLineMode; const spaceStr = lineContent.endsWith(" ") ? "" : " "; if (listMatch) { insertStr = "\n" + prefix; } else if (mode === "two_space" /* TwoSpace */) { insertStr = spaceStr + "\n" + prefix; } else if (quoteMatch) { if (mode === "enter_twice" /* EnterTwice */) { insertStr = "\n" + prefix + "\n" + prefix; } else { insertStr = spaceStr + "\n" + prefix; } } else { insertStr = "\n\n" + prefix; } } changes = [{ from: line.to, insert: insertStr }]; newCursorPos = line.to + insertStr.length; const tr = state.update({ changes, selection: { anchor: newCursorPos, head: newCursorPos }, userEvent: "EasyTyping.goNewLineAfterCurLine" }); view.dispatch(tr); return true; } function getBlockLinesInPos(ctx, state, pos) { const strictLineBreaks = ctx.app.vault.config.strictLineBreaks || false; let line = state.doc.lineAt(pos); let block_start = line.number; let block_end = line.number; let reg_headings = /^#+ /; for (let i = line.number - 1; i >= 1; i--) { let line2 = state.doc.line(i); if (getPosLineType2(state, line2.from) == "text" /* text */ && line2.text !== "" && !reg_headings.test(line2.text)) { block_start = i; continue; } break; } for (let i = line.number + 1; i <= state.doc.lines; i++) { let line2 = state.doc.line(i); if (getPosLineType2(state, line2.from) == "text" /* text */ && line2.text !== "" && !reg_headings.test(line2.text)) { block_end = i; continue; } break; } return [block_start, block_end]; } function selectBlockInCursor(ctx, view) { let selection = view.state.selection.main; let line = view.state.doc.lineAt(selection.head); if (/^\s*$/.test(line.text)) return false; let [block_start, block_end] = getBlockLinesInPos(ctx, view.state, selection.head); view.dispatch({ selection: { anchor: view.state.doc.line(block_start).from, head: view.state.doc.line(block_end).to }, userEvent: "EasyTyping.selectBlockInCursor" }); return true; } // src/cm_extensions.ts var import_state5 = require("@codemirror/state"); var import_obsidian8 = require("obsidian"); var import_view4 = require("@codemirror/view"); function createTransactionFilter(ctx) { return import_state5.EditorState.transactionFilter.of((tr) => { const changes = []; if (!tr.docChanged) return tr; let selected = tr.startState.selection.asSingle().main.anchor != tr.startState.selection.asSingle().main.head; let changeTypeStr = getTypeStrOfTransac(tr); tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => { var _a, _b, _c, _d; let changedStr = tr.startState.sliceDoc(fromA, toA); let changestr_ = changedStr.replace(/\s/g, "0"); let insertedStr = inserted.sliceString(0); if ((_a = ctx.settings) == null ? void 0 : _a.debug) { console.log("[TransactionFilter] type, fromA, toA, changed, fromB, toB, inserted"); console.log(changeTypeStr, fromA, toA, changedStr, fromB, toB, insertedStr); } if (getPosLineType(tr.startState, fromA) == "table" /* table */) return tr; if ((changeTypeStr == "input.type" || changeTypeStr == "input.type.compose") && fromA != toA && (fromB + 1 === toB || insertedStr == "\u2014\u2014" || insertedStr == "\u2026\u2026")) { const selScope = detectRuleScope(tr.startState, fromA); const selCtx = { kind: "selectKey" /* SelectKey */, docText: tr.startState.doc.toString(), selection: { from: fromA, to: toA }, inserted: insertedStr, changeType: changeTypeStr, scopeHint: selScope.scope, scopeLanguage: selScope.language, key: insertedStr, debug: (_b = ctx.settings) == null ? void 0 : _b.debug }; const selResult = ctx.ruleEngine.process(selCtx); if (selResult) { const tabstopGroups = tabstopSpecsToTabstopGroups(selResult.tabstops); if (tabstopGroups.length > 0) { changes.push({ changes: { from: selResult.matchRange.from, to: selResult.matchRange.to, insert: selResult.newText }, selection: tabstopGroups[0].toEditorSelection(), effects: [addTabstopsEffect.of(tabstopGroups)], userEvent: "EasyTyping.change" }); } else { changes.push({ changes: { from: selResult.matchRange.from, to: selResult.matchRange.to, insert: selResult.newText }, selection: { anchor: selResult.cursor }, userEvent: "EasyTyping.change" }); } tr = tr.startState.update(...changes); return tr; } } if (ctx.settings.BetterCodeEdit && changeTypeStr.contains("paste") && fromA == fromB && isCodeBlockInPos(tr.startState, fromA)) { print("\u68C0\u6D4B\u5230\u5728\u4EE3\u7801\u5757\u4E2D\u7C98\u8D34"); let line = tr.startState.doc.lineAt(fromB).text; let base_indent_num = (_c = getCodeBlockInfoInPos(tr.startState, fromA)) == null ? void 0 : _c.indent; let base_indent = base_indent_num == 0 ? "" : " ".repeat(base_indent_num); let inserted_lines = insertedStr.split("\n"); if (inserted_lines.length > 1) { let min_indent_space = Infinity; for (let line2 of inserted_lines) { if (!/^\s*$/.test(line2)) { let indent = line2.match(/^\s*/)[0].length; min_indent_space = Math.min(min_indent_space, indent); } } let adjusted_lines = inserted_lines.map((line2, index) => { let trimmed_line = line2.substring(min_indent_space); trimmed_line = trimmed_line.replace(/[\t]/g, ctx.getDefaultIndentChar()); if (index === 0) { return trimmed_line; } else { return base_indent + trimmed_line; } }); let new_insertedStr = adjusted_lines.join("\n"); changes.push({ changes: { from: fromA, to: toA, insert: new_insertedStr }, selection: { anchor: fromA + new_insertedStr.length }, userEvent: "EasyTyping.change" }); tr = tr.startState.update(...changes); return tr; } } if (ctx.settings.SmartPaste && changeTypeStr.contains("paste") && fromA == fromB && fromA == tr.startState.doc.lineAt(toA).to) { const lineContent = tr.startState.doc.lineAt(toA).text; const listMatch = lineContent.match(/^(\s*)([-*+] \[.\]|[-*+]|\d+\.)\s/); const quoteMatch = lineContent.match(/^(\s*)(>+)(\s)?/); if (listMatch || quoteMatch) { let prefix = listMatch ? listMatch[1] + listMatch[2] + " " : quoteMatch[1] + quoteMatch[2] + " "; let indent_num = listMatch ? listMatch[1].length : quoteMatch[1].length; let indent_str = indent_num == 0 ? "" : " ".repeat(indent_num); let inserted_lines = insertedStr.split("\n"); let min_indent_space = Infinity; for (let line of inserted_lines) { if (!/^\s*$/.test(line)) { let indent = line.match(/^\s*/)[0].length; min_indent_space = Math.min(min_indent_space, indent); } } let paste_list = true; for (let line of inserted_lines) { if (line.match(/^(\s*)([-*+] \[.\]|[-*+]|\d+\.)\s/) || /^\s*$/.test(line)) { continue; } else { let indent = line.match(/^\s*/)[0].length; if (indent < min_indent_space + 2) { paste_list = false; break; } } } let adjusted_lines = []; if (paste_list && listMatch) { adjusted_lines = inserted_lines.map((line, index) => { let trimmed_line = line.substring(min_indent_space); trimmed_line = trimmed_line.replace(/[\t]/g, ctx.getDefaultIndentChar()); if (index === 0) { trimmed_line = trimmed_line.replace(/^([-*+] \[.\]|[-*+]|\d+\.)\s/, ""); return trimmed_line; } else { return indent_str + trimmed_line; } }); } else { adjusted_lines = inserted_lines.map((line, index) => { let trimmed_line = line.substring(min_indent_space); trimmed_line = trimmed_line.replace(/[\t]/g, ctx.getDefaultIndentChar()); if (index === 0) { return trimmed_line; } else { return prefix + trimmed_line; } }); } let new_insertedStr = adjusted_lines.join("\n"); changes.push({ changes: { from: fromA, to: toA, insert: new_insertedStr }, selection: { anchor: fromA + new_insertedStr.length }, userEvent: "EasyTyping.change" }); tr = tr.startState.update(...changes); return tr; } } if (selected) return tr; if (ctx.settings.TryFixMSIME && changeTypeStr == "input.type.compose" && changedStr == "" && /^[\u4e00-\u9fa5]+$/.test(insertedStr)) { print("MS-IME Compose detected:", insertedStr); tr = tr.startState.update(...changes); return tr; } let codeblockinfo = getCodeBlockInfoInPos(tr.startState, toA); if (ctx.settings.BetterCodeEdit && changeTypeStr == "delete.backward" && !selected && codeblockinfo && toA > tr.startState.doc.lineAt(codeblockinfo.start_pos).to) { let line_number = tr.startState.doc.lineAt(toA).number; let cur_line = tr.startState.doc.lineAt(toA); let list_code_indent = codeblockinfo.indent; if (list_code_indent !== 0) { print("list_code, indent: ", list_code_indent); if (toA == cur_line.from + list_code_indent) { changes.push({ changes: { from: tr.startState.doc.line(line_number - 1).to, to: toA, insert: "" }, userEvent: "EasyTyping.change" }); tr = tr.startState.update(...changes); return tr; } if (fromA >= cur_line.from && fromA < cur_line.from + list_code_indent && toA > cur_line.from + list_code_indent) { changes.push({ changes: { from: cur_line.from + list_code_indent, to: toA, insert: "" }, userEvent: "EasyTyping.change" }); tr = tr.startState.update(...changes); return tr; } } } if (changeTypeStr === "delete.backward") { const delScope = detectRuleScope(tr.startState, toA); const delCtx = { kind: "delete" /* Delete */, docText: tr.startState.doc.toString(), selection: { from: toA, to: toA }, inserted: "", changeType: changeTypeStr, scopeHint: delScope.scope, scopeLanguage: delScope.language, debug: (_d = ctx.settings) == null ? void 0 : _d.debug }; const delResult = ctx.ruleEngine.process(delCtx); if (delResult) { const tabstopGroups = tabstopSpecsToTabstopGroups(delResult.tabstops); if (tabstopGroups.length > 0) { changes.push({ changes: { from: delResult.matchRange.from, to: delResult.matchRange.to, insert: delResult.newText }, selection: tabstopGroups[0].toEditorSelection(), effects: [addTabstopsEffect.of(tabstopGroups)], userEvent: "EasyTyping.change" }); } else { changes.push({ changes: { from: delResult.matchRange.from, to: delResult.matchRange.to, insert: delResult.newText }, selection: { anchor: delResult.cursor }, userEvent: "EasyTyping.change" }); } tr = tr.startState.update(...changes); return tr; } } }); return tr; }); } function tryProcessInput(ctx, update, changeFrom, cursorPos, changeType = "input.type") { const lineType = getPosLineType(update.view.state, cursorPos); if (lineType === "table" /* table */) return false; if (!changeType.includes("paste") && changeType !== "unknown" && !ctx.pasteDetected && triggerCvtRule(ctx, update.view, cursorPos, changeType)) return true; if (!ctx.settings.AutoFormat || isCurrentFileExclude(ctx)) return false; if (lineType !== "text" /* text */) return false; if (changeType.includes("paste") || changeType === "unknown" || ctx.pasteDetected) return false; const insertedStr = update.view.state.doc.sliceString(changeFrom, cursorPos); const changes = ctx.Formater.formatLineOfDoc(update.state, ctx.settings, changeFrom, cursorPos, insertedStr); if (changes) { const allSpecs = changes[0]; if (allSpecs.length > 0) { allSpecs[allSpecs.length - 1] = { ...allSpecs[allSpecs.length - 1], ...changes[1] }; } update.view.dispatch(...allSpecs); return true; } return false; } function createViewUpdatePlugin(ctx) { return import_view4.EditorView.updateListener.of((update) => { var _a; if (ctx.onFormatArticle) return; if (hasTabstops(update.view)) { const cursor_changed = update.transactions.some((tr2) => tr2.selection); if ((update.docChanged || cursor_changed) && !update.view.composing && !isInsideCurTabstop(update.view)) { removeAllTabstops(update.view); } if (update.transactions.some((tr2) => tr2.isUserEvent("undo"))) { removeAllTabstops(update.view); } } const inTable = getPosLineType(update.view.state, update.view.state.selection.asSingle().main.anchor) === "table" /* table */; if (inTable) return; if (update.view.composing) { if (update.docChanged) { let tr2 = update.transactions[0]; tr2.changes.iterChanges((fromA2) => { if (!ctx.compose_need_handle) { ctx.compose_need_handle = true; ctx.compose_begin_pos = fromA2; } ctx.compose_end_pos = update.view.state.selection.asSingle().main.anchor; }); } return; } if (ctx.compose_need_handle) { ctx.compose_need_handle = false; const cursor2 = update.view.state.selection.asSingle().main; if (cursor2.head === cursor2.anchor && cursor2.anchor > ctx.compose_begin_pos) { if (tryProcessInput(ctx, update, ctx.compose_begin_pos, cursor2.anchor)) return; } } if (!update.docChanged) return; const tr = update.transactions[0]; const changeType = getTypeStrOfTransac(tr); let fromA = 0, toA = 0, fromB = 0, toB = 0, insertedStr = "", changedStr = ""; tr.changes.iterChanges((_fromA, _toA, _fromB, _toB, inserted) => { fromA = _fromA; toA = _toA; fromB = _fromB; toB = _toB; insertedStr = inserted.sliceString(0); changedStr = tr.startState.doc.sliceString(_fromA, _toA); }); if ((_a = ctx.settings) == null ? void 0 : _a.debug) { console.log("[ViewUpdate] type, fromA, toA, changed, fromB, toB, inserted"); console.log(changeType, fromA, toA, changedStr, fromB, toB, insertedStr); } if (getPosLineType(update.view.state, fromB) === "table" /* table */) return; if (changeType.includes("EasyTyping") || changeType === "undo" || changeType === "redo") return; const cursor = update.view.state.selection.asSingle().main; const notSelected = cursor.anchor === cursor.head; if (notSelected && changedStr.length < 1 && !changeType.includes("delete")) { if (tryProcessInput(ctx, update, fromB, cursor.anchor, changeType)) return; } const isPaste = changeType.contains("paste") || ctx.pasteDetected; const isFormattedPaste = isPaste && !ctx.plainPasteInProgress; const isPlainPaste = isPaste && ctx.plainPasteInProgress; if (isPlainPaste) ctx.plainPasteInProgress = false; const isExcludeFile = isCurrentFileExclude(ctx); if (ctx.settings.AutoFormat && ctx.settings.AutoFormatPaste && !isExcludeFile && isFormattedPaste && !import_obsidian8.Platform.isIosApp) { let updateLineStart = update.state.doc.lineAt(fromB).number; let updateLineEnd = update.state.doc.lineAt(toB).number; if (updateLineStart === updateLineEnd && getPosLineType(update.view.state, toB) === "text" /* text */) { let changes = ctx.Formater.formatLineOfDoc(update.state, { ...ctx.settings, AutoCapital: false }, fromB, toB, insertedStr); if (changes) { update.view.dispatch(...changes[0]); return; } } else { let all_changes = []; let inserted_array = insertedStr.split("\n"); let update_start = fromB; for (let i = updateLineStart; i <= updateLineEnd; i++) { let real_inserted = inserted_array[i - updateLineStart]; let changes = ctx.Formater.formatLineOfDoc(update.state, { ...ctx.settings, AutoCapital: false }, update_start, update_start + real_inserted.length, real_inserted); if (changes) { all_changes.push(...changes[0]); } update_start += real_inserted.length + 1; } if (all_changes.length > 0) { update.view.dispatch(...all_changes); return; } } } }); } // src/main.ts var EasyTypingPlugin = class extends import_obsidian9.Plugin { constructor() { super(...arguments); this.pasteTimerId = null; this.configReloadTimerId = null; this.getDefaultIndentChar = () => { let useTab = this.app.vault.config.useTab === void 0 ? true : false; let tabSize = this.app.vault.config.tabSize == void 0 ? 4 : this.app.vault.config.tabSize; let default_indent = useTab ? " " : " ".repeat(tabSize); return default_indent; }; this.getEditor = () => { let editor = null; let markdownView = this.app.workspace.getActiveViewOfType(import_obsidian9.MarkdownView); if (markdownView) { editor = markdownView.editor; } if (editor === null) console.log("can't get editor"); return editor; }; } get ruleEngine() { return this.ruleManager.ruleEngine; } async onload() { await this.loadSettings(); this.ruleManager = new RuleManager(this.app, this.manifest, this.settings, () => this.saveSettings()); await this.ruleManager.initRuleEngine(); let TaboutPairStrs = [ "\u3010|\u3011", "\uFF08|\uFF09", "\u300A|\u300B", "\u201C|\u201D", "\u2018|\u2019", "\u300C|\u300D", "\u300E|\u300F", "'|'", '"|"', "$$|$$", "$|$", "__|__", "_|_", "==|==", "~~|~~", "**|**", "*|*", "[[|]]", "[|]", "{|}", "(|)", "<|>" ]; this.TaboutPairStrs = TaboutPairStrs.map((s) => string2pairstring(s)); this.CurActiveMarkdown = ""; this.compose_need_handle = false; this.Formater = new LineFormater(); this.onFormatArticle = false; this.plainPasteInProgress = false; this.pasteDetected = false; if (!this.settings) { console.error("EasyTyping: Settings not loaded properly, using defaults"); this.settings = Object.assign({}, DEFAULT_SETTINGS); } setDebug(this.settings.debug); this.registerEditorExtension([ createTransactionFilter(this), createViewUpdatePlugin(this), tabstopsStateField.extension ]); this.registerEditorExtension(import_state6.Prec.highest(import_view5.keymap.of([ { key: "Mod-v", run: () => { this.markPaste(false); return false; } }, { key: "Mod-Shift-v", run: () => { this.markPaste(true); return false; } }, { key: "Tab", run: (v) => handleTabDown(this, v) }, { key: "Enter", run: (v) => handleEnter(this, v) }, { key: "Mod-a", run: (v) => handleModA(this, v) }, { key: "Backspace", run: (v) => { if (!this.settings.BetterBackspace) return false; return handleBackspace(v); } }, { key: "Shift-Enter", run: (v) => handleShiftEnter(this, v) } ]))); const locale7 = getLocale(); this.addCommand({ id: "easy-typing-format-article", name: locale7.commands.formatArticle, editorCallback: (editor, view) => { formatArticle(this, editor, view); }, hotkeys: [{ modifiers: ["Mod", "Shift"], key: "s" }] }); this.addCommand({ id: "easy-typing-select-block", name: locale7.commands.selectBlock, editorCallback: (editor, view) => { selectBlockInCursor(this, editor.cm); } }); this.addCommand({ id: "easy-typing-format-selection", name: locale7.commands.formatSelection, editorCallback: (editor, view) => { formatSelectionOrCurLine(this, editor, view); }, hotkeys: [{ modifiers: ["Mod", "Shift"], key: "l" }] }); this.addCommand({ id: "easy-typing-delete-blank-line", name: locale7.commands.deleteBlankLine, editorCallback: (editor, view) => { deleteBlankLines(this, editor); }, hotkeys: [{ modifiers: ["Mod", "Shift"], key: "k" }] }); this.addCommand({ id: "easy-typing-goto-new-line-after-cur-line", name: locale7.commands.gotoNewLine, editorCallback: (editor, view) => { goNewLineAfterCurLine(this, editor.cm); }, hotkeys: [{ modifiers: ["Mod"], key: "Enter" }] }); this.addCommand({ id: "easy-typing-insert-codeblock", name: locale7.commands.insertCodeblock, editorCallback: (editor, view) => { convert2CodeBlock(this, editor); }, hotkeys: [{ modifiers: ["Mod", "Shift"], key: "n" }] }); this.addCommand({ id: "easy-typing-format-switch", name: locale7.commands.switchAutoformat, callback: () => switchAutoFormatting(this), hotkeys: [{ modifiers: ["Ctrl"], key: "tab" }] }); this.addCommand({ id: "easy-typing-toggle-comment", name: locale7.commands.toggleComment, editorCallback: (editor, view) => toggleComment(editor.cm), hotkeys: [{ modifiers: ["Mod"], key: "/" }] }); this.addSettingTab(new EasyTypingSettingTab(this.app, this)); this.registerEvent(this.app.vault.on("raw", (path) => { this.onConfigFileChange(path); })); this.registerEvent(this.app.workspace.on("active-leaf-change", (leaf) => { var _a; if (leaf.view.getViewType() == "markdown") { let file = this.app.workspace.getActiveFile(); if (file != null && this.CurActiveMarkdown != file.path) { this.CurActiveMarkdown = file.path; if ((_a = this.settings) == null ? void 0 : _a.debug) new import_obsidian9.Notice("new md-file open: " + file.path); } } })); if (import_obsidian9.Platform.isMacOS && this.settings.FixMacOSContextMenu) { this.registerEvent(this.app.workspace.on("editor-menu", (menu, editor, view) => { if (editor.listSelections().length != 1) return; let selection = editor.listSelections()[0]; let selected = editor.getSelection(); if (selected == "\n") { editor.setSelection(selection.anchor, selection.anchor); } })); } console.log("Easy Typing Plugin loaded."); } onunload() { if (this.pasteTimerId) clearTimeout(this.pasteTimerId); if (this.configReloadTimerId) clearTimeout(this.configReloadTimerId); console.log("Easy Typing Plugin unloaded."); } onConfigFileChange(path) { if (Date.now() - this.ruleManager.lastSaveTime < 2e3) return; const builtinRulesPath = this.ruleManager.pluginPath("builtin-rules.json"); const userRulesPath = this.ruleManager.pluginPath("user-rules.json"); if (path !== builtinRulesPath && path !== userRulesPath) return; if (this.configReloadTimerId) clearTimeout(this.configReloadTimerId); this.configReloadTimerId = setTimeout(async () => { this.configReloadTimerId = null; try { await this.ruleManager.initRuleEngine(); if (this.settings.debug) { console.log("[EasyTyping] Rules reloaded from external change:", path); } } catch (e) { console.error("[EasyTyping] Failed to reload rules:", e); } }, 1e3); } markPaste(plain) { this.pasteDetected = true; if (plain) this.plainPasteInProgress = true; if (this.pasteTimerId) clearTimeout(this.pasteTimerId); this.pasteTimerId = setTimeout(() => { this.pasteDetected = false; this.plainPasteInProgress = false; this.pasteTimerId = null; }, 500); } isCurrentFileExclude() { return isCurrentFileExclude(this); } async loadSettings() { try { const userData = await this.loadData(); this.settings = Object.assign({}, DEFAULT_SETTINGS, userData || {}); } catch (error) { console.error("EasyTyping: Failed to load settings, using defaults:", error); this.settings = Object.assign({}, DEFAULT_SETTINGS); } } async saveSettings() { await this.saveData(this.settings); } }; /* nosourcemap */