2025-08-02 12:09:34 +08:00
/ *
THIS IS A GENERATED / BUNDLED FILE BY ESBUILD
if you want to view the source , please visit the github repository of this plugin
* /
"use strict" ;
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 ;
2026-05-06 17:32:44 +08:00
var _ _typeError = ( msg ) => {
throw TypeError ( msg ) ;
} ;
2025-08-02 12:09:34 +08:00
var _ _defNormalProp = ( obj , key , value ) => key in obj ? _ _defProp ( obj , key , { enumerable : true , configurable : true , writable : true , value } ) : obj [ key ] = value ;
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 (
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || ! mod || ! mod . _ _esModule ? _ _defProp ( target , "default" , { value : mod , enumerable : true } ) : target ,
mod
) ) ;
var _ _toCommonJS = ( mod ) => _ _copyProps ( _ _defProp ( { } , "__esModule" , { value : true } ) , mod ) ;
2026-05-06 17:32:44 +08:00
var _ _publicField = ( obj , key , value ) => _ _defNormalProp ( obj , typeof key !== "symbol" ? key + "" : key , value ) ;
var _ _accessCheck = ( obj , member , msg ) => member . has ( obj ) || _ _typeError ( "Cannot " + msg ) ;
var _ _privateGet = ( obj , member , getter ) => ( _ _accessCheck ( obj , member , "read from private field" ) , getter ? getter . call ( obj ) : member . get ( obj ) ) ;
var _ _privateAdd = ( obj , member , value ) => member . has ( obj ) ? _ _typeError ( "Cannot add the same private member more than once" ) : member instanceof WeakSet ? member . add ( obj ) : member . set ( obj , value ) ;
var _ _privateSet = ( obj , member , value , setter ) => ( _ _accessCheck ( obj , member , "write to private field" ) , setter ? setter . call ( obj , value ) : member . set ( obj , value ) , value ) ;
var _ _privateMethod = ( obj , member , method ) => ( _ _accessCheck ( obj , member , "access private method" ) , method ) ;
2025-08-02 12:09:34 +08:00
2026-05-06 17:32:44 +08:00
// node_modules/.pnpm/prettify-pinyin@0.1.5/node_modules/prettify-pinyin/index.js
2025-08-02 12:09:34 +08:00
var require _prettify _pinyin = _ _commonJS ( {
2026-05-06 17:32:44 +08:00
"node_modules/.pnpm/prettify-pinyin@0.1.5/node_modules/prettify-pinyin/index.js" ( exports , module2 ) {
2025-08-02 12:09:34 +08:00
var replacements = {
"a" : [ "\u0101" , "\xE1" , "\u01CE" , "\xE0" ] ,
"e" : [ "\u0113" , "\xE9" , "\u011B" , "\xE8" ] ,
"u" : [ "\u016B" , "\xFA" , "\u01D4" , "\xF9" ] ,
"i" : [ "\u012B" , "\xED" , "\u01D0" , "\xEC" ] ,
"o" : [ "\u014D" , "\xF3" , "\u01D2" , "\xF2" ] ,
"\xFC" : [ "\u01D6" , "\u01D8" , "\u01DA" , "\u01DC" ]
} ;
var medials = [ "i" , "u" , "\xFC" ] ;
var prettify = function ( str ) {
str = str . replace ( "v" , "\xFC" ) ;
var syllables = str . split ( " " ) ;
for ( var i = 0 ; i < syllables . length ; i ++ ) {
var syllable = syllables [ i ] ;
var tone = parseInt ( syllable [ syllable . length - 1 ] ) ;
if ( tone <= 0 || tone > 5 ) {
console . error ( "invalid tone number:" , tone , "in" , syllable ) ;
} else if ( tone === 5 ) {
syllables [ i ] = syllable . slice ( 0 , syllable . length - 1 ) ;
} else {
for ( var j = 0 ; j < syllable . length ; j ++ ) {
var currentLetter = syllable [ j ] ;
var nextLetter = syllable [ j + 1 ] ;
if ( replacements [ currentLetter ] ) {
var replaced ;
var letterToReplace ;
if ( replacements [ nextLetter ] && medials . indexOf ( currentLetter ) >= 0 ) {
letterToReplace = nextLetter ;
} else {
letterToReplace = currentLetter ;
}
replaced = syllable . replace ( letterToReplace , replacements [ letterToReplace ] [ tone - 1 ] ) ;
syllables [ i ] = replaced . slice ( 0 , replaced . length - 1 ) ;
break ;
}
}
}
}
return syllables . join ( " " ) ;
} ;
module2 . exports . prettify = prettify ;
}
} ) ;
2026-05-06 17:32:44 +08:00
// node_modules/.pnpm/chinese-tokenizer@https+++codeload.github.com+tadashi-aikawa+chinese-tokenizer+tar.gz+3_3982f36683f7491dc77ca9b1040b1318/node_modules/chinese-tokenizer/src/trie.js
2025-08-02 12:09:34 +08:00
var require _trie = _ _commonJS ( {
2026-05-06 17:32:44 +08:00
"node_modules/.pnpm/chinese-tokenizer@https+++codeload.github.com+tadashi-aikawa+chinese-tokenizer+tar.gz+3_3982f36683f7491dc77ca9b1040b1318/node_modules/chinese-tokenizer/src/trie.js" ( exports , module2 ) {
2025-08-02 12:09:34 +08:00
var Trie = class {
constructor ( ) {
this . content = { } ;
}
getKeyObject ( key , create = false ) {
key = key . toString ( ) ;
let chars = key === "" ? [ key ] : Array . from ( key ) ;
let obj = this . content ;
for ( let char of chars ) {
if ( obj [ char ] == null ) {
2026-05-06 17:32:44 +08:00
if ( create ) obj [ char ] = { } ;
else return { } ;
2025-08-02 12:09:34 +08:00
}
obj = obj [ char ] ;
}
return obj ;
}
get ( key ) {
let obj = this . getKeyObject ( key ) ;
return obj . values || [ ] ;
}
getPrefix ( key ) {
let inner = ( key2 , obj = null ) => {
2026-05-06 17:32:44 +08:00
if ( obj == null ) obj = this . getKeyObject ( key2 ) ;
2025-08-02 12:09:34 +08:00
let result = obj . values ? [ ... obj . values ] : [ ] ;
for ( let char in obj ) {
2026-05-06 17:32:44 +08:00
if ( char === "values" || obj [ char ] == null ) continue ;
2025-08-02 12:09:34 +08:00
result . push ( ... inner ( key2 + char , obj [ char ] ) ) ;
}
return result ;
} ;
return inner ( key ) ;
}
push ( key , value ) {
let obj = this . getKeyObject ( key , true ) ;
2026-05-06 17:32:44 +08:00
if ( obj . values == null ) obj . values = [ ] ;
if ( ! obj . values . includes ( value ) ) obj . values . push ( value ) ;
2025-08-02 12:09:34 +08:00
return this ;
}
} ;
module2 . exports = Trie ;
}
} ) ;
2026-05-06 17:32:44 +08:00
// node_modules/.pnpm/chinese-tokenizer@https+++codeload.github.com+tadashi-aikawa+chinese-tokenizer+tar.gz+3_3982f36683f7491dc77ca9b1040b1318/node_modules/chinese-tokenizer/src/cedict.js
2025-08-02 12:09:34 +08:00
var require _cedict = _ _commonJS ( {
2026-05-06 17:32:44 +08:00
"node_modules/.pnpm/chinese-tokenizer@https+++codeload.github.com+tadashi-aikawa+chinese-tokenizer+tar.gz+3_3982f36683f7491dc77ca9b1040b1318/node_modules/chinese-tokenizer/src/cedict.js" ( exports , module2 ) {
2025-08-02 12:09:34 +08:00
var { prettify } = require _prettify _pinyin ( ) ;
var Trie = require _trie ( ) ;
function parseLine ( line ) {
2026-05-06 17:32:44 +08:00
let match2 = line . match ( /^(\S+)\s(\S+)\s\[([^\]]+)\]\s\/(.+)\// ) ;
if ( match2 == null ) return ;
let [ , traditional , simplified , pinyin , english ] = match2 ;
2025-08-02 12:09:34 +08:00
pinyin = pinyin . replace ( /u:/g , "\xFC" ) ;
let pinyinPretty = prettify ( pinyin ) ;
return { traditional , simplified , pinyin , pinyinPretty , english } ;
}
var Cedict = class {
load ( contents ) {
this . simplifiedTrie = new Trie ( ) ;
this . traditionalTrie = new Trie ( ) ;
let lines = contents . split ( "\n" ) ;
for ( let line of lines ) {
2026-05-06 17:32:44 +08:00
if ( line . trim ( ) === "" || line [ 0 ] === "#" ) continue ;
2025-08-02 12:09:34 +08:00
let entry = parseLine ( line ) ;
2026-05-06 17:32:44 +08:00
if ( entry == null ) continue ;
2025-08-02 12:09:34 +08:00
this . simplifiedTrie . push ( entry . simplified , entry ) ;
this . traditionalTrie . push ( entry . traditional , entry ) ;
}
}
get ( word , traditional = false ) {
return traditional ? this . traditionalTrie . get ( word ) : this . simplifiedTrie . get ( word ) ;
}
getPrefix ( word , traditional = false ) {
return traditional ? this . traditionalTrie . getPrefix ( word ) : this . simplifiedTrie . getPrefix ( word ) ;
}
} ;
module2 . exports = Cedict ;
}
} ) ;
2026-05-06 17:32:44 +08:00
// node_modules/.pnpm/chinese-tokenizer@https+++codeload.github.com+tadashi-aikawa+chinese-tokenizer+tar.gz+3_3982f36683f7491dc77ca9b1040b1318/node_modules/chinese-tokenizer/src/main.js
2025-08-02 12:09:34 +08:00
var require _main = _ _commonJS ( {
2026-05-06 17:32:44 +08:00
"node_modules/.pnpm/chinese-tokenizer@https+++codeload.github.com+tadashi-aikawa+chinese-tokenizer+tar.gz+3_3982f36683f7491dc77ca9b1040b1318/node_modules/chinese-tokenizer/src/main.js" ( exports ) {
2025-08-02 12:09:34 +08:00
var Cedict = require _cedict ( ) ;
var chinesePunctuation = [
"\xB7" ,
"\xD7" ,
"\u2014" ,
"\u2018" ,
"\u2019" ,
"\u201C" ,
"\u201D" ,
"\u2026" ,
"\u3001" ,
"\u3002" ,
"\u300A" ,
"\u300B" ,
"\u300E" ,
"\u300F" ,
"\u3010" ,
"\u3011" ,
"\uFF01" ,
"\uFF08" ,
"\uFF09" ,
"\uFF0C" ,
"\uFF1A" ,
"\uFF1B" ,
"\uFF1F"
] ;
exports . load = function ( contents ) {
let dictionary = new Cedict ( ) ;
dictionary . load ( contents ) ;
return function tokenize ( text2 ) {
text2 = Array . from ( text2 . replace ( /\r/g , "" ) ) ;
let result = [ ] ;
let i = 0 ;
let [ offset , line , column ] = [ 0 , 1 , 1 ] ;
let [ simplifiedPreference , traditionalPreference ] = [ 0 , 0 ] ;
let pushToken = ( word ) => {
let simplifiedEntries = dictionary . get ( word , false ) ;
let traditionalEntries = dictionary . get ( word , true ) ;
let entries = simplifiedEntries . length === 0 ? traditionalEntries : traditionalEntries . length === 0 ? simplifiedEntries : simplifiedPreference < traditionalPreference ? traditionalEntries : simplifiedPreference > traditionalPreference ? simplifiedEntries : traditionalEntries ;
if ( traditionalEntries . length === 0 && simplifiedEntries . length > 0 ) {
simplifiedPreference ++ ;
} else if ( simplifiedEntries . length === 0 && traditionalEntries . length > 0 ) {
traditionalPreference ++ ;
}
result . push ( {
text : word ,
traditional : entries [ 0 ] ? entries [ 0 ] . traditional : word ,
simplified : entries [ 0 ] ? entries [ 0 ] . simplified : word ,
position : {
offset ,
line ,
column
} ,
matches : entries . map ( ( { pinyin , pinyinPretty , english } ) => ( {
pinyin ,
pinyinPretty ,
english
} ) )
} ) ;
let wordArr = Array . from ( word ) ;
let lastLineBreakIndex = word . lastIndexOf ( "\n" ) ;
i += wordArr . length ;
offset += word . length ;
line += wordArr . filter ( ( x ) => x === "\n" ) . length ;
column = lastLineBreakIndex >= 0 ? word . length - lastLineBreakIndex : column + word . length ;
} ;
while ( i < text2 . length ) {
if ( i !== text2 . length - 1 ) {
let getTwo = text2 . slice ( i , i + 2 ) . join ( "" ) ;
let simplifiedEntries = dictionary . getPrefix ( getTwo , false ) ;
let traditionalEntries = dictionary . getPrefix ( getTwo , true ) ;
let foundWord = null ;
let foundEntries = null ;
for ( let entries of [ traditionalEntries , simplifiedEntries ] ) {
for ( let entry of entries ) {
let matchText = entries === traditionalEntries ? entry . traditional : entry . simplified ;
let word2 = text2 . slice ( i , i + Array . from ( matchText ) . length ) . join ( "" ) ;
if ( matchText === word2 && ( foundWord == null || Array . from ( word2 ) . length > Array . from ( foundWord ) . length ) ) {
foundWord = word2 ;
foundEntries = entries ;
}
}
}
if ( foundWord != null ) {
pushToken ( foundWord ) ;
if ( foundEntries === simplifiedEntries ) {
simplifiedPreference ++ ;
} else if ( foundEntries === traditionalEntries ) {
traditionalPreference ++ ;
}
continue ;
}
}
let character = text2 [ i ] ;
let isChinese = ( character2 ) => chinesePunctuation . includes ( character2 ) || dictionary . get ( character2 , false ) . length > 0 || dictionary . get ( character2 , true ) . length > 0 ;
if ( isChinese ( character ) || character . match ( /\s/ ) != null ) {
pushToken ( character ) ;
continue ;
}
let end = i + 1 ;
for ( ; end < text2 . length ; end ++ ) {
2026-05-06 17:32:44 +08:00
if ( text2 [ end ] . match ( /\s/ ) != null || isChinese ( text2 [ end ] ) ) break ;
2025-08-02 12:09:34 +08:00
}
let word = text2 . slice ( i , end ) . join ( "" ) ;
pushToken ( word ) ;
}
return result ;
} ;
} ;
}
} ) ;
// src/main.ts
var main _exports = { } ;
_ _export ( main _exports , {
default : ( ) => VariousComponents
} ) ;
module . exports = _ _toCommonJS ( main _exports ) ;
var import _obsidian9 = require ( "obsidian" ) ;
2026-05-06 17:32:44 +08:00
// node_modules/.pnpm/ts-deepmerge@7.0.3/node_modules/ts-deepmerge/esm/index.js
var isObject = ( obj ) => {
if ( typeof obj === "object" && obj !== null ) {
if ( typeof Object . getPrototypeOf === "function" ) {
const prototype = Object . getPrototypeOf ( obj ) ;
return prototype === Object . prototype || prototype === null ;
}
return Object . prototype . toString . call ( obj ) === "[object Object]" ;
}
return false ;
} ;
var merge = ( ... objects ) => objects . reduce ( ( result , current ) => {
if ( current === void 0 ) {
return result ;
}
if ( Array . isArray ( current ) ) {
throw new TypeError ( "Arguments provided to ts-deepmerge must be objects, not arrays." ) ;
}
Object . keys ( current ) . forEach ( ( key ) => {
if ( [ "__proto__" , "constructor" , "prototype" ] . includes ( key ) ) {
return ;
}
if ( Array . isArray ( result [ key ] ) && Array . isArray ( current [ key ] ) ) {
result [ key ] = merge . options . mergeArrays ? merge . options . uniqueArrayItems ? Array . from ( new Set ( result [ key ] . concat ( current [ key ] ) ) ) : [ ... result [ key ] , ... current [ key ] ] : current [ key ] ;
} else if ( isObject ( result [ key ] ) && isObject ( current [ key ] ) ) {
result [ key ] = merge ( result [ key ] , current [ key ] ) ;
} else if ( ! isObject ( result [ key ] ) && isObject ( current [ key ] ) ) {
result [ key ] = merge ( current [ key ] , void 0 ) ;
} else {
result [ key ] = current [ key ] === void 0 ? merge . options . allowUndefinedOverrides ? current [ key ] : result [ key ] : current [ key ] ;
}
} ) ;
return result ;
} , { } ) ;
var defaultOptions = {
allowUndefinedOverrides : true ,
mergeArrays : true ,
uniqueArrayItems : true
} ;
merge . options = defaultOptions ;
merge . withOptions = ( options , ... objects ) => {
merge . options = Object . assign ( Object . assign ( { } , defaultOptions ) , options ) ;
const result = merge ( ... objects ) ;
merge . options = defaultOptions ;
return result ;
} ;
// src/app-helper.ts
var import _obsidian = require ( "obsidian" ) ;
// node_modules/.pnpm/emoji-regex@10.6.0/node_modules/emoji-regex/index.mjs
var emoji _regex _default = ( ) => {
return / [ # * 0 - 9 ] \ u F E 0 F ? \ u 2 0 E 3 | [ \ x A 9 \ x A E \ u 2 0 3 C \ u 2 0 4 9 \ u 2 1 2 2 \ u 2 1 3 9 \ u 2 1 9 4 - \ u 2 1 9 9 \ u 2 1 A 9 \ u 2 1 A A \ u 2 3 1 A \ u 2 3 1 B \ u 2 3 2 8 \ u 2 3 C F \ u 2 3 E D - \ u 2 3 E F \ u 2 3 F 1 \ u 2 3 F 2 \ u 2 3 F 8 - \ u 2 3 F A \ u 2 4 C 2 \ u 2 5 A A \ u 2 5 A B \ u 2 5 B 6 \ u 2 5 C 0 \ u 2 5 F B \ u 2 5 F C \ u 2 5 F E \ u 2 6 0 0 - \ u 2 6 0 4 \ u 2 6 0 E \ u 2 6 1 1 \ u 2 6 1 4 \ u 2 6 1 5 \ u 2 6 1 8 \ u 2 6 2 0 \ u 2 6 2 2 \ u 2 6 2 3 \ u 2 6 2 6 \ u 2 6 2 A \ u 2 6 2 E \ u 2 6 2 F \ u 2 6 3 8 - \ u 2 6 3 A \ u 2 6 4 0 \ u 2 6 4 2 \ u 2 6 4 8 - \ u 2 6 5 3 \ u 2 6 5 F \ u 2 6 6 0 \ u 2 6 6 3 \ u 2 6 6 5 \ u 2 6 6 6 \ u 2 6 6 8 \ u 2 6 7 B \ u 2 6 7 E \ u 2 6 7 F \ u 2 6 9 2 \ u 2 6 9 4 - \ u 2 6 9 7 \ u 2 6 9 9 \ u 2 6 9 B \ u 2 6 9 C \ u 2 6 A 0 \ u 2 6 A 7 \ u 2 6 A A \ u 2 6 B 0 \ u 2 6 B 1 \ u 2 6 B D \ u 2 6 B E \ u 2 6 C 4 \ u 2 6 C 8 \ u 2 6 C F \ u 2 6 D 1 \ u 2 6 E 9 \ u 2 6 F 0 - \ u 2 6 F 5 \ u 2 6 F 7 \ u 2 6 F 8 \ u 2 6 F A \ u 2 7 0 2 \ u 2 7 0 8 \ u 2 7 0 9 \ u 2 7 0 F \ u 2 7 1 2 \ u 2 7 1 4 \ u 2 7 1 6 \ u 2 7 1 D \ u 2 7 2 1 \ u 2 7 3 3 \ u 2 7 3 4 \ u 2 7 4 4 \ u 2 7 4 7 \ u 2 7 5 7 \ u 2 7 6 3 \ u 2 7 A 1 \ u 2 9 3 4 \ u 2 9 3 5 \ u 2 B 0 5 - \ u 2 B 0 7 \ u 2 B 1 B \ u 2 B 1 C \ u 2 B 5 5 \ u 3 0 3 0 \ u 3 0 3 D \ u 3 2 9 7 \ u 3 2 9 9 ] \ u F E 0 F ? | [ \ u 2 6 1 D \ u 2 7 0 C \ u 2 7 0 D ] ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F F ] | \ u F E 0 F ) ? | [ \ u 2 7 0 A \ u 2 7 0 B ] ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F F ] ) ? | [ \ u 2 3 E 9 - \ u 2 3 E C \ u 2 3 F 0 \ u 2 3 F 3 \ u 2 5 F D \ u 2 6 9 3 \ u 2 6 A 1 \ u 2 6 A B \ u 2 6 C 5 \ u 2 6 C E \ u 2 6 D 4 \ u 2 6 E A \ u 2 6 F D \ u 2 7 0 5 \ u 2 7 2 8 \ u 2 7 4 C \ u 2 7 4 E \ u 2 7 5 3 - \ u 2 7 5 5 \ u 2 7 9 5 - \ u 2 7 9 7 \ u 2 7 B 0 \ u 2 7 B F \ u 2 B 5 0 ] | \ u 2 6 D 3 \ u F E 0 F ? ( ? : \ u 2 0 0 D \ u D 8 3 D \ u D C A 5 ) ? | \ u 2 6 F 9 ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F F ] | \ u F E 0 F ) ? ( ? : \ u 2 0 0 D [ \ u 2 6 4 0 \ u 2 6 4 2 ] \ u F E 0 F ? ) ? | \ u 2 7 6 4 \ u F E 0 F ? ( ? : \ u 2 0 0 D ( ? : \ u D 8 3 D \ u D D 2 5 | \ u D 8 3 E \ u D E 7 9 ) ) ? | \ u D 8 3 C ( ? : [ \ u D C 0 4 \ u D D 7 0 \ u D D 7 1 \ u D D 7 E \ u D D 7 F \ u D E 0 2 \ u D E 3 7 \ u D F 2 1 \ u D F 2 4 - \ u D F 2 C \ u D F 3 6 \ u D F 7 D \ u D F 9 6 \ u D F 9 7 \ u D F 9 9 - \ u D F 9 B \ u D F 9 E \ u D F 9 F \ u D F C D \ u D F C E \ u D F D 4 - \ u D F D F \ u D F F 5 \ u D F F 7 ] \ u F E 0 F ? | [ \ u D F 8 5 \ u D F C 2 \ u D F C 7 ] ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F F ] ) ? | [ \ u D F C 4 \ u D F C A ] ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F F ] ) ? ( ? : \ u 2 0 0 D [ \ u 2 6 4 0 \ u 2 6 4 2 ] \ u F E 0 F ? ) ? | [ \ u D F C B \ u D F C C ] ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F F ] | \ u F E 0 F ) ? ( ? : \ u 2 0 0 D [ \ u 2 6 4 0 \ u 2 6 4 2 ] \ u F E 0 F ? ) ? | [ \ u D C C F \ u D D 8 E \ u D D 9 1 - \ u D D 9 A \ u D E 0 1 \ u D E 1 A \ u D E 2 F \ u D E 3 2 - \ u D E 3 6 \ u D E 3 8 - \ u D E 3 A \ u D E 5 0 \ u D E 5 1 \ u D F 0 0 - \ u D F 2 0 \ u D F 2 D - \ u D F 3 5 \ u D F 3 7 - \ u D F 4 3 \ u D F 4 5 - \ u D F 4 A \ u D F 4 C - \ u D F 7 C \ u D F 7 E - \ u D F 8 4 \ u D F 8 6 - \ u D F 9 3 \ u D F A 0 - \ u D F C 1 \ u D F C 5 \ u D F C 6 \ u D F C 8 \ u D F C 9 \ u D F C F - \ u D F D 3 \ u D F E 0 - \ u D F F 0 \ u D F F 8 - \ u D F F F ] | \ u D D E 6 \ u D 8 3 C [ \ u D D E 8 - \ u D D E C \ u D D E E \ u D D F 1 \ u D D F 2 \ u D D F 4 \ u D D F 6 - \ u D D F A \ u D D F C \ u D D F D \ u D D F F ] | \ u D D E 7 \ u D 8 3 C [ \ u D D E 6 \ u D D E 7 \ u D D E 9 - \ u D D E F \ u D D F 1 - \ u D D F 4 \ u D D F 6 - \ u D D F 9 \ u D D F B \ u D D F C \ u D D F E \ u D D F F ] | \ u D D E 8 \ u D 8 3 C [ \ u D D E 6 \ u D D E 8 \ u D D E 9 \ u D D E B - \ u D D E E \ u D D F 0 - \ u D D F 7 \ u D D F A - \ u D D F F ] | \ u D D E 9 \ u D 8 3 C [ \ u D D E A \ u D D E C \ u D D E F \ u D D F 0 \ u D D F 2 \ u D D F 4 \ u D D F F ] | \ u D D E A \ u D 8 3 C [ \ u D D E 6 \ u D D E 8 \ u D D E A \ u D D E C \ u D D E D \ u D D F 7 - \ u D D F A ] | \ u D D E B \ u D 8 3 C [ \ u D D E E - \ u D D F 0 \ u D D F 2 \ u D D F 4 \ u D D F 7 ] | \ u D D E C \ u D 8 3 C [ \ u D D E 6 \ u D D E 7 \ u D D E 9 - \ u D D E E \ u D D F 1 - \ u D D F 3 \ u D D F 5 - \ u D D F A \ u D D F C \ u D D F E ] | \ u D D E D \ u D 8 3 C [ \ u D D F 0 \ u D D F 2 \ u D D F 3 \ u D D F 7 \ u D D F 9 \ u D D F A ] | \ u D D E E \ u D 8 3 C [ \ u D D E 8 - \ u D D E A \ u D D F 1 - \ u D D F 4 \ u D D F 6 - \ u D D F 9 ] | \ u D D E F \ u D 8 3 C [ \ u D D E A \ u D D F 2 \ u D D F 4 \ u D D F 5 ] | \ u D D F 0 \ u D 8 3 C [ \ u D D E A \ u D D E C - \ u D D E E \ u D D F 2 \ u D D F 3 \ u D D F 5 \ u D D F 7 \ u D D F C \ u D D F E \ u D D F F ] | \ u D D F 1 \ u D 8 3 C [ \ u D D E 6 - \ u D D E 8 \ u D D E E \ u D D F 0 \ u D D F 7 - \ u D D F B \ u D D F E ] | \ u D D F 2 \ u D 8 3 C [ \ u D D E 6 \ u D D E 8 - \ u D D E D \ u D D F 0 - \ u D D F F ] | \ u D D F 3 \ u D 8 3 C [ \ u D D E 6 \ u D D E 8 \ u D D E A - \ u D D E C \ u D D E E \ u D D F 1 \ u D D F 4 \ u D D F 5 \ u D D F 7 \ u D D F A \ u D D F F ] | \ u D D F 4 \ u D 8 3 C \ u D D F 2 | \ u D D F 5 \ u D 8 3 C [ \ u D D E 6 \ u D D E A - \ u D D E D \ u D D F 0 - \ u D D F 3 \ u D D F 7 - \ u D D F 9 \ u D D F C \ u D D F E ] | \ u D D F 6 \ u D 8 3 C \ u D D E 6 | \ u D D F 7 \ u D 8 3 C [ \ u D D E A \ u D D F 4 \ u D D F 8 \ u D D F A \ u D D F C ] | \ u D D F 8 \ u D 8 3 C [ \ u D D E 6 - \ u D D E A \ u D D E C - \ u D D F 4 \ u D D F 7 - \ u D D F 9 \ u D D F B \ u D D F D - \ u D D F F ] | \ u D D F 9 \ u D 8 3 C [ \ u D D E 6 \ u D D E 8 \ u D D E 9 \ u D D E B - \ u D D E D \ u D D E F - \ u D D F 4 \ u D D F 7 \ u D D F 9 \ u D D F B \ u D D F C \ u D D F F ] | \ u D D F A \ u D 8 3 C [ \ u D D E 6 \ u D D E C \ u D D F 2 \ u D D F 3 \ u D D F 8 \ u D D F E \ u D D F F ] | \ u D D F B \ u D 8 3 C [ \ u D D E 6 \ u D D E 8 \ u D D E A \ u D D E C \ u D D E E \ u D D F 3 \ u D D F A ] | \ u D D F C \ u D 8 3 C [ \ u D D E B \ u D D F 8 ] | \ u D D F D \ u D 8 3 C \ u D D F 0 | \ u D D F E \ u D 8 3 C [ \ u D D E A \ u D D F 9 ] | \ u D D F F \ u D 8 3 C [ \ u D D E 6 \ u D D F 2 \ u D D F C ] | \ u D F 4 4 ( ? : \ u 2 0 0 D \ u D 8 3 D \ u D F E B ) ? | \ u D F 4 B ( ? : \ u 2 0 0 D \ u D 8 3 D \ u D F E 9 ) ? | \ u D F C 3 ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F F ] ) ? ( ? : \ u 2 0 0 D ( ? : [ \ u 2 6 4 0 \ u 2 6 4 2 ] \ u F E 0 F ? ( ? : \ u 2 0 0 D \ u 2 7 A 1 \ u F E 0 F ? ) ? | \ u 2 7 A 1 \ u F E 0 F ? ) ) ? | \ u D F F 3 \ u F E 0 F ? ( ? : \ u 2 0 0 D ( ? : \ u 2 6 A 7 \ u F E 0 F ? | \ u D 8 3 C \ u D F 0 8 ) ) ? | \ u D F F 4 ( ? : \ u 2 0 0 D \ u 2 6 2 0 \ u F E 0 F ? | \ u D B 4 0 \ u D C 6 7 \ u D B 4 0 \ u D C 6 2 \ u D B 4 0 ( ? : \ u D C 6 5 \ u D B 4 0 \ u D C 6 E \ u D B 4 0 \ u D C 6 7 | \ u D C 7 3 \ u D B 4 0 \ u D C 6 3 \ u D B 4 0 \ u D C 7 4 | \ u D C 7 7 \ u D B 4 0 \ u D C 6 C \ u D B 4 0 \ u D C 7 3 ) \ u D B 4 0 \ u D C 7 F ) ? ) | \ u D 8 3 D ( ? : [ \ u D C 3 F \ u D C F D \ u D D 4 9 \ u D D 4 A \ u D D 6 F \ u D D 7 0 \ u D D 7 3 \ u D D 7 6 - \ u D D 7 9 \ u D D 8 7 \ u D D 8 A - \ u D D 8 D \ u D D A 5 \ u D D A 8 \ u D D B 1 \ u D D B 2 \ u D D B C \ u D D C 2 - \ u D D C 4 \ u D D D 1 - \ u D D D 3 \ u D D D C - \ u D D D E \ u D D E 1 \ u D D E 3 \ u D D E 8 \ u D D E F \ u D D F 3 \ u D D F A \ u D E C B \ u D E C D - \ u D E C F \ u D E E 0 - \ u D E E 5 \ u D E E 9 \ u D E F 0 \ u D E F 3 ] \ u F E 0 F ? | [ \ u D C 4 2 \ u D C 4 3 \ u D C 4 6 - \ u D C 5 0 \ u D C 6 6 \ u D C 6 7 \ u D C 6 B - \ u D C 6 D \ u D C 7 2 \ u D C 7 4 - \ u D C 7 6 \ u D C 7 8 \ u D C 7 C \ u D C 8 3 \ u D C 8 5 \ u D C 8 F \ u D C 9 1 \ u D C A A \ u D D 7 A \ u D D 9 5 \ u D D 9 6 \ u D E 4 C \ u D E 4 F \ u D E C 0 \ u D E C C ] ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F F ] ) ? | [ \ u D C 6 E - \ u D C 7 1 \ u D C 7 3 \ u D C 7 7 \ u D C 8 1 \ u D C 8 2 \ u D C 8 6 \ u D C 8 7 \ u D E 4 5 - \ u D E 4 7 \ u D E 4 B \ u D E 4 D \ u D E 4 E \ u D E A 3 \ u D E B 4 \ u D E B 5 ] ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F F ] ) ? ( ? : \
} ;
2025-08-02 12:09:34 +08:00
// src/util/collection-helper.ts
var groupBy = ( values , toKey ) => values . reduce (
( prev , cur , _1 , _2 , k = toKey ( cur ) ) => ( ( prev [ k ] || ( prev [ k ] = [ ] ) ) . push ( cur ) , prev ) ,
{ }
) ;
function uniq ( values ) {
return [ ... new Set ( values ) ] ;
}
function uniqBy ( values , fn ) {
const m = /* @__PURE__ */ new Map ( ) ;
values . forEach ( ( x ) => {
const k = fn ( x ) ;
if ( ! m . has ( k ) ) {
m . set ( k , x ) ;
}
} ) ;
return Array . from ( m . values ( ) ) ;
}
function uniqWith ( arr , fn ) {
return arr . filter (
( element2 , index ) => arr . findIndex ( ( step ) => fn ( element2 , step ) ) === index
) ;
}
2026-05-06 17:32:44 +08:00
function hasSameElement ( arr1 , arr2 ) {
return arr1 . some ( ( x ) => arr2 . includes ( x ) ) ;
}
2025-08-02 12:09:34 +08:00
function setEquals ( set1 , set2 ) {
if ( set1 . size !== set2 . size ) {
return false ;
}
return Array . from ( set1 ) . every ( ( element2 ) => set2 . has ( element2 ) ) ;
}
function mirrorMap ( collection , toValue ) {
return collection . reduce ( ( p , c ) => ( { ... p , [ toValue ( c ) ] : toValue ( c ) } ) , { } ) ;
}
function max ( collection , emptyValue ) {
const select2 = ( a , b ) => a >= b ? a : b ;
return collection . reduce ( select2 , emptyValue ) ;
}
// src/util/diacritics-map.ts
var defaultDiacriticsRemovalMap = [
{
base : "A" ,
letters : "A\u24B6\uFF21\xC0\xC1\xC2\u1EA6\u1EA4\u1EAA\u1EA8\xC3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\xC4\u01DE\u1EA2\xC5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F"
} ,
{ base : "AA" , letters : "\uA732" } ,
{ base : "AE" , letters : "\xC6\u01FC\u01E2" } ,
{ base : "AO" , letters : "\uA734" } ,
{ base : "AU" , letters : "\uA736" } ,
{ base : "AV" , letters : "\uA738\uA73A" } ,
{ base : "AY" , letters : "\uA73C" } ,
{
base : "B" ,
letters : "B\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181"
} ,
{
base : "C" ,
letters : "C\u24B8\uFF23\u0106\u0108\u010A\u010C\xC7\u1E08\u0187\u023B\uA73E"
} ,
{
base : "D" ,
letters : "D\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779\xD0"
} ,
{ base : "DZ" , letters : "\u01F1\u01C4" } ,
{ base : "Dz" , letters : "\u01F2\u01C5" } ,
{
base : "E" ,
letters : "E\u24BA\uFF25\xC8\xC9\xCA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\xCB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E"
} ,
{ base : "F" , letters : "F\u24BB\uFF26\u1E1E\u0191\uA77B" } ,
{
base : "G" ,
letters : "G\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E"
} ,
{
base : "H" ,
letters : "H\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D"
} ,
{
base : "I" ,
letters : "I\u24BE\uFF29\xCC\xCD\xCE\u0128\u012A\u012C\u0130\xCF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197"
} ,
{ base : "J" , letters : "J\u24BF\uFF2A\u0134\u0248" } ,
{
base : "K" ,
letters : "K\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2"
} ,
{
base : "L" ,
letters : "L\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780"
} ,
{ base : "LJ" , letters : "\u01C7" } ,
{ base : "Lj" , letters : "\u01C8" } ,
{ base : "M" , letters : "M\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C" } ,
{
base : "N" ,
letters : "N\u24C3\uFF2E\u01F8\u0143\xD1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4"
} ,
{ base : "NJ" , letters : "\u01CA" } ,
{ base : "Nj" , letters : "\u01CB" } ,
{
base : "O" ,
letters : "O\u24C4\uFF2F\xD2\xD3\xD4\u1ED2\u1ED0\u1ED6\u1ED4\xD5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\xD6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\xD8\u01FE\u0186\u019F\uA74A\uA74C"
} ,
{ base : "OI" , letters : "\u01A2" } ,
{ base : "OO" , letters : "\uA74E" } ,
{ base : "OU" , letters : "\u0222" } ,
{ base : "OE" , letters : "\x8C\u0152" } ,
{ base : "oe" , letters : "\x9C\u0153" } ,
{
base : "P" ,
letters : "P\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754"
} ,
{ base : "Q" , letters : "Q\u24C6\uFF31\uA756\uA758\u024A" } ,
{
base : "R" ,
letters : "R\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782"
} ,
{
base : "S" ,
letters : "S\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784"
} ,
{
base : "T" ,
letters : "T\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786"
} ,
{ base : "TZ" , letters : "\uA728" } ,
{
base : "U" ,
letters : "U\u24CA\uFF35\xD9\xDA\xDB\u0168\u1E78\u016A\u1E7A\u016C\xDC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244"
} ,
{ base : "V" , letters : "V\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245" } ,
{ base : "VY" , letters : "\uA760" } ,
{
base : "W" ,
letters : "W\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72"
} ,
{ base : "X" , letters : "X\u24CD\uFF38\u1E8A\u1E8C" } ,
{
base : "Y" ,
letters : "Y\u24CE\uFF39\u1EF2\xDD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE"
} ,
{
base : "Z" ,
letters : "Z\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762"
} ,
{
base : "a" ,
letters : "a\u24D0\uFF41\u1E9A\xE0\xE1\xE2\u1EA7\u1EA5\u1EAB\u1EA9\xE3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\xE4\u01DF\u1EA3\xE5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250"
} ,
{ base : "aa" , letters : "\uA733" } ,
{ base : "ae" , letters : "\xE6\u01FD\u01E3" } ,
{ base : "ao" , letters : "\uA735" } ,
{ base : "au" , letters : "\uA737" } ,
{ base : "av" , letters : "\uA739\uA73B" } ,
{ base : "ay" , letters : "\uA73D" } ,
{
base : "b" ,
letters : "b\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253"
} ,
{
base : "c" ,
letters : "c\u24D2\uFF43\u0107\u0109\u010B\u010D\xE7\u1E09\u0188\u023C\uA73F\u2184"
} ,
{
base : "d" ,
letters : "d\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A"
} ,
{ base : "dz" , letters : "\u01F3\u01C6" } ,
{
base : "e" ,
letters : "e\u24D4\uFF45\xE8\xE9\xEA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\xEB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD"
} ,
{ base : "f" , letters : "f\u24D5\uFF46\u1E1F\u0192\uA77C" } ,
{
base : "g" ,
letters : "g\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F"
} ,
{
base : "h" ,
letters : "h\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265"
} ,
{ base : "hv" , letters : "\u0195" } ,
{
base : "i" ,
letters : "i\u24D8\uFF49\xEC\xED\xEE\u0129\u012B\u012D\xEF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131"
} ,
{ base : "j" , letters : "j\u24D9\uFF4A\u0135\u01F0\u0249" } ,
{
base : "k" ,
letters : "k\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3"
} ,
{
base : "l" ,
letters : "l\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747"
} ,
{ base : "lj" , letters : "\u01C9" } ,
{ base : "m" , letters : "m\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F" } ,
{
base : "n" ,
letters : "n\u24DD\uFF4E\u01F9\u0144\xF1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5"
} ,
{ base : "nj" , letters : "\u01CC" } ,
{
base : "o" ,
letters : "o\u24DE\uFF4F\xF2\xF3\xF4\u1ED3\u1ED1\u1ED7\u1ED5\xF5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\xF6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\xF8\u01FF\u0254\uA74B\uA74D\u0275"
} ,
{ base : "oi" , letters : "\u01A3" } ,
{ base : "ou" , letters : "\u0223" } ,
{ base : "oo" , letters : "\uA74F" } ,
{
base : "p" ,
letters : "p\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755"
} ,
{ base : "q" , letters : "q\u24E0\uFF51\u024B\uA757\uA759" } ,
{
base : "r" ,
letters : "r\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783"
} ,
{
base : "s" ,
letters : "s\u24E2\uFF53\xDF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B"
} ,
{
base : "t" ,
letters : "t\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787"
} ,
{ base : "tz" , letters : "\uA729" } ,
{
base : "u" ,
letters : "u\u24E4\uFF55\xF9\xFA\xFB\u0169\u1E79\u016B\u1E7B\u016D\xFC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289"
} ,
{ base : "v" , letters : "v\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C" } ,
{ base : "vy" , letters : "\uA761" } ,
{
base : "w" ,
letters : "w\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73"
} ,
{ base : "x" , letters : "x\u24E7\uFF58\u1E8B\u1E8D" } ,
{
base : "y" ,
letters : "y\u24E8\uFF59\u1EF3\xFD\u0177\u1EF9\u0233\u1E8F\xFF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF"
} ,
{
base : "z" ,
letters : "z\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763"
} ,
// Added to original source definitions
// https://github.com/tadashi-aikawa/obsidian-another-quick-switcher/issues/131
{
base : "2" ,
letters : "\xB2"
} ,
{
base : "3" ,
letters : "\xB3"
}
] ;
var diacriticsMap = { } ;
for ( let i = 0 ; i < defaultDiacriticsRemovalMap . length ; i ++ ) {
const letters = defaultDiacriticsRemovalMap [ i ] . letters ;
for ( let j = 0 ; j < letters . length ; j ++ ) {
diacriticsMap [ letters [ j ] ] = defaultDiacriticsRemovalMap [ i ] . base ;
}
}
var diacritics _map _default = diacriticsMap ;
// src/util/strings.ts
var regEmoji = new RegExp ( ` *( ${ emoji _regex _default ( ) . source } ) * ` , "g" ) ;
function equalsAsLiterals ( one , another ) {
return one . replace ( /[ \t]/g , "" ) === another . replace ( /[ \t]/g , "" ) ;
}
function allNumbersOrFewSymbols ( text2 ) {
return Boolean ( text2 . match ( /^[0-9_\-.]+$/ ) ) ;
}
function allAlphabets ( text2 ) {
return Boolean ( text2 . match ( /^[a-zA-Z0-9_\-]+$/ ) ) ;
}
function excludeEmoji ( text2 ) {
return text2 . replace ( regEmoji , "" ) ;
}
function encodeSpace ( text2 ) {
return text2 . replace ( / /g , "%20" ) ;
}
function removeFromPattern ( pattern , removeChars ) {
return new RegExp (
pattern . source . replace ( new RegExp ( ` [ ${ removeChars } ] ` , "g" ) , "" ) ,
pattern . flags
) ;
}
function normalizeAccentsDiacritics ( text2 ) {
return text2 . replace ( /[^\u0000-\u007E]/g , ( x ) => {
var _a ;
return ( _a = diacritics _map _default [ x ] ) != null ? _a : x ;
} ) ;
}
function synonymAliases ( value , option ) {
let synonym = value ;
if ( option . emoji ) {
synonym = excludeEmoji ( synonym ) ;
}
if ( option . accentsDiacritics ) {
synonym = normalizeAccentsDiacritics ( synonym ) ;
}
return synonym === value ? [ ] : [ synonym ] ;
}
function lowerIncludes ( one , other ) {
return one . toLowerCase ( ) . includes ( other . toLowerCase ( ) ) ;
}
function lowerStartsWith ( a , b ) {
return a . toLowerCase ( ) . startsWith ( b . toLowerCase ( ) ) ;
}
function wrapFuzzy ( func ) {
return ( ... xs ) => func ( ... xs ) ? { type : "concrete_match" } : { type : "none" } ;
}
function lowerFuzzy ( a , b ) {
return microFuzzy ( a . toLowerCase ( ) , b . toLowerCase ( ) ) ;
}
function lowerFuzzyStarsWith ( a , b ) {
const aLower = a . toLowerCase ( ) ;
const bLower = b . toLowerCase ( ) ;
return aLower [ 0 ] === bLower [ 0 ] ? microFuzzy ( aLower , bLower ) : { type : "none" } ;
}
function capitalizeFirstLetter ( str ) {
return str . charAt ( 0 ) . toUpperCase ( ) + str . slice ( 1 ) ;
}
2026-05-06 17:32:44 +08:00
function applyQueryFirstLetterCase ( value , query ) {
if ( ! query ) {
return value ;
}
const words = value . split ( " " ) ;
let offset = 0 ;
const hasUpperExceptSingleLetter = words . some ( ( word ) => {
if ( word . length <= 1 ) {
offset += word . length + 1 ;
return false ;
}
for ( let i = 0 ; i < word . length ; i ++ ) {
const ch = word . charAt ( i ) ;
if ( ch >= "A" && ch <= "Z" ) {
if ( i > 0 || offset !== 0 ) {
return true ;
}
}
}
offset += word . length + 1 ;
return false ;
} ) ;
if ( hasUpperExceptSingleLetter ) {
return value ;
}
const queryFirst = query . charAt ( 0 ) ;
const valueFirst = value . charAt ( 0 ) ;
if ( ! queryFirst || ! valueFirst ) {
return value ;
}
const queryUpper = queryFirst . toUpperCase ( ) ;
const queryLower = queryFirst . toLowerCase ( ) ;
if ( queryUpper === queryLower ) {
return value ;
}
const adjustedFirst = queryFirst === queryUpper ? valueFirst . toUpperCase ( ) : valueFirst . toLowerCase ( ) ;
if ( adjustedFirst === valueFirst ) {
return value ;
}
return adjustedFirst + value . slice ( 1 ) ;
}
2025-08-02 12:09:34 +08:00
function startsSmallLetterOnlyFirst ( str ) {
return Boolean ( str . match ( /^[A-Z][^A-Z]+$/ ) ) ;
}
function isInternalLink ( text2 ) {
return Boolean ( text2 . match ( /^\[\[.+]]$/ ) ) ;
}
function smartLineBreakSplit ( text2 ) {
return text2 . split ( "\n" ) . filter ( ( x ) => x ) ;
}
function findCommonPrefix ( strs ) {
if ( strs . length === 0 ) {
return null ;
}
const min = Math . min ( ... strs . map ( ( x ) => x . length ) ) ;
for ( let i = 0 ; i < min ; i ++ ) {
if ( uniq ( strs . map ( ( x ) => x [ i ] . toLowerCase ( ) ) ) . length > 1 ) {
return strs [ 0 ] . substring ( 0 , i ) ;
}
}
return strs [ 0 ] . substring ( 0 , min ) ;
}
function microFuzzy ( value , query ) {
let i = 0 ;
let lastMatchIndex = null ;
let isFuzzy = false ;
let scoreSeed = 0 ;
let combo = 0 ;
for ( let j = 0 ; j < value . length ; j ++ ) {
if ( value [ j ] === query [ i ] ) {
if ( lastMatchIndex != null && j - lastMatchIndex > 1 ) {
isFuzzy = true ;
}
lastMatchIndex = j ;
combo ++ ;
i ++ ;
} else {
if ( combo > 0 ) {
scoreSeed += 2 * * combo ;
combo = 0 ;
}
}
if ( i === query . length ) {
if ( combo > 0 ) {
scoreSeed += 2 * * combo ;
}
return isFuzzy ? { type : "fuzzy_match" , score : scoreSeed / value . length } : { type : "concrete_match" } ;
}
}
return { type : "none" } ;
}
function joinNumberWithSymbol ( tokens ) {
if ( tokens . length === 0 ) {
return [ ] ;
}
let stock = tokens . shift ( ) ;
const ret = [ ] ;
for ( const token of tokens ) {
if ( allNumbersOrFewSymbols ( token ) && allNumbersOrFewSymbols ( stock ) ) {
stock += token ;
} else {
if ( stock ) {
ret . push ( stock ) ;
}
stock = token ;
}
}
ret . push ( stock ) ;
return ret ;
}
2026-05-06 17:32:44 +08:00
function isEOTinCodeBlock ( text2 ) {
const lines = text2 . split ( "\n" ) ;
let inCodeBlock = false ;
let codeBlockDelimiter = "" ;
let codeBlockDelimiterLength = 0 ;
for ( const line of lines ) {
const trimmedLine = line . trim ( ) ;
const codeBlockMatch = trimmedLine . match ( /^(`{3,}|~{3,})/ ) ;
if ( codeBlockMatch ) {
const delimiter = codeBlockMatch [ 1 ] ;
const delimiterChar = delimiter [ 0 ] ;
const delimiterLength = delimiter . length ;
if ( ! inCodeBlock ) {
inCodeBlock = true ;
codeBlockDelimiter = delimiterChar ;
codeBlockDelimiterLength = delimiterLength ;
} else if ( delimiterChar === codeBlockDelimiter && delimiterLength >= codeBlockDelimiterLength ) {
inCodeBlock = false ;
codeBlockDelimiter = "" ;
codeBlockDelimiterLength = 0 ;
}
}
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
return inCodeBlock ;
}
2025-08-02 12:09:34 +08:00
2026-05-06 17:32:44 +08:00
// src/app-helper.ts
var AppHelper = class {
constructor ( app ) {
this . unsafeApp = app ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
async exists ( path2 ) {
return await this . unsafeApp . vault . adapter . exists ( path2 ) ;
}
async loadFile ( path2 ) {
if ( ! await this . exists ( path2 ) ) {
throw Error ( ` The file is not found: ${ path2 } ` ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
return this . unsafeApp . vault . adapter . read ( path2 ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
async loadJson ( path2 ) {
return JSON . parse ( await this . loadFile ( path2 ) ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
async saveJson ( path2 , data ) {
await this . unsafeApp . vault . adapter . write ( path2 , JSON . stringify ( data ) ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
equalsAsEditorPosition ( one , other ) {
return one . line === other . line && one . ch === other . ch ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
getAliases ( file ) {
var _a , _b ;
return ( _b = ( 0 , import _obsidian . parseFrontMatterAliases ) (
( _a = this . unsafeApp . metadataCache . getFileCache ( file ) ) == null ? void 0 : _a . frontmatter
) ) != null ? _b : [ ] ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
getFrontMatter ( file ) {
var _a , _b , _c , _d ;
const frontMatter = ( _a = this . unsafeApp . metadataCache . getFileCache ( file ) ) == null ? void 0 : _a . frontmatter ;
if ( ! frontMatter ) {
return void 0 ;
}
const tags = ( _c = ( _b = ( 0 , import _obsidian . parseFrontMatterTags ) ( frontMatter ) ) == null ? void 0 : _b . map ( ( x ) => x . slice ( 1 ) ) ) != null ? _c : [ ] ;
const aliases = ( _d = ( 0 , import _obsidian . parseFrontMatterAliases ) ( frontMatter ) ) != null ? _d : [ ] ;
const { position , ... rest } = frontMatter ;
return {
... Object . fromEntries (
Object . entries ( rest ) . map ( ( [ k , _v ] ) => [
k ,
( 0 , import _obsidian . parseFrontMatterStringArray ) ( frontMatter , k )
] )
) ,
tags ,
tag : tags ,
aliases ,
alias : aliases
} ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
getTagsProperty ( file ) {
var _a , _b , _c ;
const frontMatter = ( _a = this . unsafeApp . metadataCache . getFileCache ( file ) ) == null ? void 0 : _a . frontmatter ;
if ( ! frontMatter ) {
return [ ] ;
}
return ( _c = ( _b = ( 0 , import _obsidian . parseFrontMatterTags ) ( frontMatter ) ) == null ? void 0 : _b . map ( ( x ) => x . slice ( 1 ) ) ) != null ? _c : [ ] ;
}
getBoolFrontMatter ( file , key ) {
var _a , _b ;
return Boolean (
( _b = ( _a = this . unsafeApp . metadataCache . getFileCache ( file ) ) == null ? void 0 : _a . frontmatter ) == null ? void 0 : _b [ key ]
) ;
}
getMarkdownViewInActiveLeaf ( ) {
if ( ! this . unsafeApp . workspace . getActiveViewOfType ( import _obsidian . MarkdownView ) ) {
return null ;
}
return this . unsafeApp . workspace . activeLeaf . view ;
}
getActiveFile ( ) {
return this . unsafeApp . workspace . getActiveFile ( ) ;
}
isActiveFile ( file ) {
var _a ;
return ( ( _a = this . getActiveFile ( ) ) == null ? void 0 : _a . path ) === file . path ;
}
getPreviousFile ( ) {
var _a ;
const fName = ( _a = this . unsafeApp . workspace . getLastOpenFiles ( ) ) == null ? void 0 : _a [ 1 ] ;
if ( ! fName ) {
return null ;
}
return this . getMarkdownFileByPath ( fName ) ;
}
getCurrentDirname ( ) {
var _a , _b , _c ;
return ( _c = ( _b = ( _a = this . getActiveFile ( ) ) == null ? void 0 : _a . parent ) == null ? void 0 : _b . path ) != null ? _c : null ;
}
getCurrentEditor ( ) {
var _a , _b ;
return ( _b = ( _a = this . getMarkdownViewInActiveLeaf ( ) ) == null ? void 0 : _a . editor ) != null ? _b : null ;
}
getSelection ( ) {
var _a ;
return ( _a = this . getCurrentEditor ( ) ) == null ? void 0 : _a . getSelection ( ) ;
}
getCurrentOffset ( editor ) {
return editor . posToOffset ( editor . getCursor ( ) ) ;
}
getContentUntilCursor ( editor ) {
return editor . getValue ( ) . slice ( 0 , this . getCurrentOffset ( editor ) ) ;
}
getCurrentLine ( editor ) {
return editor . getLine ( editor . getCursor ( ) . line ) ;
}
getCurrentLineUntilCursor ( editor ) {
return this . getCurrentLine ( editor ) . slice ( 0 , editor . getCursor ( ) . ch ) ;
}
optimizeMarkdownLinkText ( linkText ) {
var _a ;
const activeFile = this . getActiveFile ( ) ;
if ( ! activeFile ) {
return null ;
}
const path2 = this . linkText2Path ( linkText ) ;
if ( ! path2 ) {
return { displayed : linkText , link : linkText } ;
}
const file = this . getMarkdownFileByPath ( path2 ) ;
if ( ! file ) {
return null ;
}
const markdownLink = this . unsafeApp . fileManager . generateMarkdownLink (
file ,
activeFile . path
) ;
if ( markdownLink . startsWith ( "[[" ) ) {
const text2 = ( _a = markdownLink . matchAll ( /^\[\[(?<text>.+)]]$/g ) . next ( ) . value . groups ) == null ? void 0 : _a . text ;
return { displayed : text2 , link : text2 } ;
} else {
const { displayed , link } = markdownLink . matchAll ( /^\[(?<displayed>.+)]\(\<?(?<link>.+)\.md\>?\)$/g ) . next ( ) . value . groups ;
return { displayed , link } ;
}
}
linkText2Path ( linkText ) {
var _a , _b ;
const activeFile = this . getActiveFile ( ) ;
if ( ! activeFile ) {
return null ;
}
return ( _b = ( _a = this . unsafeApp . metadataCache . getFirstLinkpathDest (
linkText ,
activeFile . path
) ) == null ? void 0 : _a . path ) != null ? _b : null ;
}
inMathBlock ( editor ) {
var _a , _b ;
const numberOfDollarPair = ( _b = ( _a = this . getContentUntilCursor ( editor ) . match ( /\$\$\n/g ) ) == null ? void 0 : _a . length ) != null ? _b : 0 ;
return numberOfDollarPair % 2 !== 0 ;
}
/ * *
* WARN : This code does not support inline code blocks .
* /
inCodeBlock ( editor ) {
return isEOTinCodeBlock ( this . getContentUntilCursor ( editor ) ) ;
}
searchPhantomLinks ( ) {
return Object . entries ( this . unsafeApp . metadataCache . unresolvedLinks ) . flatMap (
( [ path2 , obj ] ) => Object . keys ( obj ) . map ( ( link ) => ( { path : path2 , link } ) )
) ;
}
getResolvedLinks ( file ) {
var _a , _b ;
return ( _b = Object . keys (
( _a = this . unsafeApp . metadataCache . resolvedLinks [ file . path ] ) != null ? _a : { }
) ) != null ? _b : [ ] ;
}
getUnresolvedLinks ( file ) {
var _a ;
const countsByLink = ( _a = this . unsafeApp . metadataCache . unresolvedLinks [ file . path ] ) != null ? _a : { } ;
return new Set ( Object . keys ( countsByLink ) ) ;
}
getMarkdownFileByPath ( path2 ) {
if ( ! path2 . endsWith ( ".md" ) ) {
return null ;
}
const abstractFile = this . unsafeApp . vault . getAbstractFileByPath ( path2 ) ;
if ( ! abstractFile ) {
return null ;
}
return abstractFile ;
}
openMarkdownFile ( file , newLeaf , offset = 0 ) {
var _a ;
const leaf = this . unsafeApp . workspace . getLeaf ( newLeaf ) ;
leaf . openFile ( file , ( _a = this . unsafeApp . workspace . activeLeaf ) == null ? void 0 : _a . getViewState ( ) ) . then ( ( ) => {
this . unsafeApp . workspace . setActiveLeaf ( leaf , true , true ) ;
const viewOfType = this . unsafeApp . workspace . getActiveViewOfType ( import _obsidian . MarkdownView ) ;
if ( viewOfType ) {
const editor = viewOfType . editor ;
const pos = editor . offsetToPos ( offset ) ;
editor . setCursor ( pos ) ;
editor . scrollIntoView ( { from : pos , to : pos } , true ) ;
}
} ) ;
}
getCurrentFrontMatter ( ) {
var _a , _b ;
const editor = this . getCurrentEditor ( ) ;
if ( ! editor ) {
return null ;
}
if ( ! this . getActiveFile ( ) ) {
return null ;
}
if ( editor . getLine ( 0 ) !== "---" ) {
return null ;
}
const endPosition = editor . getValue ( ) . indexOf ( "---" , 3 ) ;
const currentOffset = this . getCurrentOffset ( editor ) ;
if ( endPosition !== - 1 && currentOffset >= endPosition ) {
return null ;
}
const keyLocations = Array . from (
editor . getValue ( ) . matchAll ( /\s*['"]?(?<key>.+?)['"]?:/g )
) ;
if ( keyLocations . length === 0 ) {
return null ;
}
const currentKeyLocation = keyLocations . filter ( ( x ) => x . index < currentOffset ) . last ( ) ;
if ( ! currentKeyLocation ) {
return null ;
}
return ( _b = ( _a = currentKeyLocation . groups ) == null ? void 0 : _a . key ) != null ? _b : null ;
}
/ * *
* Unsafe method
* /
isIMEOn ( ) {
var _a , _b , _c ;
if ( ! this . unsafeApp . workspace . getActiveViewOfType ( import _obsidian . MarkdownView ) ) {
return false ;
}
const markdownView = this . unsafeApp . workspace . activeLeaf . view ;
const cm5or6 = markdownView . editor . cm ;
if ( ( ( _a = cm5or6 == null ? void 0 : cm5or6 . inputState ) == null ? void 0 : _a . composing ) > 0 ) {
return true ;
}
return ! ! ( ( _c = ( _b = cm5or6 == null ? void 0 : cm5or6 . display ) == null ? void 0 : _b . input ) == null ? void 0 : _c . composing ) ;
}
/ * *
* Unsafe method
* /
getVisibleLineRange ( ) {
var _a ;
const markdownView = this . unsafeApp . workspace . getActiveViewOfType ( import _obsidian . MarkdownView ) ;
if ( ! markdownView ) {
return null ;
}
const cm = markdownView . editor . cm ;
if ( ! ( cm == null ? void 0 : cm . visibleRanges ) || ! ( ( _a = cm == null ? void 0 : cm . state ) == null ? void 0 : _a . doc ) ) {
return null ;
}
const visibleRanges = cm . visibleRanges ;
if ( visibleRanges . length === 0 ) {
return null ;
}
const first = visibleRanges [ 0 ] ;
const last = visibleRanges [ visibleRanges . length - 1 ] ;
const fromLine = cm . state . doc . lineAt ( first . from ) . number - 1 ;
const toLine = cm . state . doc . lineAt ( last . to ) . number - 1 ;
return { from : fromLine , to : toLine } ;
}
isMobile ( ) {
return this . unsafeApp . isMobile ;
}
async writeLog ( log ) {
await this . unsafeApp . vault . adapter . append ( ( 0 , import _obsidian . normalizePath ) ( "log.md" ) , log ) ;
}
get useWikiLinks ( ) {
return ! this . unsafeApp . vault . config . useMarkdownLinks ;
}
get newLinkFormat ( ) {
var _a ;
return ( _a = this . unsafeApp . vault . config . newLinkFormat ) != null ? _a : "shortest" ;
}
} ;
// src/setting/settings.ts
var import _obsidian3 = require ( "obsidian" ) ;
// src/composables/settings/useFilterSetting.ts
var useFilterSetting = ( group ) => {
const filterTargets = [ ] ;
let latestQuery = "" ;
const applyFilter = ( query ) => {
latestQuery = query ;
const normalizedQuery = query . trim ( ) . toLowerCase ( ) ;
const shouldShowAll = normalizedQuery . length === 0 ;
for ( const target of filterTargets ) {
const searchText = target . getSearchText ( ) . toLowerCase ( ) ;
const isMatch = shouldShowAll || searchText . includes ( normalizedQuery ) ;
target . settingEl . toggle ( isMatch ) ;
}
2025-08-02 12:09:34 +08:00
} ;
2026-05-06 17:32:44 +08:00
const addFilterTarget = ( element2 , getSearchText ) => {
filterTargets . push ( { settingEl : element2 , getSearchText } ) ;
applyFilter ( latestQuery ) ;
2025-08-02 12:09:34 +08:00
} ;
2026-05-06 17:32:44 +08:00
const addFilterableSetting = ( name , desc , build ) => {
const searchText = name . trim ( ) ;
group . addSetting ( ( setting ) => {
setting . setName ( name ) ;
if ( desc ) {
setting . setDesc ( desc ) ;
}
build ( setting ) ;
addFilterTarget ( setting . settingEl , ( ) => searchText ) ;
} ) ;
2025-08-02 12:09:34 +08:00
} ;
2026-05-06 17:32:44 +08:00
group . addSearch ( ( sc ) => {
sc . setPlaceholder ( "Filter settings" ) . onChange ( ( value ) => {
applyFilter ( value ) ;
} ) ;
} ) ;
return { addFilterableSetting } ;
} ;
// src/keys.ts
var import _obsidian2 = require ( "obsidian" ) ;
var MOD = import _obsidian2 . Platform . isMacOS ? "Cmd" : "Ctrl" ;
var ALT = import _obsidian2 . Platform . isMacOS ? "Option" : "Alt" ;
function hotkey2String ( hk ) {
if ( ! hk ) {
return "" ;
}
const hotkey = hk . key === " " ? "Space" : hk . key ;
const mods = hk . modifiers . join ( " " ) ;
return mods ? ` ${ mods } ${ hotkey } ` : hotkey ;
}
function string2Hotkey ( hotKey , hideHotkeyGuide ) {
const keys = hotKey . split ( " " ) ;
if ( keys . length === 0 || keys [ 0 ] === "" ) {
return null ;
}
if ( keys . length === 1 ) {
return {
modifiers : [ ] ,
key : keys [ 0 ] . replace ( "Space" , " " ) ,
hideHotkeyGuide
} ;
}
return {
modifiers : keys . slice ( 0 , - 1 ) ,
key : keys . last ( ) . replace ( "Space" , " " ) ,
hideHotkeyGuide
2025-08-02 12:09:34 +08:00
} ;
2026-05-06 17:32:44 +08:00
}
// src/option/ColumnDelimiter.ts
var _ColumnDelimiter = class _ColumnDelimiter {
constructor ( name , value ) {
this . name = name ;
this . value = value ;
_ColumnDelimiter . _values . push ( this ) ;
}
static fromName ( name ) {
return _ColumnDelimiter . _values . find ( ( x ) => x . name === name ) ;
}
static values ( ) {
return _ColumnDelimiter . _values ;
}
} ;
_ColumnDelimiter . _values = [ ] ;
_ColumnDelimiter . TAB = new _ColumnDelimiter ( "Tab" , " " ) ;
_ColumnDelimiter . COMMA = new _ColumnDelimiter ( "Comma" , "," ) ;
_ColumnDelimiter . PIPE = new _ColumnDelimiter ( "Pipe" , "|" ) ;
var ColumnDelimiter = _ColumnDelimiter ;
// src/util/path.ts
function basename ( path2 , ext2 ) {
var _a , _b ;
const name = ( _b = ( _a = path2 . match ( /.+[\\/]([^\\/]+)[\\/]?$/ ) ) == null ? void 0 : _a [ 1 ] ) != null ? _b : path2 ;
return ext2 && name . endsWith ( ext2 ) ? name . replace ( ext2 , "" ) : name ;
}
function dirname ( path2 ) {
var _a , _b ;
return ( _b = ( _a = path2 . match ( /(.+)[\\/].+$/ ) ) == null ? void 0 : _a [ 1 ] ) != null ? _b : "." ;
}
function isURL ( path2 ) {
return Boolean ( path2 . match ( new RegExp ( "^https?://" ) ) ) ;
}
var DEFAULT _HISTORIES _PATH = ".obsidian/plugins/various-complements/histories.json" ;
// src/option/DescriptionOnSuggestion.ts
var _DescriptionOnSuggestion = class _DescriptionOnSuggestion {
constructor ( name , toDisplay ) {
this . name = name ;
this . toDisplay = toDisplay ;
_DescriptionOnSuggestion . _values . push ( this ) ;
}
static fromName ( name ) {
return _DescriptionOnSuggestion . _values . find ( ( x ) => x . name === name ) ;
}
static values ( ) {
return _DescriptionOnSuggestion . _values ;
}
} ;
_DescriptionOnSuggestion . _values = [ ] ;
_DescriptionOnSuggestion . NONE = new _DescriptionOnSuggestion ( "None" , ( ) => null ) ;
_DescriptionOnSuggestion . SHORT = new _DescriptionOnSuggestion ( "Short" , ( word ) => {
if ( ! word . description ) {
return null ;
}
return word . type === "customDictionary" ? word . description : basename ( word . description ) ;
} ) ;
_DescriptionOnSuggestion . FULL = new _DescriptionOnSuggestion (
"Full" ,
( word ) => {
var _a ;
return ( _a = word . description ) != null ? _a : null ;
}
) ;
var DescriptionOnSuggestion = _DescriptionOnSuggestion ;
// src/model/Word.ts
var _WordTypeMeta = class _WordTypeMeta {
constructor ( type , priority , group ) {
this . type = type ;
this . priority = priority ;
this . group = group ;
_WordTypeMeta . _values . push ( this ) ;
_WordTypeMeta . _dict [ type ] = this ;
}
static of ( type ) {
return _WordTypeMeta . _dict [ type ] ;
}
static values ( ) {
return _WordTypeMeta . _values ;
}
} ;
_WordTypeMeta . _values = [ ] ;
_WordTypeMeta . _dict = { } ;
_WordTypeMeta . FRONT _MATTER = new _WordTypeMeta (
"frontMatter" ,
100 ,
"frontMatter"
) ;
_WordTypeMeta . INTERNAL _LINK = new _WordTypeMeta (
"internalLink" ,
90 ,
"internalLink"
) ;
_WordTypeMeta . CUSTOM _DICTIONARY = new _WordTypeMeta (
"customDictionary" ,
80 ,
"suggestion"
) ;
_WordTypeMeta . CURRENT _FILE = new _WordTypeMeta (
"currentFile" ,
70 ,
"suggestion"
) ;
_WordTypeMeta . CURRENT _VAULT = new _WordTypeMeta (
"currentVault" ,
60 ,
"suggestion"
) ;
var WordTypeMeta = _WordTypeMeta ;
// src/provider/suggester.ts
function suggestionUniqPredicate ( a , b ) {
if ( a . value !== b . value ) {
return false ;
}
if ( WordTypeMeta . of ( a . type ) . group !== WordTypeMeta . of ( b . type ) . group ) {
return false ;
}
if ( a . type === "internalLink" && ! a . phantom && a . createdPath !== b . createdPath ) {
return false ;
}
return true ;
}
function pushWord ( wordsByFirstLetter , key , word ) {
if ( wordsByFirstLetter [ key ] === void 0 ) {
wordsByFirstLetter [ key ] = [ word ] ;
return ;
}
wordsByFirstLetter [ key ] . push ( word ) ;
}
function judge ( word , query , queryStartWithUpper , options ) {
var _a , _b , _c ;
if ( query === "" ) {
return {
word : {
... word ,
hit : word . value
} ,
value : word . value ,
alias : false
} ;
}
const matcher = ( options == null ? void 0 : options . fuzzy ) ? lowerFuzzy : wrapFuzzy ( lowerStartsWith ) ;
const matched = matcher ( word . value , query ) ;
if ( matched . type === "concrete_match" || matched . type === "fuzzy_match" && matched . score > ( ( _a = options == null ? void 0 : options . fuzzy ) == null ? void 0 : _a . minMatchScore ) ) {
if ( queryStartWithUpper && word . type !== "internalLink" && word . type !== "frontMatter" ) {
const c = capitalizeFirstLetter ( word . value ) ;
return {
word : {
... word ,
value : c ,
hit : c ,
fuzzy : matched . type === "fuzzy_match" ,
query
} ,
value : c ,
alias : false
} ;
} else {
return {
word : {
... word ,
hit : word . value ,
fuzzy : matched . type === "fuzzy_match" ,
query
} ,
value : word . value ,
alias : false
} ;
}
}
const matchedAlias = ( _b = word . aliases ) == null ? void 0 : _b . map ( ( a ) => ( { aliases : a , matched : matcher ( a , query ) } ) ) . sort (
( a , b ) => a . matched . type === "concrete_match" && b . matched . type !== "concrete_match" ? - 1 : 0
) . find ( ( x ) => x . matched . type !== "none" ) ;
if ( matchedAlias && ( matchedAlias . matched . type === "concrete_match" || matchedAlias . matched . type === "fuzzy_match" && matchedAlias . matched . score > ( ( _c = options == null ? void 0 : options . fuzzy ) == null ? void 0 : _c . minMatchScore ) ) ) {
return {
word : {
... word ,
hit : matchedAlias . aliases ,
fuzzy : matchedAlias . matched . type === "fuzzy_match" ,
query
} ,
value : matchedAlias . aliases ,
alias : true
} ;
}
return {
word ,
alias : false
2025-08-02 12:09:34 +08:00
} ;
2026-05-06 17:32:44 +08:00
}
function suggestWords ( indexedWords , query , maxNum , option = { } ) {
var _a , _b , _c , _d , _e , _f , _g , _h , _i , _j , _k , _l , _m , _n , _o , _p ;
const {
frontMatter ,
selectionHistoryStorage ,
providerMinChars ,
globalMinChar
} = option ;
const queryStartWithUpper = capitalizeFirstLetter ( query ) === query ;
const shouldIncludeProvider = ( providerType ) => {
if ( ! providerMinChars ) {
return true ;
}
const minChars = providerMinChars [ providerType ] || globalMinChar || 0 ;
return query . length >= minChars ;
2025-08-02 12:09:34 +08:00
} ;
2026-05-06 17:32:44 +08:00
const flattenFrontMatterWords = ( ) => {
var _a2 , _b2 ;
if ( frontMatter === "alias" || frontMatter === "aliases" ) {
return [ ] ;
}
if ( frontMatter && ( ( _a2 = indexedWords . frontMatter ) == null ? void 0 : _a2 [ frontMatter ] ) ) {
return Object . values ( ( _b2 = indexedWords . frontMatter ) == null ? void 0 : _b2 [ frontMatter ] ) . flat ( ) ;
}
return [ ] ;
2025-08-02 12:09:34 +08:00
} ;
2026-05-06 17:32:44 +08:00
const words = queryStartWithUpper ? frontMatter ? flattenFrontMatterWords ( ) : [
... shouldIncludeProvider ( "currentFile" ) ? ( _a = indexedWords . currentFile [ query . charAt ( 0 ) ] ) != null ? _a : [ ] : [ ] ,
... shouldIncludeProvider ( "currentFile" ) ? ( _b = indexedWords . currentFile [ query . charAt ( 0 ) . toLowerCase ( ) ] ) != null ? _b : [ ] : [ ] ,
... shouldIncludeProvider ( "currentVault" ) ? ( _c = indexedWords . currentVault [ query . charAt ( 0 ) ] ) != null ? _c : [ ] : [ ] ,
... shouldIncludeProvider ( "currentVault" ) ? ( _d = indexedWords . currentVault [ query . charAt ( 0 ) . toLowerCase ( ) ] ) != null ? _d : [ ] : [ ] ,
... shouldIncludeProvider ( "customDictionary" ) ? ( _e = indexedWords . customDictionary [ query . charAt ( 0 ) ] ) != null ? _e : [ ] : [ ] ,
... shouldIncludeProvider ( "customDictionary" ) ? ( _f = indexedWords . customDictionary [ query . charAt ( 0 ) . toLowerCase ( ) ] ) != null ? _f : [ ] : [ ] ,
... shouldIncludeProvider ( "internalLink" ) ? ( _g = indexedWords . internalLink [ query . charAt ( 0 ) ] ) != null ? _g : [ ] : [ ] ,
... shouldIncludeProvider ( "internalLink" ) ? ( _h = indexedWords . internalLink [ query . charAt ( 0 ) . toLowerCase ( ) ] ) != null ? _h : [ ] : [ ]
] : frontMatter ? flattenFrontMatterWords ( ) : [
... shouldIncludeProvider ( "currentFile" ) ? ( _i = indexedWords . currentFile [ query . charAt ( 0 ) ] ) != null ? _i : [ ] : [ ] ,
... shouldIncludeProvider ( "currentFile" ) ? ( _j = indexedWords . currentFile [ query . charAt ( 0 ) . toUpperCase ( ) ] ) != null ? _j : [ ] : [ ] ,
... shouldIncludeProvider ( "currentVault" ) ? ( _k = indexedWords . currentVault [ query . charAt ( 0 ) ] ) != null ? _k : [ ] : [ ] ,
... shouldIncludeProvider ( "currentVault" ) ? ( _l = indexedWords . currentVault [ query . charAt ( 0 ) . toUpperCase ( ) ] ) != null ? _l : [ ] : [ ] ,
... shouldIncludeProvider ( "customDictionary" ) ? ( _m = indexedWords . customDictionary [ query . charAt ( 0 ) ] ) != null ? _m : [ ] : [ ] ,
... shouldIncludeProvider ( "customDictionary" ) ? ( _n = indexedWords . customDictionary [ query . charAt ( 0 ) . toUpperCase ( ) ] ) != null ? _n : [ ] : [ ] ,
... shouldIncludeProvider ( "internalLink" ) ? ( _o = indexedWords . internalLink [ query . charAt ( 0 ) ] ) != null ? _o : [ ] : [ ] ,
... shouldIncludeProvider ( "internalLink" ) ? ( _p = indexedWords . internalLink [ query . charAt ( 0 ) . toUpperCase ( ) ] ) != null ? _p : [ ] : [ ]
] ;
const filteredJudgement = Array . from ( words ) . map ( ( x ) => judge ( x , query , queryStartWithUpper , option ) ) . filter ( ( x ) => x . value !== void 0 ) ;
const latestUpdated = max (
filteredJudgement . map (
( x ) => {
var _a2 , _b2 ;
return ( _b2 = ( _a2 = selectionHistoryStorage == null ? void 0 : selectionHistoryStorage . getSelectionHistory ( x . word ) ) == null ? void 0 : _a2 . lastUpdated ) != null ? _b2 : 0 ;
}
) ,
0
) ;
const candidate = filteredJudgement . sort ( ( a , b ) => {
const aWord = a . word ;
const bWord = b . word ;
if ( a . word . fuzzy !== b . word . fuzzy ) {
return a . word . fuzzy ? 1 : - 1 ;
}
const notSameWordType = aWord . type !== bWord . type ;
if ( frontMatter && notSameWordType ) {
return bWord . type === "frontMatter" ? 1 : - 1 ;
}
if ( selectionHistoryStorage ) {
const ret = selectionHistoryStorage . compare (
aWord ,
bWord ,
latestUpdated
) ;
if ( ret !== 0 ) {
return ret ;
}
}
if ( a . value . length !== b . value . length ) {
return a . value . length > b . value . length ? 1 : - 1 ;
}
if ( notSameWordType ) {
return WordTypeMeta . of ( bWord . type ) . priority > WordTypeMeta . of ( aWord . type ) . priority ? 1 : - 1 ;
}
if ( a . alias !== b . alias ) {
return a . alias ? 1 : - 1 ;
}
return 0 ;
} ) . map ( ( x ) => x . word ) . slice ( 0 , maxNum ) ;
return uniqWith ( candidate , suggestionUniqPredicate ) ;
}
function judgeByPartialMatch ( word , query , queryStartWithUpper , options ) {
var _a , _b , _c , _d , _e , _f ;
if ( query === "" ) {
return {
word : { ... word , hit : word . value } ,
value : word . value ,
alias : false
} ;
}
const startsWithMatcher = ( options == null ? void 0 : options . fuzzy ) ? lowerFuzzyStarsWith : wrapFuzzy ( lowerStartsWith ) ;
const includesMatcher = ( options == null ? void 0 : options . fuzzy ) ? lowerFuzzy : wrapFuzzy ( lowerIncludes ) ;
const startsWithMatched = startsWithMatcher ( word . value , query ) ;
if ( startsWithMatched . type === "concrete_match" || startsWithMatched . type === "fuzzy_match" && startsWithMatched . score > ( ( _a = options == null ? void 0 : options . fuzzy ) == null ? void 0 : _a . minMatchScore ) ) {
if ( queryStartWithUpper && word . type !== "internalLink" && word . type !== "frontMatter" ) {
const c = capitalizeFirstLetter ( word . value ) ;
return {
word : {
... word ,
value : c ,
hit : c ,
fuzzy : startsWithMatched . type === "fuzzy_match" ,
query
} ,
value : c ,
alias : false
} ;
} else {
return {
word : {
... word ,
hit : word . value ,
fuzzy : startsWithMatched . type === "fuzzy_match" ,
query
} ,
value : word . value ,
alias : false
} ;
}
}
const startsWithAliasMatched = ( _b = word . aliases ) == null ? void 0 : _b . map ( ( a ) => ( { aliases : a , matched : startsWithMatcher ( a , query ) } ) ) . sort (
( a , b ) => a . matched . type === "concrete_match" && b . matched . type !== "concrete_match" ? - 1 : 0
) . find ( ( x ) => x . matched . type !== "none" ) ;
if ( startsWithAliasMatched && ( startsWithAliasMatched . matched . type === "concrete_match" || startsWithAliasMatched . matched . type === "fuzzy_match" && startsWithAliasMatched . matched . score > ( ( _c = options == null ? void 0 : options . fuzzy ) == null ? void 0 : _c . minMatchScore ) ) ) {
return {
word : {
... word ,
hit : startsWithAliasMatched . aliases ,
fuzzy : startsWithAliasMatched . matched . type === "fuzzy_match" ,
query
} ,
value : startsWithAliasMatched . aliases ,
alias : true
} ;
}
const includesMatched = includesMatcher ( word . value , query ) ;
if ( includesMatched && ( includesMatched . type === "concrete_match" || includesMatched . type === "fuzzy_match" && includesMatched . score > ( ( _d = options == null ? void 0 : options . fuzzy ) == null ? void 0 : _d . minMatchScore ) ) ) {
return {
word : {
... word ,
hit : word . value ,
fuzzy : includesMatched . type === "fuzzy_match" ,
query
} ,
value : word . value ,
alias : false
} ;
}
const matchedAliasIncluded = ( _e = word . aliases ) == null ? void 0 : _e . map ( ( a ) => ( { aliases : a , matched : includesMatcher ( a , query ) } ) ) . sort (
( a , b ) => a . matched . type === "concrete_match" && b . matched . type !== "concrete_match" ? - 1 : 0
) . find ( ( x ) => x . matched . type !== "none" ) ;
if ( matchedAliasIncluded && ( matchedAliasIncluded . matched . type === "concrete_match" || matchedAliasIncluded . matched . type === "fuzzy_match" && matchedAliasIncluded . matched . score > ( ( _f = options == null ? void 0 : options . fuzzy ) == null ? void 0 : _f . minMatchScore ) ) ) {
return {
word : {
... word ,
hit : matchedAliasIncluded . aliases ,
fuzzy : matchedAliasIncluded . matched . type === "fuzzy_match" ,
query
} ,
value : matchedAliasIncluded . aliases ,
alias : true
} ;
}
return { word , alias : false } ;
}
function suggestWordsByPartialMatch ( indexedWords , query , maxNum , option = { } ) {
const {
frontMatter ,
selectionHistoryStorage ,
providerMinChars ,
globalMinChar
} = option ;
const queryStartWithUpper = capitalizeFirstLetter ( query ) === query ;
const shouldIncludeProvider = ( providerType ) => {
if ( ! providerMinChars ) {
return true ;
}
const minChars = providerMinChars [ providerType ] || globalMinChar || 0 ;
return query . length >= minChars ;
2025-08-02 12:09:34 +08:00
} ;
2026-05-06 17:32:44 +08:00
const flatObjectValues = ( object ) => Object . values ( object ) . flat ( ) ;
const flattenFrontMatterWords = ( ) => {
var _a , _b ;
if ( frontMatter === "alias" || frontMatter === "aliases" ) {
return [ ] ;
}
if ( frontMatter && ( ( _a = indexedWords . frontMatter ) == null ? void 0 : _a [ frontMatter ] ) ) {
return Object . values ( ( _b = indexedWords . frontMatter ) == null ? void 0 : _b [ frontMatter ] ) . flat ( ) ;
}
return [ ] ;
2025-08-02 12:09:34 +08:00
} ;
const words = frontMatter ? flattenFrontMatterWords ( ) : [
2026-05-06 17:32:44 +08:00
... shouldIncludeProvider ( "currentFile" ) ? flatObjectValues ( indexedWords . currentFile ) : [ ] ,
... shouldIncludeProvider ( "currentVault" ) ? flatObjectValues ( indexedWords . currentVault ) : [ ] ,
... shouldIncludeProvider ( "customDictionary" ) ? flatObjectValues ( indexedWords . customDictionary ) : [ ] ,
... shouldIncludeProvider ( "internalLink" ) ? flatObjectValues ( indexedWords . internalLink ) : [ ]
2025-08-02 12:09:34 +08:00
] ;
const filteredJudgement = Array . from ( words ) . map ( ( x ) => judgeByPartialMatch ( x , query , queryStartWithUpper , option ) ) . filter ( ( x ) => x . value !== void 0 ) ;
const latestUpdated = max (
filteredJudgement . map (
( x ) => {
var _a , _b ;
return ( _b = ( _a = selectionHistoryStorage == null ? void 0 : selectionHistoryStorage . getSelectionHistory ( x . word ) ) == null ? void 0 : _a . lastUpdated ) != null ? _b : 0 ;
}
) ,
0
) ;
const candidate = filteredJudgement . sort ( ( a , b ) => {
const aWord = a . word ;
const bWord = b . word ;
if ( a . word . fuzzy !== b . word . fuzzy ) {
return a . word . fuzzy ? 1 : - 1 ;
}
const notSameWordType = aWord . type !== bWord . type ;
if ( frontMatter && notSameWordType ) {
return bWord . type === "frontMatter" ? 1 : - 1 ;
}
if ( selectionHistoryStorage ) {
const ret = selectionHistoryStorage . compare (
aWord ,
bWord ,
latestUpdated
) ;
if ( ret !== 0 ) {
return ret ;
}
}
const as = lowerStartsWith ( a . value , query ) ;
const bs = lowerStartsWith ( b . value , query ) ;
if ( as !== bs ) {
return bs ? 1 : - 1 ;
}
if ( a . value . length !== b . value . length ) {
return a . value . length > b . value . length ? 1 : - 1 ;
}
2026-05-06 17:32:44 +08:00
if ( notSameWordType ) {
return WordTypeMeta . of ( bWord . type ) . priority > WordTypeMeta . of ( aWord . type ) . priority ? 1 : - 1 ;
}
if ( a . alias !== b . alias ) {
return a . alias ? 1 : - 1 ;
}
return 0 ;
} ) . map ( ( x ) => x . word ) . slice ( 0 , maxNum ) ;
return uniqWith ( candidate , suggestionUniqPredicate ) ;
}
// src/provider/MatchStrategy.ts
var _MatchStrategy = class _MatchStrategy {
constructor ( name , handler ) {
this . name = name ;
this . handler = handler ;
_MatchStrategy . _values . push ( this ) ;
}
static fromName ( name ) {
return _MatchStrategy . _values . find ( ( x ) => x . name === name ) ;
}
static values ( ) {
return _MatchStrategy . _values ;
}
} ;
_MatchStrategy . _values = [ ] ;
_MatchStrategy . PREFIX = new _MatchStrategy ( "prefix" , suggestWords ) ;
_MatchStrategy . PARTIAL = new _MatchStrategy (
"partial" ,
suggestWordsByPartialMatch
) ;
var MatchStrategy = _MatchStrategy ;
// src/provider/SpecificMatchStrategy.ts
var neverUsedHandler = ( ... _args ) => [ ] ;
var _SpecificMatchStrategy = class _SpecificMatchStrategy {
constructor ( name , handler ) {
this . name = name ;
this . handler = handler ;
_SpecificMatchStrategy . _values . push ( this ) ;
}
static fromName ( name ) {
return _SpecificMatchStrategy . _values . find ( ( x ) => x . name === name ) ;
}
static values ( ) {
return _SpecificMatchStrategy . _values ;
}
} ;
_SpecificMatchStrategy . _values = [ ] ;
_SpecificMatchStrategy . INHERIT = new _SpecificMatchStrategy (
"inherit" ,
neverUsedHandler
) ;
_SpecificMatchStrategy . PREFIX = new _SpecificMatchStrategy ( "prefix" , suggestWords ) ;
_SpecificMatchStrategy . PARTIAL = new _SpecificMatchStrategy (
"partial" ,
suggestWordsByPartialMatch
) ;
var SpecificMatchStrategy = _SpecificMatchStrategy ;
// src/tokenizer/TokenizeStrategy.ts
var _TokenizeStrategy = class _TokenizeStrategy {
constructor ( name , triggerThreshold , indexingThreshold , canTreatUnderscoreAsPartOfWord ) {
this . name = name ;
this . triggerThreshold = triggerThreshold ;
this . indexingThreshold = indexingThreshold ;
this . canTreatUnderscoreAsPartOfWord = canTreatUnderscoreAsPartOfWord ;
_TokenizeStrategy . _values . push ( this ) ;
}
static fromName ( name ) {
return _TokenizeStrategy . _values . find ( ( x ) => x . name === name ) ;
}
static values ( ) {
return _TokenizeStrategy . _values ;
}
} ;
_TokenizeStrategy . _values = [ ] ;
_TokenizeStrategy . DEFAULT = new _TokenizeStrategy ( "default" , 3 , 5 , true ) ;
_TokenizeStrategy . ENGLISH _ONLY = new _TokenizeStrategy (
"english-only" ,
3 ,
5 ,
true
) ;
_TokenizeStrategy . JAPANESE = new _TokenizeStrategy ( "japanese" , 2 , 2 , false ) ;
_TokenizeStrategy . ARABIC = new _TokenizeStrategy ( "arabic" , 3 , 3 , false ) ;
_TokenizeStrategy . CHINESE = new _TokenizeStrategy ( "chinese" , 1 , 2 , false ) ;
_TokenizeStrategy . KOREAN = new _TokenizeStrategy ( "korean" , 1 , 2 , true ) ;
var TokenizeStrategy = _TokenizeStrategy ;
// src/types.ts
function isPresent ( arg ) {
return arg != null ;
}
// src/setting/settings-helper.ts
var TextComponentEvent ;
( ( TextComponentEvent2 ) => {
function onChange ( component , handler , option ) {
component . inputEl . addEventListener ( "change" , async ( ev ) => {
if ( ! ( ev . target instanceof HTMLInputElement ) ) {
return ;
}
handler ( ev . target . value ) ;
} ) ;
if ( option == null ? void 0 : option . className ) {
component . inputEl . className = option . className ;
}
return component ;
}
TextComponentEvent2 . onChange = onChange ;
} ) ( TextComponentEvent || ( TextComponentEvent = { } ) ) ;
// src/setting/settings.ts
var DEFAULT _SETTINGS = {
// general
strategy : "default" ,
cedictPath : "./cedict_ts.u8" ,
matchStrategy : "prefix" ,
fuzzyMatch : true ,
minFuzzyMatchScore : 0.5 ,
matchingWithoutEmoji : true ,
treatAccentDiacriticsAsAlphabeticCharacters : false ,
treatUnderscoreAsPartOfWord : false ,
maxNumberOfSuggestions : 5 ,
maxNumberOfWordsAsPhrase : 3 ,
minNumberOfCharactersTriggered : 0 ,
minNumberOfWordsTriggeredPhrase : 1 ,
complementAutomatically : true ,
delayMilliSeconds : 0 ,
disableSuggestionsDuringImeOn : false ,
disableSuggestionsInMathBlock : false ,
disableSuggestionsInCodeBlock : false ,
insertSpaceAfterCompletion : false ,
firstCharactersDisableSuggestions : ":/^" ,
patternsToSuppressTrigger : [ "^~~~.*" , "^```.*" ] ,
phrasePatternsToSuppressTrigger : [ ] ,
noAutoFocusUntilCycle : false ,
// appearance
showMatchStrategy : false ,
showComplementAutomatically : false ,
showIndexingStatus : false ,
descriptionOnSuggestion : "Short" ,
// key customization
hotkeys : {
select : [ { modifiers : [ ] , key : "Enter" } ] ,
"select with custom alias" : [ ] ,
"select with custom alias and add to aliases" : [ ] ,
"select with query alias" : [ ] ,
up : [ { modifiers : [ ] , key : "ArrowUp" } ] ,
down : [ { modifiers : [ ] , key : "ArrowDown" } ] ,
"select 1st" : [ ] ,
"select 2nd" : [ ] ,
"select 3rd" : [ ] ,
"select 4th" : [ ] ,
"select 5th" : [ ] ,
"select 6th" : [ ] ,
"select 7th" : [ ] ,
"select 8th" : [ ] ,
"select 9th" : [ ] ,
open : [ ] ,
completion : [ ] ,
"insert as text" : [ ]
} ,
propagateEsc : false ,
// current file complement
enableCurrentFileComplement : true ,
currentFileMinNumberOfCharacters : 0 ,
onlyComplementEnglishOnCurrentFileComplement : false ,
excludeCurrentFileWordPatterns : [ ] ,
// current vault complement
enableCurrentVaultComplement : false ,
currentVaultMinNumberOfCharacters : 0 ,
includeCurrentVaultPathPrefixPatterns : "" ,
excludeCurrentVaultPathPrefixPatterns : "" ,
excludeCurrentVaultPathGlobPatterns : [ ] ,
includeCurrentVaultOnlyFilesUnderCurrentDirectory : false ,
excludeCurrentVaultWordPatterns : [ ] ,
// custom dictionary complement
enableCustomDictionaryComplement : false ,
customDictionaryPaths : ` https://raw.githubusercontent.com/first20hours/google-10000-english/master/google-10000-english-no-swears.txt ` ,
columnDelimiter : "Tab" ,
customDictionaryWordRegexPattern : "" ,
delimiterToHideSuggestion : "" ,
delimiterToDivideSuggestionsForDisplayFromInsertion : "" ,
caretLocationSymbolAfterComplement : "" ,
displayedTextSuffix : " => ..." ,
// internal link complement
enableInternalLinkComplement : true ,
suggestInternalLinkWithAlias : false ,
preserveFirstLetterCaseOnInternalLink : false ,
excludeInternalLinkPathPrefixPatterns : "" ,
excludeInternalLinkPathGlobPatterns : [ ] ,
excludeSelfInternalLink : false ,
excludeExistingInActiveFileInternalLinks : false ,
excludeUnresolvedInternalLinks : false ,
updateInternalLinksOnSave : true ,
insertAliasTransformedFromDisplayedInternalLink : {
enabled : false ,
beforeRegExp : "" ,
after : ""
} ,
frontMatterKeyForExclusionInternalLink : "" ,
tagsForExclusionInternalLink : [ ] ,
// front matter complement
enableFrontMatterComplement : false ,
frontMatterComplementMatchStrategy : "inherit" ,
insertCommaAfterFrontMatterCompletion : false ,
// provider-specific trigger settings
currentFileMinNumberOfCharactersForTrigger : 0 ,
currentVaultMinNumberOfCharactersForTrigger : 0 ,
customDictionaryMinNumberOfCharactersForTrigger : 0 ,
internalLinkMinNumberOfCharactersForTrigger : 0 ,
intelligentSuggestionPrioritization : {
enabled : true ,
historyFilePath : "" ,
maxDaysToKeepHistory : 30 ,
maxNumberOfHistoryToKeep : 0
} ,
// mobile
disableOnMobile : false ,
// debug
showLogAboutPerformanceInConsole : false
} ;
var VariousComplementsSettingTab = class extends import _obsidian3 . PluginSettingTab {
constructor ( app , plugin ) {
super ( app , plugin ) ;
this . plugin = plugin ;
}
async display ( ) {
let { containerEl } = this ;
containerEl . empty ( ) ;
containerEl . createEl ( "h2" , { text : "Various Complements - Settings" } ) ;
await this . addMainSettings ( containerEl ) ;
this . addAppearanceSettings ( containerEl ) ;
this . addKeyCustomizationSettings ( containerEl ) ;
this . addCurrentFileComplementSettings ( containerEl ) ;
this . addCurrentVaultComplementSettings ( containerEl ) ;
this . addCustomDictionaryComplementSettings ( containerEl ) ;
this . addInternalLinkComplementSettings ( containerEl ) ;
this . addFrontMatterComplementSettings ( containerEl ) ;
this . addIntelligentSuggestionPrioritizationSettings ( containerEl ) ;
this . addMobileSettings ( containerEl ) ;
this . addDebugSettings ( containerEl ) ;
}
async addMainSettings ( containerEl ) {
containerEl . createEl ( "h3" , {
text : "Main" ,
cls : "various-complements__settings__header various-complements__settings__header__main"
} ) ;
const group = new import _obsidian3 . SettingGroup ( containerEl ) ;
const { addFilterableSetting } = useFilterSetting ( group ) ;
addFilterableSetting ( "Strategy" , null , ( setting ) => {
setting . addDropdown (
( tc ) => tc . addOptions ( mirrorMap ( TokenizeStrategy . values ( ) , ( x ) => x . name ) ) . setValue ( this . plugin . settings . strategy ) . onChange ( async ( value ) => {
this . plugin . settings . strategy = value ;
this . display ( ) ;
await this . plugin . saveSettings ( {
currentFile : true ,
currentVault : true
} ) ;
} )
) ;
} ) ;
if ( this . plugin . settings . strategy === TokenizeStrategy . CHINESE . name ) {
const df = document . createDocumentFragment ( ) ;
df . append (
createSpan ( {
text : "The path to `cedict_ts.u8`. You can download it from "
} ) ,
createEl ( "a" , {
href : "https://www.mdbg.net/chinese/dictionary?page=cc-cedict" ,
text : " the site "
} )
) ;
addFilterableSetting ( "CC-CEDICT path" , df , ( setting ) => {
setting . setClass ( "various-complements__settings__nested" ) . addText ( ( cb ) => {
TextComponentEvent . onChange ( cb , async ( value ) => {
this . plugin . settings . cedictPath = value ;
await this . plugin . saveSettings ( ) ;
await this . display ( ) ;
} ) . setValue ( this . plugin . settings . cedictPath ) ;
} ) ;
} ) ;
const hasCedict = await this . app . vault . adapter . exists (
this . plugin . settings . cedictPath
) ;
if ( ! hasCedict ) {
containerEl . createEl ( "div" , {
text : ` \u 26A0 cedict_ts.u8 doesn't exist in ${ this . plugin . settings . cedictPath } . ` ,
cls : "various-complements__settings__warning"
} ) ;
}
}
addFilterableSetting ( "Match strategy" , null , ( setting ) => {
setting . addDropdown (
( tc ) => tc . addOptions ( mirrorMap ( MatchStrategy . values ( ) , ( x ) => x . name ) ) . setValue ( this . plugin . settings . matchStrategy ) . onChange ( async ( value ) => {
this . plugin . settings . matchStrategy = value ;
await this . plugin . saveSettings ( ) ;
this . display ( ) ;
} )
) ;
} ) ;
if ( this . plugin . settings . matchStrategy === MatchStrategy . PARTIAL . name ) {
containerEl . createEl ( "div" , {
text : "\u26A0 `partial` is more than 10 times slower than `prefix`" ,
cls : "various-complements__settings__warning"
} ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
addFilterableSetting ( "Fuzzy match" , null , ( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue ( this . plugin . settings . fuzzyMatch ) . onChange ( async ( value ) => {
this . plugin . settings . fuzzyMatch = value ;
await this . plugin . saveSettings ( ) ;
} ) ;
} ) ;
} ) ;
addFilterableSetting (
"Min fuzzy match score" ,
"It only shows suggestions whose fuzzy matched score is more than the specific value." ,
( setting ) => {
setting . addSlider (
( sc ) => sc . setLimits ( 0 , 5 , 0.1 ) . setValue ( this . plugin . settings . minFuzzyMatchScore ) . setDynamicTooltip ( ) . onChange ( async ( value ) => {
this . plugin . settings . minFuzzyMatchScore = value ;
await this . plugin . saveSettings ( ) ;
} )
) ;
}
) ;
addFilterableSetting (
"Treat accent diacritics as alphabetic characters." ,
"Ex: If enabled, 'aaa' matches with '\xE1\xE4\u0101'" ,
( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue (
this . plugin . settings . treatAccentDiacriticsAsAlphabeticCharacters
) . onChange ( async ( value ) => {
this . plugin . settings . treatAccentDiacriticsAsAlphabeticCharacters = value ;
await this . plugin . saveSettings ( {
internalLink : true ,
customDictionary : true ,
currentVault : true ,
currentFile : true
} ) ;
} ) ;
} ) ;
}
) ;
if ( TokenizeStrategy . fromName ( this . plugin . settings . strategy ) . canTreatUnderscoreAsPartOfWord ) {
addFilterableSetting (
"Treat an underscore as a part of a word." ,
"If this setting is enabled, aaa_bbb will be tokenized as a single token aaa_bbb, rather than being split into aaa and bbb." ,
( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue (
this . plugin . settings . treatUnderscoreAsPartOfWord
) . onChange ( async ( value ) => {
this . plugin . settings . treatUnderscoreAsPartOfWord = value ;
await this . plugin . saveSettings ( {
internalLink : true ,
customDictionary : true ,
currentVault : true ,
currentFile : true
} ) ;
} ) ;
} ) ;
}
) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
addFilterableSetting (
"Matching without emoji" ,
"Ex: If enabled, 'aaa' matches with '\u{1F600}aaa'" ,
( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue ( this . plugin . settings . matchingWithoutEmoji ) . onChange (
async ( value ) => {
this . plugin . settings . matchingWithoutEmoji = value ;
await this . plugin . saveSettings ( {
internalLink : true ,
customDictionary : true ,
currentVault : true ,
currentFile : true
} ) ;
}
) ;
} ) ;
}
) ;
addFilterableSetting ( "Max number of suggestions" , null , ( setting ) => {
setting . addSlider (
( sc ) => sc . setLimits ( 1 , 255 , 1 ) . setValue ( this . plugin . settings . maxNumberOfSuggestions ) . setDynamicTooltip ( ) . onChange ( async ( value ) => {
this . plugin . settings . maxNumberOfSuggestions = value ;
await this . plugin . saveSettings ( ) ;
} )
) ;
} ) ;
addFilterableSetting (
"Max number of words as a phrase" ,
` [ \u 26A0Warning] It makes slower more than N times (N is set value) ` ,
( setting ) => {
setting . addSlider (
( sc ) => sc . setLimits ( 1 , 10 , 1 ) . setValue ( this . plugin . settings . maxNumberOfWordsAsPhrase ) . setDynamicTooltip ( ) . onChange ( async ( value ) => {
this . plugin . settings . maxNumberOfWordsAsPhrase = value ;
await this . plugin . saveSettings ( ) ;
} )
) ;
}
) ;
addFilterableSetting (
"Min number of characters for trigger" ,
"Setting the value to 0 does not mean the suggestion will be triggered without any inputted character. Instead, a designated value will be used depending on the Strategy you choose." ,
( setting ) => {
setting . addSlider (
( sc ) => sc . setLimits ( 0 , 10 , 1 ) . setValue ( this . plugin . settings . minNumberOfCharactersTriggered ) . setDynamicTooltip ( ) . onChange ( async ( value ) => {
this . plugin . settings . minNumberOfCharactersTriggered = value ;
await this . plugin . saveSettings ( ) ;
} )
) ;
}
) ;
addFilterableSetting ( "Min number of words for trigger" , null , ( setting ) => {
setting . addSlider (
( sc ) => sc . setLimits ( 1 , 10 , 1 ) . setValue ( this . plugin . settings . minNumberOfWordsTriggeredPhrase ) . setDynamicTooltip ( ) . onChange ( async ( value ) => {
this . plugin . settings . minNumberOfWordsTriggeredPhrase = value ;
await this . plugin . saveSettings ( ) ;
} )
) ;
} ) ;
addFilterableSetting ( "Complement automatically" , null , ( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue ( this . plugin . settings . complementAutomatically ) . onChange (
async ( value ) => {
this . plugin . settings . complementAutomatically = value ;
await this . plugin . saveSettings ( ) ;
}
) ;
} ) ;
} ) ;
addFilterableSetting ( "Delay milli-seconds for trigger" , null , ( setting ) => {
setting . addSlider (
( sc ) => sc . setLimits ( 0 , 1e3 , 10 ) . setValue ( this . plugin . settings . delayMilliSeconds ) . setDynamicTooltip ( ) . onChange ( async ( value ) => {
this . plugin . settings . delayMilliSeconds = value ;
await this . plugin . saveSettings ( ) ;
} )
) ;
} ) ;
addFilterableSetting (
"Disable suggestions during IME on" ,
null ,
( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue (
this . plugin . settings . disableSuggestionsDuringImeOn
) . onChange ( async ( value ) => {
this . plugin . settings . disableSuggestionsDuringImeOn = value ;
await this . plugin . saveSettings ( ) ;
} ) ;
} ) ;
}
) ;
addFilterableSetting (
"Disable suggestions in the Math block" ,
"Disables suggestions within math blocks. This setting does not apply to inline blocks." ,
( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue (
this . plugin . settings . disableSuggestionsInMathBlock
) . onChange ( async ( value ) => {
this . plugin . settings . disableSuggestionsInMathBlock = value ;
await this . plugin . saveSettings ( ) ;
} ) ;
} ) ;
}
) ;
addFilterableSetting (
"Disable suggestions in the Code block" ,
"Disables suggestions within code blocks. This setting does not apply to inline blocks." ,
( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue (
this . plugin . settings . disableSuggestionsInCodeBlock
) . onChange ( async ( value ) => {
this . plugin . settings . disableSuggestionsInCodeBlock = value ;
await this . plugin . saveSettings ( ) ;
} ) ;
} ) ;
}
) ;
addFilterableSetting ( "Insert space after completion" , null , ( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue ( this . plugin . settings . insertSpaceAfterCompletion ) . onChange (
async ( value ) => {
this . plugin . settings . insertSpaceAfterCompletion = value ;
await this . plugin . saveSettings ( ) ;
}
) ;
} ) ;
} ) ;
addFilterableSetting (
"First characters to disable suggestions" ,
null ,
( setting ) => {
setting . addText ( ( cb ) => {
cb . setValue (
this . plugin . settings . firstCharactersDisableSuggestions
) . onChange ( async ( value ) => {
this . plugin . settings . firstCharactersDisableSuggestions = value ;
await this . plugin . saveSettings ( ) ;
} ) ;
} ) ;
}
) ;
addFilterableSetting (
"Line patterns to suppress trigger" ,
"Regular expression line patterns (partial match) until the cursor, that suppresses the activation of autocomplete. Multiple patterns can be defined with line breaks." ,
( setting ) => {
setting . addTextArea ( ( tc ) => {
const el = tc . setValue ( this . plugin . settings . patternsToSuppressTrigger . join ( "\n" ) ) . onChange ( async ( value ) => {
this . plugin . settings . patternsToSuppressTrigger = smartLineBreakSplit ( value ) ;
await this . plugin . saveSettings ( ) ;
} ) ;
el . inputEl . className = "various-complements__settings__text-area-path-dense" ;
return el ;
} ) ;
}
) ;
addFilterableSetting (
"Phrase patterns to suppress trigger" ,
"Regular expression patterns (exact match) that suppress the activation of autocomplete. Multiple patterns can be defined with line breaks." ,
( setting ) => {
setting . addTextArea ( ( tc ) => {
const el = tc . setValue (
this . plugin . settings . phrasePatternsToSuppressTrigger . join ( "\n" )
) . onChange ( async ( value ) => {
this . plugin . settings . phrasePatternsToSuppressTrigger = smartLineBreakSplit ( value ) ;
await this . plugin . saveSettings ( ) ;
} ) ;
el . inputEl . className = "various-complements__settings__text-area-path-dense" ;
return el ;
} ) ;
}
) ;
addFilterableSetting (
"No auto-focus until the cycle" ,
"No focus on the suggestions until the cycle key is pressed." ,
( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue ( this . plugin . settings . noAutoFocusUntilCycle ) . onChange (
async ( value ) => {
this . plugin . settings . noAutoFocusUntilCycle = value ;
await this . plugin . saveSettings ( ) ;
}
) ;
} ) ;
}
) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
addAppearanceSettings ( containerEl ) {
containerEl . createEl ( "h3" , {
text : "Appearance" ,
cls : "various-complements__settings__header various-complements__settings__header__appearance"
} ) ;
const group = new import _obsidian3 . SettingGroup ( containerEl ) ;
const { addFilterableSetting } = useFilterSetting ( group ) ;
addFilterableSetting (
"Show Match strategy" ,
"Show Match strategy at the status bar. Changing this option requires a restart to take effect." ,
( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue ( this . plugin . settings . showMatchStrategy ) . onChange (
async ( value ) => {
this . plugin . settings . showMatchStrategy = value ;
await this . plugin . saveSettings ( ) ;
}
) ;
} ) ;
}
) ;
addFilterableSetting (
"Show Complement automatically" ,
"Show complement automatically at the status bar. Changing this option requires a restart to take effect." ,
( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue (
this . plugin . settings . showComplementAutomatically
) . onChange ( async ( value ) => {
this . plugin . settings . showComplementAutomatically = value ;
await this . plugin . saveSettings ( ) ;
} ) ;
} ) ;
}
) ;
addFilterableSetting (
"Show Indexing status" ,
"Show indexing status at the status bar. Changing this option requires a restart to take effect." ,
( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue ( this . plugin . settings . showIndexingStatus ) . onChange (
async ( value ) => {
this . plugin . settings . showIndexingStatus = value ;
await this . plugin . saveSettings ( ) ;
}
) ;
} ) ;
}
) ;
addFilterableSetting ( "Description on a suggestion" , null , ( setting ) => {
setting . addDropdown (
( tc ) => tc . addOptions (
mirrorMap ( DescriptionOnSuggestion . values ( ) , ( x ) => x . name )
) . setValue ( this . plugin . settings . descriptionOnSuggestion ) . onChange ( async ( value ) => {
this . plugin . settings . descriptionOnSuggestion = value ;
await this . plugin . saveSettings ( ) ;
} )
) ;
} ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
addKeyCustomizationSettings ( containerEl ) {
containerEl . createEl ( "h3" , {
text : "Key customization" ,
cls : "various-complements__settings__header various-complements__settings__header__key-customization"
} ) ;
const group = new import _obsidian3 . SettingGroup ( containerEl ) . addClass (
"various-complements__settings__popup-hotkey"
) ;
const { addFilterableSetting } = useFilterSetting ( group ) ;
const li = createEl ( "li" ) ;
li . append (
"You can find the keycode at " ,
createEl ( "a" , {
text : "keycode.info" ,
href : "https://keycode.info/"
} ) ,
". Press any key to see the '" ,
createEl ( "code" , {
text : "event.key"
} ) ,
"' value, " ,
createEl ( "b" , {
text : "except for the space key"
} ) ,
". Set the space key as '" ,
createEl ( "code" , {
text : "Space"
} ) ,
"'."
) ;
const ul = createEl ( "ul" ) ;
ul . createEl ( "li" , {
text : "'Ctrl a' means pressing the Ctrl key and the A key."
} ) ;
ul . createEl ( "li" , {
text : "'Enter|Tab' means pressing the Enter key or the Tab key."
} ) ;
ul . createEl ( "li" , {
text : "Use 'Mod' instead of 'Ctrl' on Windows or 'Cmd' on macOS."
} ) ;
ul . append ( li ) ;
const df = document . createDocumentFragment ( ) ;
df . append ( ul ) ;
group . addSetting ( ( setting ) => {
setting . setHeading ( ) . setName ( "Hotkeys" ) . setDesc ( df ) ;
} ) ;
const hotkeys = this . plugin . settings . hotkeys ;
Object . keys ( hotkeys ) . forEach ( ( k ) => {
const key = k ;
addFilterableSetting ( key , null , ( setting ) => {
setting . setClass ( "various-complements__settings__popup-hotkey-item" ) . addText ( ( cb ) => {
return cb . setValue ( hotkeys [ key ] . map ( hotkey2String ) . join ( "|" ) ) . onChange ( async ( value ) => {
hotkeys [ key ] = value . split ( "|" ) . map ( ( x ) => string2Hotkey ( x , false ) ) . filter ( isPresent ) ;
await this . plugin . saveSettings ( ) ;
} ) ;
} ) ;
} ) ;
} ) ;
new import _obsidian3 . Setting ( containerEl ) . setName ( "Propagate ESC" ) . setDesc (
"It is handy if you use Vim mode because you can switch to Normal mode by one ESC, whether it shows suggestions or not."
) . addToggle ( ( tc ) => {
tc . setValue ( this . plugin . settings . propagateEsc ) . onChange (
async ( value ) => {
this . plugin . settings . propagateEsc = value ;
await this . plugin . saveSettings ( ) ;
}
) ;
} ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
addCurrentFileComplementSettings ( containerEl ) {
containerEl . createEl ( "h3" , {
text : "Current file complement" ,
cls : "various-complements__settings__header various-complements__settings__header__current-file"
} ) ;
const group = new import _obsidian3 . SettingGroup ( containerEl ) ;
const { addFilterableSetting } = useFilterSetting ( group ) ;
addFilterableSetting ( "Enable Current file complement" , null , ( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue ( this . plugin . settings . enableCurrentFileComplement ) . onChange (
async ( value ) => {
this . plugin . settings . enableCurrentFileComplement = value ;
await this . plugin . saveSettings ( { currentFile : true } ) ;
this . display ( ) ;
}
) ;
} ) ;
} ) ;
if ( this . plugin . settings . enableCurrentFileComplement ) {
addFilterableSetting (
"Min number of characters for indexing" ,
"It uses a default value of Strategy if set 0." ,
( setting ) => {
setting . addSlider (
( sc ) => sc . setLimits ( 0 , 15 , 1 ) . setValue ( this . plugin . settings . currentFileMinNumberOfCharacters ) . setDynamicTooltip ( ) . onChange ( async ( value ) => {
this . plugin . settings . currentFileMinNumberOfCharacters = value ;
await this . plugin . saveSettings ( { currentFile : true } ) ;
} )
) ;
}
) ;
addFilterableSetting (
"Only complement English on current file complement" ,
null ,
( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue (
this . plugin . settings . onlyComplementEnglishOnCurrentFileComplement
) . onChange ( async ( value ) => {
this . plugin . settings . onlyComplementEnglishOnCurrentFileComplement = value ;
await this . plugin . saveSettings ( { currentFile : true } ) ;
} ) ;
} ) ;
}
) ;
addFilterableSetting (
"Min number of characters for trigger" ,
"Override the main trigger setting for this provider. Set 0 to use the main setting value." ,
( setting ) => {
setting . addSlider (
( sc ) => sc . setLimits ( 0 , 10 , 1 ) . setValue (
this . plugin . settings . currentFileMinNumberOfCharactersForTrigger
) . setDynamicTooltip ( ) . onChange ( async ( value ) => {
this . plugin . settings . currentFileMinNumberOfCharactersForTrigger = value ;
await this . plugin . saveSettings ( ) ;
} )
) ;
}
) ;
addFilterableSetting (
"Exclude word patterns for indexing" ,
"Regexp patterns for words to be excluded from the suggestions, separated by line breaks." ,
( setting ) => {
setting . addTextArea ( ( tc ) => {
const el = tc . setValue (
this . plugin . settings . excludeCurrentFileWordPatterns . join ( "\n" )
) . onChange ( async ( value ) => {
this . plugin . settings . excludeCurrentFileWordPatterns = smartLineBreakSplit ( value ) ;
await this . plugin . saveSettings ( ) ;
} ) ;
el . inputEl . className = "various-complements__settings__text-area-path-dense" ;
return el ;
} ) ;
}
) ;
}
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
addCurrentVaultComplementSettings ( containerEl ) {
containerEl . createEl ( "h3" , {
text : "Current vault complement" ,
cls : "various-complements__settings__header various-complements__settings__header__current-vault"
} ) ;
const group = new import _obsidian3 . SettingGroup ( containerEl ) ;
const { addFilterableSetting } = useFilterSetting ( group ) ;
addFilterableSetting ( "Enable Current vault complement" , null , ( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue ( this . plugin . settings . enableCurrentVaultComplement ) . onChange (
async ( value ) => {
this . plugin . settings . enableCurrentVaultComplement = value ;
this . display ( ) ;
await this . plugin . saveSettings ( { currentVault : true } ) ;
}
) ;
} ) ;
} ) ;
if ( this . plugin . settings . enableCurrentVaultComplement ) {
addFilterableSetting (
"Min number of characters for indexing" ,
"It uses a default value of Strategy if set 0." ,
( setting ) => {
setting . addSlider (
( sc ) => sc . setLimits ( 0 , 15 , 1 ) . setValue ( this . plugin . settings . currentVaultMinNumberOfCharacters ) . setDynamicTooltip ( ) . onChange ( async ( value ) => {
this . plugin . settings . currentVaultMinNumberOfCharacters = value ;
await this . plugin . saveSettings ( ) ;
} )
) ;
}
) ;
addFilterableSetting (
"Include prefix path patterns" ,
"Prefix match path patterns to include files." ,
( setting ) => {
setting . addTextArea ( ( tac ) => {
const el = tac . setValue (
this . plugin . settings . includeCurrentVaultPathPrefixPatterns
) . setPlaceholder ( "Private/" ) . onChange ( async ( value ) => {
this . plugin . settings . includeCurrentVaultPathPrefixPatterns = value ;
await this . plugin . saveSettings ( ) ;
} ) ;
el . inputEl . className = "various-complements__settings__text-area-path" ;
return el ;
} ) ;
}
) ;
addFilterableSetting (
"Exclude prefix path patterns" ,
"Prefix match path patterns to exclude files." ,
( setting ) => {
setting . addTextArea ( ( tac ) => {
const el = tac . setValue (
this . plugin . settings . excludeCurrentVaultPathPrefixPatterns
) . setPlaceholder ( "Private/" ) . onChange ( async ( value ) => {
this . plugin . settings . excludeCurrentVaultPathPrefixPatterns = value ;
await this . plugin . saveSettings ( ) ;
} ) ;
el . inputEl . className = "various-complements__settings__text-area-path" ;
return el ;
} ) ;
}
) ;
addFilterableSetting (
"Exclude path glob patterns" ,
"Glob patterns to exclude files. Supports wildcards like **/attachments, **/*.png, etc." ,
( setting ) => {
setting . addTextArea ( ( tac ) => {
const el = tac . setValue (
this . plugin . settings . excludeCurrentVaultPathGlobPatterns . join (
"\n"
)
) . setPlaceholder ( "**/attachments\n**/*.png" ) . onChange ( async ( value ) => {
this . plugin . settings . excludeCurrentVaultPathGlobPatterns = smartLineBreakSplit ( value ) ;
await this . plugin . saveSettings ( ) ;
this . display ( ) ;
} ) ;
el . inputEl . className = "various-complements__settings__text-area-path" ;
return el ;
} ) ;
}
) ;
containerEl . createEl ( "div" , {
text : "\u26A0 Glob patterns add processing overhead. Use prefix path patterns above for better performance when possible." ,
cls : "various-complements__settings__warning"
} ) ;
addFilterableSetting (
"Include only files under current directory" ,
null ,
( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue (
this . plugin . settings . includeCurrentVaultOnlyFilesUnderCurrentDirectory
) . onChange ( async ( value ) => {
this . plugin . settings . includeCurrentVaultOnlyFilesUnderCurrentDirectory = value ;
await this . plugin . saveSettings ( ) ;
} ) ;
} ) ;
}
) ;
addFilterableSetting (
"Min number of characters for trigger" ,
"Override the main trigger setting for this provider. Set 0 to use the main setting value." ,
( setting ) => {
setting . addSlider (
( sc ) => sc . setLimits ( 0 , 10 , 1 ) . setValue (
this . plugin . settings . currentVaultMinNumberOfCharactersForTrigger
) . setDynamicTooltip ( ) . onChange ( async ( value ) => {
this . plugin . settings . currentVaultMinNumberOfCharactersForTrigger = value ;
await this . plugin . saveSettings ( ) ;
} )
) ;
}
) ;
addFilterableSetting (
"Exclude word patterns for indexing" ,
"Regexp patterns for words to be excluded from the suggestions, separated by line breaks." ,
( setting ) => {
setting . addTextArea ( ( tc ) => {
const el = tc . setValue (
this . plugin . settings . excludeCurrentVaultWordPatterns . join ( "\n" )
) . onChange ( async ( value ) => {
this . plugin . settings . excludeCurrentVaultWordPatterns = smartLineBreakSplit ( value ) ;
await this . plugin . saveSettings ( ) ;
} ) ;
el . inputEl . className = "various-complements__settings__text-area-path-dense" ;
return el ;
} ) ;
}
) ;
}
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
addCustomDictionaryComplementSettings ( containerEl ) {
containerEl . createEl ( "h3" , {
text : "Custom dictionary complement" ,
cls : "various-complements__settings__header various-complements__settings__header__custom-dictionary"
} ) ;
const group = new import _obsidian3 . SettingGroup ( containerEl ) ;
const { addFilterableSetting } = useFilterSetting ( group ) ;
addFilterableSetting (
"Enable Custom dictionary complement" ,
null ,
( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue (
this . plugin . settings . enableCustomDictionaryComplement
) . onChange ( async ( value ) => {
this . plugin . settings . enableCustomDictionaryComplement = value ;
await this . plugin . saveSettings ( { customDictionary : true } ) ;
this . display ( ) ;
} ) ;
} ) ;
}
) ;
if ( this . plugin . settings . enableCustomDictionaryComplement ) {
addFilterableSetting (
"Custom dictionary paths" ,
"Specify either a relative path from Vault root or URL for each line." ,
( setting ) => {
setting . addTextArea ( ( tac ) => {
const el = tac . setValue ( this . plugin . settings . customDictionaryPaths ) . setPlaceholder ( "dictionary.md" ) . onChange ( async ( value ) => {
this . plugin . settings . customDictionaryPaths = value ;
await this . plugin . saveSettings ( ) ;
} ) ;
el . inputEl . className = "various-complements__settings__text-area-path" ;
return el ;
} ) ;
}
) ;
addFilterableSetting ( "Column delimiter" , null , ( setting ) => {
setting . addDropdown (
( tc ) => tc . addOptions ( mirrorMap ( ColumnDelimiter . values ( ) , ( x ) => x . name ) ) . setValue ( this . plugin . settings . columnDelimiter ) . onChange ( async ( value ) => {
this . plugin . settings . columnDelimiter = value ;
await this . plugin . saveSettings ( ) ;
2025-08-02 12:09:34 +08:00
} )
) ;
2026-05-06 17:32:44 +08:00
} ) ;
addFilterableSetting (
"Word regex pattern" ,
"Only load words that match the regular expression pattern." ,
( setting ) => {
setting . addText ( ( cb ) => {
cb . setValue (
this . plugin . settings . customDictionaryWordRegexPattern
) . onChange ( async ( value ) => {
this . plugin . settings . customDictionaryWordRegexPattern = value ;
await this . plugin . saveSettings ( ) ;
} ) ;
} ) ;
}
) ;
addFilterableSetting (
"Delimiter to hide a suggestion" ,
"If set ';;;', 'abcd;;;efg' is shown as 'abcd' on suggestions, but completes to 'abcdefg'." ,
( setting ) => {
setting . addText ( ( cb ) => {
cb . setValue (
this . plugin . settings . delimiterToHideSuggestion
) . onChange ( async ( value ) => {
this . plugin . settings . delimiterToHideSuggestion = value ;
await this . plugin . saveSettings ( ) ;
} ) ;
} ) ;
}
) ;
addFilterableSetting (
"Delimiter to divide suggestions for display from ones for insertion" ,
"If set ' >>> ', 'displayed >>> inserted' is shown as 'displayed' on suggestions, but completes to 'inserted'." ,
( setting ) => {
setting . addText ( ( cb ) => {
cb . setValue (
this . plugin . settings . delimiterToDivideSuggestionsForDisplayFromInsertion
) . onChange ( async ( value ) => {
this . plugin . settings . delimiterToDivideSuggestionsForDisplayFromInsertion = value ;
await this . plugin . saveSettings ( ) ;
} ) ;
} ) ;
}
) ;
addFilterableSetting (
"Caret location symbol after complement" ,
"If set '<CARET>' and there is '<li><CARET></li>' in custom dictionary, it complements '<li></li>' and move a caret where between '<li>' and `</li>`." ,
( setting ) => {
setting . addText ( ( cb ) => {
cb . setValue (
this . plugin . settings . caretLocationSymbolAfterComplement
) . onChange ( async ( value ) => {
this . plugin . settings . caretLocationSymbolAfterComplement = value ;
await this . plugin . saveSettings ( ) ;
} ) ;
} ) ;
}
) ;
addFilterableSetting (
"Displayed text suffix" ,
"It shows as a suffix of displayed text if there is a difference between displayed and inserted" ,
( setting ) => {
setting . addText ( ( cb ) => {
cb . setValue ( this . plugin . settings . displayedTextSuffix ) . onChange (
async ( value ) => {
this . plugin . settings . displayedTextSuffix = value ;
await this . plugin . saveSettings ( ) ;
}
) ;
} ) ;
}
) ;
addFilterableSetting (
"Min number of characters for trigger" ,
"Override the main trigger setting for this provider. Set 0 to use the main setting value." ,
( setting ) => {
setting . addSlider (
( sc ) => sc . setLimits ( 0 , 10 , 1 ) . setValue (
this . plugin . settings . customDictionaryMinNumberOfCharactersForTrigger
) . setDynamicTooltip ( ) . onChange ( async ( value ) => {
this . plugin . settings . customDictionaryMinNumberOfCharactersForTrigger = value ;
await this . plugin . saveSettings ( ) ;
} )
) ;
}
) ;
}
}
addInternalLinkComplementSettings ( containerEl ) {
containerEl . createEl ( "h3" , {
text : "Internal link complement" ,
cls : "various-complements__settings__header various-complements__settings__header__internal-link"
} ) ;
const group = new import _obsidian3 . SettingGroup ( containerEl ) ;
const { addFilterableSetting } = useFilterSetting ( group ) ;
addFilterableSetting ( "Enable Internal link complement" , null , ( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue ( this . plugin . settings . enableInternalLinkComplement ) . onChange (
async ( value ) => {
this . plugin . settings . enableInternalLinkComplement = value ;
await this . plugin . saveSettings ( { internalLink : true } ) ;
this . display ( ) ;
}
) ;
} ) ;
} ) ;
if ( this . plugin . settings . enableInternalLinkComplement ) {
addFilterableSetting ( "Suggest with an alias" , null , ( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue (
this . plugin . settings . suggestInternalLinkWithAlias
) . onChange ( async ( value ) => {
this . plugin . settings . suggestInternalLinkWithAlias = value ;
await this . plugin . saveSettings ( { internalLink : true } ) ;
} ) ;
} ) ;
} ) ;
addFilterableSetting (
"Preserve first-letter case" ,
"If the first letter case differs between the query and the displayed text, insert with an alias using the query's first-letter case." ,
( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue (
this . plugin . settings . preserveFirstLetterCaseOnInternalLink
) . onChange ( async ( value ) => {
this . plugin . settings . preserveFirstLetterCaseOnInternalLink = value ;
await this . plugin . saveSettings ( ) ;
} ) ;
} ) ;
}
) ;
addFilterableSetting ( "Update internal links on save" , null , ( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue ( this . plugin . settings . updateInternalLinksOnSave ) . onChange (
async ( value ) => {
this . plugin . settings . updateInternalLinksOnSave = value ;
await this . plugin . saveSettings ( { internalLink : true } ) ;
}
) ;
} ) ;
} ) ;
addFilterableSetting ( "Exclude self internal link" , null , ( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue ( this . plugin . settings . excludeSelfInternalLink ) . onChange (
async ( value ) => {
this . plugin . settings . excludeSelfInternalLink = value ;
await this . plugin . saveSettings ( { internalLink : true } ) ;
}
) ;
} ) ;
} ) ;
addFilterableSetting (
"Exclude existing in active file internal links" ,
"Exclude internal links present in the current file from the suggestions. Note that the number of excluded suggestions will reduce the total suggestions by the value set in the 'Max number of suggestions' option." ,
( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue (
this . plugin . settings . excludeExistingInActiveFileInternalLinks
) . onChange ( async ( value ) => {
this . plugin . settings . excludeExistingInActiveFileInternalLinks = value ;
await this . plugin . saveSettings ( { internalLink : true } ) ;
} ) ;
} ) ;
}
) ;
addFilterableSetting (
"Exclude unresolved internal links" ,
"Exclude internal links that point to non-existing files (phantom links) from the suggestions." ,
( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue (
this . plugin . settings . excludeUnresolvedInternalLinks
) . onChange ( async ( value ) => {
this . plugin . settings . excludeUnresolvedInternalLinks = value ;
await this . plugin . saveSettings ( { internalLink : true } ) ;
} ) ;
} ) ;
}
) ;
addFilterableSetting (
"Insert an alias that is transformed from the displayed internal link" ,
null ,
( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue (
this . plugin . settings . insertAliasTransformedFromDisplayedInternalLink . enabled
) . onChange ( async ( value ) => {
this . plugin . settings . insertAliasTransformedFromDisplayedInternalLink . enabled = value ;
await this . plugin . saveSettings ( ) ;
this . display ( ) ;
} ) ;
} ) ;
}
) ;
if ( this . plugin . settings . insertAliasTransformedFromDisplayedInternalLink . enabled ) {
addFilterableSetting (
"Before: regular expression pattern with captures" ,
String . raw ` Ex: (?<name>.+) \( .+ \) $ ` ,
( setting ) => {
setting . setClass ( "various-complements__settings__nested" ) . addText ( ( cb ) => {
cb . setValue (
this . plugin . settings . insertAliasTransformedFromDisplayedInternalLink . beforeRegExp
) . onChange ( async ( value ) => {
this . plugin . settings . insertAliasTransformedFromDisplayedInternalLink . beforeRegExp = value ;
await this . plugin . saveSettings ( ) ;
} ) ;
} ) ;
}
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
addFilterableSetting ( "After" , "Ex: $<name>" , ( setting ) => {
setting . setClass ( "various-complements__settings__nested" ) . addText ( ( cb ) => {
cb . setValue (
this . plugin . settings . insertAliasTransformedFromDisplayedInternalLink . after
) . onChange ( async ( value ) => {
this . plugin . settings . insertAliasTransformedFromDisplayedInternalLink . after = value ;
await this . plugin . saveSettings ( ) ;
} ) ;
} ) ;
} ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
addFilterableSetting (
"Exclude prefix path patterns" ,
"Prefix match path patterns to exclude files." ,
( setting ) => {
setting . addTextArea ( ( tac ) => {
const el = tac . setValue (
this . plugin . settings . excludeInternalLinkPathPrefixPatterns
) . setPlaceholder ( "Private/" ) . onChange ( async ( value ) => {
this . plugin . settings . excludeInternalLinkPathPrefixPatterns = value ;
await this . plugin . saveSettings ( ) ;
} ) ;
el . inputEl . className = "various-complements__settings__text-area-path" ;
return el ;
} ) ;
}
) ;
addFilterableSetting (
"Exclude path glob patterns" ,
"Glob patterns to exclude files. Supports wildcards like **/attachments, **/*.png, etc." ,
( setting ) => {
setting . addTextArea ( ( tac ) => {
const el = tac . setValue (
this . plugin . settings . excludeInternalLinkPathGlobPatterns . join (
"\n"
)
) . setPlaceholder ( "**/attachments\n**/*.png" ) . onChange ( async ( value ) => {
this . plugin . settings . excludeInternalLinkPathGlobPatterns = smartLineBreakSplit ( value ) ;
await this . plugin . saveSettings ( ) ;
} ) ;
el . inputEl . className = "various-complements__settings__text-area-path" ;
return el ;
} ) ;
}
) ;
containerEl . createEl ( "div" , {
text : "\u26A0 Glob patterns add processing overhead. Use prefix path patterns above for better performance when possible." ,
cls : "various-complements__settings__warning"
} ) ;
addFilterableSetting (
"Front matter key for exclusion" ,
"Exclude internal links from the suggestions if whose front matters have the key whose name is same as this setting, and the value is 'true'" ,
( setting ) => {
setting . addText ( ( cb ) => {
TextComponentEvent . onChange ( cb , async ( value ) => {
this . plugin . settings . frontMatterKeyForExclusionInternalLink = value ;
await this . plugin . saveSettings ( { internalLink : true } ) ;
} ) . setValue (
this . plugin . settings . frontMatterKeyForExclusionInternalLink
) ;
} ) ;
}
) ;
addFilterableSetting (
"Tags for exclusion" ,
"Tags to exclude suggestions for internal links. If specifying multiple tags, separate them with line breaks." ,
( setting ) => {
setting . addTextArea ( ( tc ) => {
const el = tc . setValue (
this . plugin . settings . tagsForExclusionInternalLink . join ( "\n" )
) . onChange ( async ( value ) => {
this . plugin . settings . tagsForExclusionInternalLink = smartLineBreakSplit ( value ) ;
await this . plugin . saveSettings ( ) ;
} ) ;
el . inputEl . className = "various-complements__settings__text-area-path-mini" ;
return el ;
} ) ;
}
) ;
addFilterableSetting (
"Min number of characters for trigger" ,
"Override the main trigger setting for this provider. Set 0 to use the main setting value." ,
( setting ) => {
setting . addSlider (
( sc ) => sc . setLimits ( 0 , 10 , 1 ) . setValue (
this . plugin . settings . internalLinkMinNumberOfCharactersForTrigger
) . setDynamicTooltip ( ) . onChange ( async ( value ) => {
this . plugin . settings . internalLinkMinNumberOfCharactersForTrigger = value ;
await this . plugin . saveSettings ( ) ;
} )
) ;
}
) ;
2025-08-02 12:09:34 +08:00
}
}
2026-05-06 17:32:44 +08:00
addFrontMatterComplementSettings ( containerEl ) {
containerEl . createEl ( "h3" , {
text : "Front matter complement" ,
cls : "various-complements__settings__header various-complements__settings__header__front-matter"
} ) ;
const group = new import _obsidian3 . SettingGroup ( containerEl ) ;
const { addFilterableSetting } = useFilterSetting ( group ) ;
addFilterableSetting ( "Enable Front matter complement" , null , ( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue ( this . plugin . settings . enableFrontMatterComplement ) . onChange (
async ( value ) => {
this . plugin . settings . enableFrontMatterComplement = value ;
await this . plugin . saveSettings ( { frontMatter : true } ) ;
this . display ( ) ;
}
) ;
} ) ;
} ) ;
if ( this . plugin . settings . enableFrontMatterComplement ) {
addFilterableSetting (
"Match strategy in the front matter" ,
null ,
( setting ) => {
setting . addDropdown (
( tc ) => tc . addOptions (
mirrorMap ( SpecificMatchStrategy . values ( ) , ( x ) => x . name )
) . setValue ( this . plugin . settings . frontMatterComplementMatchStrategy ) . onChange ( async ( value ) => {
this . plugin . settings . frontMatterComplementMatchStrategy = value ;
await this . plugin . saveSettings ( ) ;
} )
) ;
}
) ;
addFilterableSetting ( "Insert comma after completion" , null , ( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue (
this . plugin . settings . insertCommaAfterFrontMatterCompletion
) . onChange ( async ( value ) => {
this . plugin . settings . insertCommaAfterFrontMatterCompletion = value ;
await this . plugin . saveSettings ( ) ;
} ) ;
} ) ;
} ) ;
}
}
addIntelligentSuggestionPrioritizationSettings ( containerEl ) {
containerEl . createEl ( "h3" , {
text : "Intelligent suggestion prioritization" ,
cls : "various-complements__settings__header various-complements__settings__header__intelligent-suggestion-prioritization"
} ) ;
const group = new import _obsidian3 . SettingGroup ( containerEl ) ;
const { addFilterableSetting } = useFilterSetting ( group ) ;
addFilterableSetting (
"Enable Intelligent Suggestion Prioritization" ,
null ,
( setting ) => {
setting . addToggle ( ( tc ) => {
tc . setValue (
this . plugin . settings . intelligentSuggestionPrioritization . enabled
) . onChange ( async ( value ) => {
this . plugin . settings . intelligentSuggestionPrioritization . enabled = value ;
await this . plugin . saveSettings ( {
intelligentSuggestionPrioritization : true
} ) ;
this . display ( ) ;
} ) ;
} ) ;
}
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
if ( this . plugin . settings . intelligentSuggestionPrioritization . enabled ) {
addFilterableSetting (
"history file path" ,
` Default: ${ DEFAULT _HISTORIES _PATH } ` ,
( setting ) => {
setting . addText ( ( cb ) => {
TextComponentEvent . onChange ( cb , async ( value ) => {
this . plugin . settings . intelligentSuggestionPrioritization . historyFilePath = value ;
await this . plugin . saveSettings ( {
intelligentSuggestionPrioritization : true
} ) ;
} ) . setValue (
this . plugin . settings . intelligentSuggestionPrioritization . historyFilePath
) ;
} ) ;
}
) ;
addFilterableSetting (
"Max days to keep history" ,
"If set 0, it will never remove" ,
( setting ) => {
setting . addSlider (
( sc ) => sc . setLimits ( 0 , 365 , 1 ) . setValue (
this . plugin . settings . intelligentSuggestionPrioritization . maxDaysToKeepHistory
) . setDynamicTooltip ( ) . onChange ( async ( value ) => {
this . plugin . settings . intelligentSuggestionPrioritization . maxDaysToKeepHistory = value ;
await this . plugin . saveSettings ( ) ;
} )
) ;
}
) ;
addFilterableSetting (
"Max number of history to keep" ,
"If set 0, it will never remove" ,
( setting ) => {
setting . addSlider (
( sc ) => sc . setLimits ( 0 , 1e4 , 1 ) . setValue (
this . plugin . settings . intelligentSuggestionPrioritization . maxNumberOfHistoryToKeep
) . setDynamicTooltip ( ) . onChange ( async ( value ) => {
this . plugin . settings . intelligentSuggestionPrioritization . maxNumberOfHistoryToKeep = value ;
await this . plugin . saveSettings ( ) ;
} )
) ;
}
) ;
}
}
addMobileSettings ( containerEl ) {
containerEl . createEl ( "h3" , {
text : "Mobile" ,
cls : "various-complements__settings__header various-complements__settings__header__mobile"
} ) ;
new import _obsidian3 . Setting ( containerEl ) . setName ( "Disable on mobile" ) . addToggle ( ( tc ) => {
tc . setValue ( this . plugin . settings . disableOnMobile ) . onChange (
async ( value ) => {
this . plugin . settings . disableOnMobile = value ;
await this . plugin . saveSettings ( ) ;
}
) ;
} ) ;
}
addDebugSettings ( containerEl ) {
containerEl . createEl ( "h3" , {
text : "Debug" ,
cls : "various-complements__settings__header various-complements__settings__header__debug"
} ) ;
new import _obsidian3 . Setting ( containerEl ) . setName ( "Show log about performance in a console" ) . addToggle ( ( tc ) => {
tc . setValue (
this . plugin . settings . showLogAboutPerformanceInConsole
) . onChange ( async ( value ) => {
this . plugin . settings . showLogAboutPerformanceInConsole = value ;
await this . plugin . saveSettings ( ) ;
} ) ;
} ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
async toggleMatchStrategy ( ) {
switch ( this . plugin . settings . matchStrategy ) {
case "prefix" :
this . plugin . settings . matchStrategy = "partial" ;
break ;
case "partial" :
this . plugin . settings . matchStrategy = "prefix" ;
break ;
default :
new import _obsidian3 . Notice ( "\u26A0Unexpected error" ) ;
}
await this . plugin . saveSettings ( ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
async toggleComplementAutomatically ( ) {
this . plugin . settings . complementAutomatically = ! this . plugin . settings . complementAutomatically ;
await this . plugin . saveSettings ( ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
async ensureCustomDictionaryPath ( path2 , state ) {
const paths = this . plugin . settings . customDictionaryPaths . split ( "\n" ) ;
const exists = paths . some ( ( x ) => x === path2 ) ;
if ( exists && state === "present" || ! exists && state === "absent" ) {
return false ;
}
const newPaths = state === "present" ? [ ... paths , path2 ] : paths . filter ( ( x ) => x !== path2 ) ;
this . plugin . settings . customDictionaryPaths = newPaths . join ( "\n" ) ;
await this . plugin . saveSettings ( { customDictionary : true } ) ;
return true ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
getPluginSettingsAsJsonString ( ) {
return JSON . stringify (
{
version : this . plugin . manifest . version ,
mobile : this . app . isMobile ,
settings : this . plugin . settings
} ,
null ,
4
) ;
2025-08-02 12:09:34 +08:00
}
} ;
2026-05-06 17:32:44 +08:00
// src/ui/AutoCompleteSuggest.ts
var import _obsidian7 = require ( "obsidian" ) ;
2025-08-02 12:09:34 +08:00
// src/provider/CurrentFileWordProvider.ts
var CurrentFileWordProvider = class {
2026-05-06 17:32:44 +08:00
constructor ( app , appHelper ) {
this . app = app ;
2025-08-02 12:09:34 +08:00
this . appHelper = appHelper ;
this . wordsByFirstLetter = { } ;
this . words = [ ] ;
}
async refreshWords ( option ) {
2026-05-06 17:32:44 +08:00
var _a ;
2025-08-02 12:09:34 +08:00
this . clearWords ( ) ;
const editor = this . appHelper . getCurrentEditor ( ) ;
if ( ! editor ) {
return ;
}
const file = this . app . workspace . getActiveFile ( ) ;
if ( ! file ) {
return ;
}
const currentToken = this . tokenizer . tokenize (
editor . getLine ( editor . getCursor ( ) . line ) . slice ( 0 , editor . getCursor ( ) . ch )
) . last ( ) ;
2026-05-06 17:32:44 +08:00
const excludePatterns = option . excludeWordPatterns . map (
( x ) => new RegExp ( ` ^ ${ x } $ ` )
) ;
2025-08-02 12:09:34 +08:00
const content = await this . app . vault . cachedRead ( file ) ;
const tokens = this . tokenizer . tokenize ( content ) . filter ( ( x ) => {
if ( x . length < option . minNumberOfCharacters ) {
return false ;
}
if ( this . tokenizer . shouldIgnoreOnCurrent ( x ) ) {
return false ;
}
return option . onlyEnglish ? allAlphabets ( x ) : true ;
2026-05-06 17:32:44 +08:00
} ) . map ( ( x ) => startsSmallLetterOnlyFirst ( x ) ? x . toLowerCase ( ) : x ) . filter ( ( x ) => ! excludePatterns . some ( ( rp ) => x . match ( rp ) ) ) ;
2025-08-02 12:09:34 +08:00
this . words = uniq ( tokens ) . filter ( ( x ) => x !== currentToken ) . map ( ( x ) => ( {
value : x ,
type : "currentFile" ,
createdPath : file . path ,
aliases : synonymAliases ( x , {
emoji : option . makeSynonymAboutEmoji ,
accentsDiacritics : option . makeSynonymAboutAccentsDiacritics
} )
} ) ) ;
for ( const word of this . words ) {
pushWord ( this . wordsByFirstLetter , word . value . charAt ( 0 ) , word ) ;
( _a = word . aliases ) == null ? void 0 : _a . forEach (
( a ) => pushWord ( this . wordsByFirstLetter , a . charAt ( 0 ) , word )
) ;
}
}
clearWords ( ) {
this . words = [ ] ;
this . wordsByFirstLetter = { } ;
}
get wordCount ( ) {
return this . words . length ;
}
2026-05-06 17:32:44 +08:00
setSettings ( tokenizer ) {
this . tokenizer = tokenizer ;
}
2025-08-02 12:09:34 +08:00
} ;
2026-05-06 17:32:44 +08:00
// node_modules/.pnpm/@isaacs+balanced-match@4.0.1/node_modules/@isaacs/balanced-match/dist/esm/index.js
var balanced = ( a , b , str ) => {
const ma = a instanceof RegExp ? maybeMatch ( a , str ) : a ;
const mb = b instanceof RegExp ? maybeMatch ( b , str ) : b ;
const r = ma !== null && mb != null && range ( ma , mb , str ) ;
return r && {
start : r [ 0 ] ,
end : r [ 1 ] ,
pre : str . slice ( 0 , r [ 0 ] ) ,
body : str . slice ( r [ 0 ] + ma . length , r [ 1 ] ) ,
post : str . slice ( r [ 1 ] + mb . length )
} ;
} ;
var maybeMatch = ( reg , str ) => {
const m = str . match ( reg ) ;
return m ? m [ 0 ] : null ;
} ;
var range = ( a , b , str ) => {
let begs , beg , left , right = void 0 , result ;
let ai = str . indexOf ( a ) ;
let bi = str . indexOf ( b , ai + 1 ) ;
let i = ai ;
if ( ai >= 0 && bi > 0 ) {
if ( a === b ) {
return [ ai , bi ] ;
}
begs = [ ] ;
left = str . length ;
while ( i >= 0 && ! result ) {
if ( i === ai ) {
begs . push ( i ) ;
ai = str . indexOf ( a , i + 1 ) ;
} else if ( begs . length === 1 ) {
const r = begs . pop ( ) ;
if ( r !== void 0 )
result = [ r , bi ] ;
} else {
beg = begs . pop ( ) ;
if ( beg !== void 0 && beg < left ) {
left = beg ;
right = bi ;
}
bi = str . indexOf ( b , i + 1 ) ;
}
i = ai < bi && ai >= 0 ? ai : bi ;
}
if ( begs . length && right !== void 0 ) {
result = [ left , right ] ;
}
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
return result ;
2025-08-02 12:09:34 +08:00
} ;
2026-05-06 17:32:44 +08:00
// node_modules/.pnpm/@isaacs+brace-expansion@5.0.0/node_modules/@isaacs/brace-expansion/dist/esm/index.js
var escSlash = "\0SLASH" + Math . random ( ) + "\0" ;
var escOpen = "\0OPEN" + Math . random ( ) + "\0" ;
var escClose = "\0CLOSE" + Math . random ( ) + "\0" ;
var escComma = "\0COMMA" + Math . random ( ) + "\0" ;
var escPeriod = "\0PERIOD" + Math . random ( ) + "\0" ;
var escSlashPattern = new RegExp ( escSlash , "g" ) ;
var escOpenPattern = new RegExp ( escOpen , "g" ) ;
var escClosePattern = new RegExp ( escClose , "g" ) ;
var escCommaPattern = new RegExp ( escComma , "g" ) ;
var escPeriodPattern = new RegExp ( escPeriod , "g" ) ;
var slashPattern = /\\\\/g ;
var openPattern = /\\{/g ;
var closePattern = /\\}/g ;
var commaPattern = /\\,/g ;
var periodPattern = /\\./g ;
function numeric ( str ) {
return ! isNaN ( str ) ? parseInt ( str , 10 ) : str . charCodeAt ( 0 ) ;
}
function escapeBraces ( str ) {
return str . replace ( slashPattern , escSlash ) . replace ( openPattern , escOpen ) . replace ( closePattern , escClose ) . replace ( commaPattern , escComma ) . replace ( periodPattern , escPeriod ) ;
}
function unescapeBraces ( str ) {
return str . replace ( escSlashPattern , "\\" ) . replace ( escOpenPattern , "{" ) . replace ( escClosePattern , "}" ) . replace ( escCommaPattern , "," ) . replace ( escPeriodPattern , "." ) ;
}
function parseCommaParts ( str ) {
if ( ! str ) {
return [ "" ] ;
}
const parts = [ ] ;
const m = balanced ( "{" , "}" , str ) ;
if ( ! m ) {
return str . split ( "," ) ;
}
const { pre , body , post } = m ;
const p = pre . split ( "," ) ;
p [ p . length - 1 ] += "{" + body + "}" ;
const postParts = parseCommaParts ( post ) ;
if ( post . length ) {
;
p [ p . length - 1 ] += postParts . shift ( ) ;
p . push . apply ( p , postParts ) ;
}
parts . push . apply ( parts , p ) ;
return parts ;
}
function expand ( str ) {
if ( ! str ) {
return [ ] ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
if ( str . slice ( 0 , 2 ) === "{}" ) {
str = "\\{\\}" + str . slice ( 2 ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
return expand _ ( escapeBraces ( str ) , true ) . map ( unescapeBraces ) ;
}
function embrace ( str ) {
return "{" + str + "}" ;
}
function isPadded ( el ) {
return /^-?0\d/ . test ( el ) ;
}
function lte ( i , y ) {
return i <= y ;
}
function gte ( i , y ) {
return i >= y ;
}
function expand _ ( str , isTop ) {
const expansions = [ ] ;
const m = balanced ( "{" , "}" , str ) ;
if ( ! m )
return [ str ] ;
const pre = m . pre ;
const post = m . post . length ? expand _ ( m . post , false ) : [ "" ] ;
if ( /\$$/ . test ( m . pre ) ) {
for ( let k = 0 ; k < post . length ; k ++ ) {
const expansion = pre + "{" + m . body + "}" + post [ k ] ;
expansions . push ( expansion ) ;
}
} else {
const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/ . test ( m . body ) ;
const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/ . test ( m . body ) ;
const isSequence = isNumericSequence || isAlphaSequence ;
const isOptions = m . body . indexOf ( "," ) >= 0 ;
if ( ! isSequence && ! isOptions ) {
if ( m . post . match ( /,(?!,).*\}/ ) ) {
str = m . pre + "{" + m . body + escClose + m . post ;
return expand _ ( str ) ;
}
return [ str ] ;
}
let n ;
if ( isSequence ) {
n = m . body . split ( /\.\./ ) ;
} else {
n = parseCommaParts ( m . body ) ;
if ( n . length === 1 && n [ 0 ] !== void 0 ) {
n = expand _ ( n [ 0 ] , false ) . map ( embrace ) ;
if ( n . length === 1 ) {
return post . map ( ( p ) => m . pre + n [ 0 ] + p ) ;
}
}
}
let N ;
if ( isSequence && n [ 0 ] !== void 0 && n [ 1 ] !== void 0 ) {
const x = numeric ( n [ 0 ] ) ;
const y = numeric ( n [ 1 ] ) ;
const width = Math . max ( n [ 0 ] . length , n [ 1 ] . length ) ;
let incr = n . length === 3 && n [ 2 ] !== void 0 ? Math . abs ( numeric ( n [ 2 ] ) ) : 1 ;
let test = lte ;
const reverse = y < x ;
if ( reverse ) {
incr *= - 1 ;
test = gte ;
}
const pad = n . some ( isPadded ) ;
N = [ ] ;
for ( let i = x ; test ( i , y ) ; i += incr ) {
let c ;
if ( isAlphaSequence ) {
c = String . fromCharCode ( i ) ;
if ( c === "\\" ) {
c = "" ;
}
} else {
c = String ( i ) ;
if ( pad ) {
const need = width - c . length ;
if ( need > 0 ) {
const z = new Array ( need + 1 ) . join ( "0" ) ;
if ( i < 0 ) {
c = "-" + z + c . slice ( 1 ) ;
} else {
c = z + c ;
}
}
}
}
N . push ( c ) ;
}
} else {
N = [ ] ;
for ( let j = 0 ; j < n . length ; j ++ ) {
N . push . apply ( N , expand _ ( n [ j ] , false ) ) ;
}
}
for ( let j = 0 ; j < N . length ; j ++ ) {
for ( let k = 0 ; k < post . length ; k ++ ) {
const expansion = pre + N [ j ] + post [ k ] ;
if ( ! isTop || isSequence || expansion ) {
expansions . push ( expansion ) ;
}
}
}
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
return expansions ;
}
2025-08-02 12:09:34 +08:00
2026-05-06 17:32:44 +08:00
// node_modules/.pnpm/minimatch@10.1.1/node_modules/minimatch/dist/esm/assert-valid-pattern.js
var MAX _PATTERN _LENGTH = 1024 * 64 ;
var assertValidPattern = ( pattern ) => {
if ( typeof pattern !== "string" ) {
throw new TypeError ( "invalid pattern" ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
if ( pattern . length > MAX _PATTERN _LENGTH ) {
throw new TypeError ( "pattern is too long" ) ;
}
} ;
// node_modules/.pnpm/minimatch@10.1.1/node_modules/minimatch/dist/esm/brace-expressions.js
var posixClasses = {
"[:alnum:]" : [ "\\p{L}\\p{Nl}\\p{Nd}" , true ] ,
"[:alpha:]" : [ "\\p{L}\\p{Nl}" , true ] ,
"[:ascii:]" : [ "\\x00-\\x7f" , false ] ,
"[:blank:]" : [ "\\p{Zs}\\t" , true ] ,
"[:cntrl:]" : [ "\\p{Cc}" , true ] ,
"[:digit:]" : [ "\\p{Nd}" , true ] ,
"[:graph:]" : [ "\\p{Z}\\p{C}" , true , true ] ,
"[:lower:]" : [ "\\p{Ll}" , true ] ,
"[:print:]" : [ "\\p{C}" , true ] ,
"[:punct:]" : [ "\\p{P}" , true ] ,
"[:space:]" : [ "\\p{Z}\\t\\r\\n\\v\\f" , true ] ,
"[:upper:]" : [ "\\p{Lu}" , true ] ,
"[:word:]" : [ "\\p{L}\\p{Nl}\\p{Nd}\\p{Pc}" , true ] ,
"[:xdigit:]" : [ "A-Fa-f0-9" , false ]
} ;
var braceEscape = ( s ) => s . replace ( /[[\]\\-]/g , "\\$&" ) ;
var regexpEscape = ( s ) => s . replace ( /[-[\]{}()*+?.,\\^$|#\s]/g , "\\$&" ) ;
var rangesToString = ( ranges ) => ranges . join ( "" ) ;
var parseClass = ( glob , position ) => {
const pos = position ;
if ( glob . charAt ( pos ) !== "[" ) {
throw new Error ( "not in a brace expression" ) ;
}
const ranges = [ ] ;
const negs = [ ] ;
let i = pos + 1 ;
let sawStart = false ;
let uflag = false ;
let escaping = false ;
let negate = false ;
let endPos = pos ;
let rangeStart = "" ;
WHILE : while ( i < glob . length ) {
const c = glob . charAt ( i ) ;
if ( ( c === "!" || c === "^" ) && i === pos + 1 ) {
negate = true ;
i ++ ;
continue ;
}
if ( c === "]" && sawStart && ! escaping ) {
endPos = i + 1 ;
break ;
}
sawStart = true ;
if ( c === "\\" ) {
if ( ! escaping ) {
escaping = true ;
i ++ ;
continue ;
2025-08-02 12:09:34 +08:00
}
}
2026-05-06 17:32:44 +08:00
if ( c === "[" && ! escaping ) {
for ( const [ cls , [ unip , u , neg ] ] of Object . entries ( posixClasses ) ) {
if ( glob . startsWith ( cls , i ) ) {
if ( rangeStart ) {
return [ "$." , false , glob . length - pos , true ] ;
}
i += cls . length ;
if ( neg )
negs . push ( unip ) ;
else
ranges . push ( unip ) ;
uflag = uflag || u ;
continue WHILE ;
}
}
}
escaping = false ;
if ( rangeStart ) {
if ( c > rangeStart ) {
ranges . push ( braceEscape ( rangeStart ) + "-" + braceEscape ( c ) ) ;
} else if ( c === rangeStart ) {
ranges . push ( braceEscape ( c ) ) ;
}
rangeStart = "" ;
i ++ ;
continue ;
}
if ( glob . startsWith ( "-]" , i + 1 ) ) {
ranges . push ( braceEscape ( c + "-" ) ) ;
i += 2 ;
continue ;
}
if ( glob . startsWith ( "-" , i + 1 ) ) {
rangeStart = c ;
i += 2 ;
continue ;
}
ranges . push ( braceEscape ( c ) ) ;
i ++ ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
if ( endPos < i ) {
return [ "" , false , 0 , false ] ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
if ( ! ranges . length && ! negs . length ) {
return [ "$." , false , glob . length - pos , true ] ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
if ( negs . length === 0 && ranges . length === 1 && /^\\?.$/ . test ( ranges [ 0 ] ) && ! negate ) {
const r = ranges [ 0 ] . length === 2 ? ranges [ 0 ] . slice ( - 1 ) : ranges [ 0 ] ;
return [ regexpEscape ( r ) , false , endPos - pos , false ] ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
const sranges = "[" + ( negate ? "^" : "" ) + rangesToString ( ranges ) + "]" ;
const snegs = "[" + ( negate ? "" : "^" ) + rangesToString ( negs ) + "]" ;
const comb = ranges . length && negs . length ? "(" + sranges + "|" + snegs + ")" : ranges . length ? sranges : snegs ;
return [ comb , uflag , endPos - pos , true ] ;
2025-08-02 12:09:34 +08:00
} ;
2026-05-06 17:32:44 +08:00
// node_modules/.pnpm/minimatch@10.1.1/node_modules/minimatch/dist/esm/unescape.js
var unescape = ( s , { windowsPathsNoEscape = false , magicalBraces = true } = { } ) => {
if ( magicalBraces ) {
return windowsPathsNoEscape ? s . replace ( /\[([^\/\\])\]/g , "$1" ) : s . replace ( /((?!\\).|^)\[([^\/\\])\]/g , "$1$2" ) . replace ( /\\([^\/])/g , "$1" ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
return windowsPathsNoEscape ? s . replace ( /\[([^\/\\{}])\]/g , "$1" ) : s . replace ( /((?!\\).|^)\[([^\/\\{}])\]/g , "$1$2" ) . replace ( /\\([^\/{}])/g , "$1" ) ;
} ;
// node_modules/.pnpm/minimatch@10.1.1/node_modules/minimatch/dist/esm/ast.js
var types = /* @__PURE__ */ new Set ( [ "!" , "?" , "+" , "*" , "@" ] ) ;
var isExtglobType = ( c ) => types . has ( c ) ;
var startNoTraversal = "(?!(?:^|/)\\.\\.?(?:$|/))" ;
var startNoDot = "(?!\\.)" ;
var addPatternStart = /* @__PURE__ */ new Set ( [ "[" , "." ] ) ;
var justDots = /* @__PURE__ */ new Set ( [ ".." , "." ] ) ;
var reSpecials = new Set ( "().*{}+?[]^$\\!" ) ;
var regExpEscape = ( s ) => s . replace ( /[-[\]{}()*+?.,\\^$|#\s]/g , "\\$&" ) ;
var qmark = "[^/]" ;
var star = qmark + "*?" ;
var starNoEmpty = qmark + "+?" ;
var _root , _hasMagic , _uflag , _parts , _parent , _parentIndex , _negs , _filledNegs , _options , _toString , _emptyExt , _AST _instances , fillNegs _fn , _AST _static , parseAST _fn , partsToRegExp _fn , parseGlob _fn ;
var _AST = class _AST {
constructor ( type , parent , options = { } ) {
_ _privateAdd ( this , _AST _instances ) ;
_ _publicField ( this , "type" ) ;
_ _privateAdd ( this , _root ) ;
_ _privateAdd ( this , _hasMagic ) ;
_ _privateAdd ( this , _uflag , false ) ;
_ _privateAdd ( this , _parts , [ ] ) ;
_ _privateAdd ( this , _parent ) ;
_ _privateAdd ( this , _parentIndex ) ;
_ _privateAdd ( this , _negs ) ;
_ _privateAdd ( this , _filledNegs , false ) ;
_ _privateAdd ( this , _options ) ;
_ _privateAdd ( this , _toString ) ;
// set to true if it's an extglob with no children
// (which really means one child of '')
_ _privateAdd ( this , _emptyExt , false ) ;
this . type = type ;
if ( type )
_ _privateSet ( this , _hasMagic , true ) ;
_ _privateSet ( this , _parent , parent ) ;
_ _privateSet ( this , _root , _ _privateGet ( this , _parent ) ? _ _privateGet ( _ _privateGet ( this , _parent ) , _root ) : this ) ;
_ _privateSet ( this , _options , _ _privateGet ( this , _root ) === this ? options : _ _privateGet ( _ _privateGet ( this , _root ) , _options ) ) ;
_ _privateSet ( this , _negs , _ _privateGet ( this , _root ) === this ? [ ] : _ _privateGet ( _ _privateGet ( this , _root ) , _negs ) ) ;
if ( type === "!" && ! _ _privateGet ( _ _privateGet ( this , _root ) , _filledNegs ) )
_ _privateGet ( this , _negs ) . push ( this ) ;
_ _privateSet ( this , _parentIndex , _ _privateGet ( this , _parent ) ? _ _privateGet ( _ _privateGet ( this , _parent ) , _parts ) . length : 0 ) ;
}
get hasMagic ( ) {
if ( _ _privateGet ( this , _hasMagic ) !== void 0 )
return _ _privateGet ( this , _hasMagic ) ;
for ( const p of _ _privateGet ( this , _parts ) ) {
if ( typeof p === "string" )
continue ;
if ( p . type || p . hasMagic )
return _ _privateSet ( this , _hasMagic , true ) ;
}
return _ _privateGet ( this , _hasMagic ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
// reconstructs the pattern
toString ( ) {
if ( _ _privateGet ( this , _toString ) !== void 0 )
return _ _privateGet ( this , _toString ) ;
if ( ! this . type ) {
return _ _privateSet ( this , _toString , _ _privateGet ( this , _parts ) . map ( ( p ) => String ( p ) ) . join ( "" ) ) ;
} else {
return _ _privateSet ( this , _toString , this . type + "(" + _ _privateGet ( this , _parts ) . map ( ( p ) => String ( p ) ) . join ( "|" ) + ")" ) ;
}
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
push ( ... parts ) {
for ( const p of parts ) {
if ( p === "" )
continue ;
if ( typeof p !== "string" && ! ( p instanceof _AST && _ _privateGet ( p , _parent ) === this ) ) {
throw new Error ( "invalid part: " + p ) ;
}
_ _privateGet ( this , _parts ) . push ( p ) ;
}
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
toJSON ( ) {
2025-08-02 12:09:34 +08:00
var _a ;
2026-05-06 17:32:44 +08:00
const ret = this . type === null ? _ _privateGet ( this , _parts ) . slice ( ) . map ( ( p ) => typeof p === "string" ? p : p . toJSON ( ) ) : [ this . type , ... _ _privateGet ( this , _parts ) . map ( ( p ) => p . toJSON ( ) ) ] ;
if ( this . isStart ( ) && ! this . type )
ret . unshift ( [ ] ) ;
if ( this . isEnd ( ) && ( this === _ _privateGet ( this , _root ) || _ _privateGet ( _ _privateGet ( this , _root ) , _filledNegs ) && ( ( _a = _ _privateGet ( this , _parent ) ) == null ? void 0 : _a . type ) === "!" ) ) {
ret . push ( { } ) ;
}
return ret ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
isStart ( ) {
var _a ;
if ( _ _privateGet ( this , _root ) === this )
return true ;
if ( ! ( ( _a = _ _privateGet ( this , _parent ) ) == null ? void 0 : _a . isStart ( ) ) )
return false ;
if ( _ _privateGet ( this , _parentIndex ) === 0 )
return true ;
const p = _ _privateGet ( this , _parent ) ;
for ( let i = 0 ; i < _ _privateGet ( this , _parentIndex ) ; i ++ ) {
const pp = _ _privateGet ( p , _parts ) [ i ] ;
if ( ! ( pp instanceof _AST && pp . type === "!" ) ) {
return false ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
}
return true ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
isEnd ( ) {
var _a , _b , _c ;
if ( _ _privateGet ( this , _root ) === this )
return true ;
if ( ( ( _a = _ _privateGet ( this , _parent ) ) == null ? void 0 : _a . type ) === "!" )
return true ;
if ( ! ( ( _b = _ _privateGet ( this , _parent ) ) == null ? void 0 : _b . isEnd ( ) ) )
return false ;
if ( ! this . type )
return ( _c = _ _privateGet ( this , _parent ) ) == null ? void 0 : _c . isEnd ( ) ;
const pl = _ _privateGet ( this , _parent ) ? _ _privateGet ( _ _privateGet ( this , _parent ) , _parts ) . length : 0 ;
return _ _privateGet ( this , _parentIndex ) === pl - 1 ;
}
copyIn ( part ) {
if ( typeof part === "string" )
this . push ( part ) ;
else
this . push ( part . clone ( this ) ) ;
}
clone ( parent ) {
const c = new _AST ( this . type , parent ) ;
for ( const p of _ _privateGet ( this , _parts ) ) {
c . copyIn ( p ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
return c ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
static fromGlob ( pattern , options = { } ) {
var _a ;
const ast = new _AST ( null , void 0 , options ) ;
_ _privateMethod ( _a = _AST , _AST _static , parseAST _fn ) . call ( _a , pattern , ast , 0 , options ) ;
return ast ;
}
// returns the regular expression if there's magic, or the unescaped
// string if not.
toMMPattern ( ) {
if ( this !== _ _privateGet ( this , _root ) )
return _ _privateGet ( this , _root ) . toMMPattern ( ) ;
const glob = this . toString ( ) ;
const [ re , body , hasMagic , uflag ] = this . toRegExpSource ( ) ;
const anyMagic = hasMagic || _ _privateGet ( this , _hasMagic ) || _ _privateGet ( this , _options ) . nocase && ! _ _privateGet ( this , _options ) . nocaseMagicOnly && glob . toUpperCase ( ) !== glob . toLowerCase ( ) ;
if ( ! anyMagic ) {
return body ;
}
const flags = ( _ _privateGet ( this , _options ) . nocase ? "i" : "" ) + ( uflag ? "u" : "" ) ;
return Object . assign ( new RegExp ( ` ^ ${ re } $ ` , flags ) , {
_src : re ,
_glob : glob
} ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
get options ( ) {
return _ _privateGet ( this , _options ) ;
}
// returns the string match, the regexp source, whether there's magic
// in the regexp (so a regular expression is required) and whether or
// not the uflag is needed for the regular expression (for posix classes)
// TODO: instead of injecting the start/end at this point, just return
// the BODY of the regexp, along with the start/end portions suitable
// for binding the start/end in either a joined full-path makeRe context
// (where we bind to (^|/), or a standalone matchPart context (where
// we bind to ^, and not /). Otherwise slashes get duped!
//
// In part-matching mode, the start is:
// - if not isStart: nothing
// - if traversal possible, but not allowed: ^(?!\.\.?$)
// - if dots allowed or not possible: ^
// - if dots possible and not allowed: ^(?!\.)
// end is:
// - if not isEnd(): nothing
// - else: $
//
// In full-path matching mode, we put the slash at the START of the
// pattern, so start is:
// - if first pattern: same as part-matching mode
// - if not isStart(): nothing
// - if traversal possible, but not allowed: /(?!\.\.?(?:$|/))
// - if dots allowed or not possible: /
// - if dots possible and not allowed: /(?!\.)
// end is:
// - if last pattern, same as part-matching mode
// - else nothing
//
// Always put the (?:$|/) on negated tails, though, because that has to be
// there to bind the end of the negated pattern portion, and it's easier to
// just stick it in now rather than try to inject it later in the middle of
// the pattern.
//
// We can just always return the same end, and leave it up to the caller
// to know whether it's going to be used joined or in parts.
// And, if the start is adjusted slightly, can do the same there:
// - if not isStart: nothing
// - if traversal possible, but not allowed: (?:/|^)(?!\.\.?$)
// - if dots allowed or not possible: (?:/|^)
// - if dots possible and not allowed: (?:/|^)(?!\.)
//
// But it's better to have a simpler binding without a conditional, for
// performance, so probably better to return both start options.
//
// Then the caller just ignores the end if it's not the first pattern,
// and the start always gets applied.
//
// But that's always going to be $ if it's the ending pattern, or nothing,
// so the caller can just attach $ at the end of the pattern when building.
//
// So the todo is:
// - better detect what kind of start is needed
// - return both flavors of starting pattern
// - attach $ at the end of the pattern when creating the actual RegExp
//
// Ah, but wait, no, that all only applies to the root when the first pattern
// is not an extglob. If the first pattern IS an extglob, then we need all
// that dot prevention biz to live in the extglob portions, because eg
// +(*|.x*) can match .xy but not .yx.
//
// So, return the two flavors if it's #root and the first child is not an
// AST, otherwise leave it to the child AST to handle it, and there,
// use the (?:^|/) style of start binding.
//
// Even simplified further:
// - Since the start for a join is eg /(?!\.) and the start for a part
// is ^(?!\.), we can just prepend (?!\.) to the pattern (either root
// or start or whatever) and prepend ^ or / at the Regexp construction.
toRegExpSource ( allowDot ) {
var _a ;
const dot = allowDot != null ? allowDot : ! ! _ _privateGet ( this , _options ) . dot ;
if ( _ _privateGet ( this , _root ) === this )
_ _privateMethod ( this , _AST _instances , fillNegs _fn ) . call ( this ) ;
if ( ! this . type ) {
const noEmpty = this . isStart ( ) && this . isEnd ( ) && ! _ _privateGet ( this , _parts ) . some ( ( s ) => typeof s !== "string" ) ;
const src = _ _privateGet ( this , _parts ) . map ( ( p ) => {
var _a2 ;
const [ re , _ , hasMagic , uflag ] = typeof p === "string" ? _ _privateMethod ( _a2 = _AST , _AST _static , parseGlob _fn ) . call ( _a2 , p , _ _privateGet ( this , _hasMagic ) , noEmpty ) : p . toRegExpSource ( allowDot ) ;
_ _privateSet ( this , _hasMagic , _ _privateGet ( this , _hasMagic ) || hasMagic ) ;
_ _privateSet ( this , _uflag , _ _privateGet ( this , _uflag ) || uflag ) ;
return re ;
} ) . join ( "" ) ;
let start2 = "" ;
if ( this . isStart ( ) ) {
if ( typeof _ _privateGet ( this , _parts ) [ 0 ] === "string" ) {
const dotTravAllowed = _ _privateGet ( this , _parts ) . length === 1 && justDots . has ( _ _privateGet ( this , _parts ) [ 0 ] ) ;
if ( ! dotTravAllowed ) {
const aps = addPatternStart ;
const needNoTrav = (
// dots are allowed, and the pattern starts with [ or .
dot && aps . has ( src . charAt ( 0 ) ) || // the pattern starts with \., and then [ or .
src . startsWith ( "\\." ) && aps . has ( src . charAt ( 2 ) ) || // the pattern starts with \.\., and then [ or .
src . startsWith ( "\\.\\." ) && aps . has ( src . charAt ( 4 ) )
) ;
const needNoDot = ! dot && ! allowDot && aps . has ( src . charAt ( 0 ) ) ;
start2 = needNoTrav ? startNoTraversal : needNoDot ? startNoDot : "" ;
}
}
}
let end = "" ;
if ( this . isEnd ( ) && _ _privateGet ( _ _privateGet ( this , _root ) , _filledNegs ) && ( ( _a = _ _privateGet ( this , _parent ) ) == null ? void 0 : _a . type ) === "!" ) {
end = "(?:$|\\/)" ;
}
const final2 = start2 + src + end ;
return [
final2 ,
unescape ( src ) ,
_ _privateSet ( this , _hasMagic , ! ! _ _privateGet ( this , _hasMagic ) ) ,
_ _privateGet ( this , _uflag )
] ;
}
const repeated = this . type === "*" || this . type === "+" ;
const start = this . type === "!" ? "(?:(?!(?:" : "(?:" ;
let body = _ _privateMethod ( this , _AST _instances , partsToRegExp _fn ) . call ( this , dot ) ;
if ( this . isStart ( ) && this . isEnd ( ) && ! body && this . type !== "!" ) {
const s = this . toString ( ) ;
_ _privateSet ( this , _parts , [ s ] ) ;
this . type = null ;
_ _privateSet ( this , _hasMagic , void 0 ) ;
return [ s , unescape ( this . toString ( ) ) , false , false ] ;
}
let bodyDotAllowed = ! repeated || allowDot || dot || ! startNoDot ? "" : _ _privateMethod ( this , _AST _instances , partsToRegExp _fn ) . call ( this , true ) ;
if ( bodyDotAllowed === body ) {
bodyDotAllowed = "" ;
}
if ( bodyDotAllowed ) {
body = ` (?: ${ body } )(?: ${ bodyDotAllowed } )*? ` ;
}
let final = "" ;
if ( this . type === "!" && _ _privateGet ( this , _emptyExt ) ) {
final = ( this . isStart ( ) && ! dot ? startNoDot : "" ) + starNoEmpty ;
} else {
const close = this . type === "!" ? (
// !() must match something,but !(x) can match ''
"))" + ( this . isStart ( ) && ! dot && ! allowDot ? startNoDot : "" ) + star + ")"
) : this . type === "@" ? ")" : this . type === "?" ? ")?" : this . type === "+" && bodyDotAllowed ? ")" : this . type === "*" && bodyDotAllowed ? ` )? ` : ` ) ${ this . type } ` ;
final = start + body + close ;
}
return [
final ,
unescape ( body ) ,
_ _privateSet ( this , _hasMagic , ! ! _ _privateGet ( this , _hasMagic ) ) ,
_ _privateGet ( this , _uflag )
] ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
} ;
_root = new WeakMap ( ) ;
_hasMagic = new WeakMap ( ) ;
_uflag = new WeakMap ( ) ;
_parts = new WeakMap ( ) ;
_parent = new WeakMap ( ) ;
_parentIndex = new WeakMap ( ) ;
_negs = new WeakMap ( ) ;
_filledNegs = new WeakMap ( ) ;
_options = new WeakMap ( ) ;
_toString = new WeakMap ( ) ;
_emptyExt = new WeakMap ( ) ;
_AST _instances = new WeakSet ( ) ;
fillNegs _fn = function ( ) {
if ( this !== _ _privateGet ( this , _root ) )
throw new Error ( "should only call on root" ) ;
if ( _ _privateGet ( this , _filledNegs ) )
return this ;
this . toString ( ) ;
_ _privateSet ( this , _filledNegs , true ) ;
let n ;
while ( n = _ _privateGet ( this , _negs ) . pop ( ) ) {
if ( n . type !== "!" )
continue ;
let p = n ;
let pp = _ _privateGet ( p , _parent ) ;
while ( pp ) {
for ( let i = _ _privateGet ( p , _parentIndex ) + 1 ; ! pp . type && i < _ _privateGet ( pp , _parts ) . length ; i ++ ) {
for ( const part of _ _privateGet ( n , _parts ) ) {
if ( typeof part === "string" ) {
throw new Error ( "string part in extglob AST??" ) ;
}
part . copyIn ( _ _privateGet ( pp , _parts ) [ i ] ) ;
}
}
p = pp ;
pp = _ _privateGet ( p , _parent ) ;
}
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
return this ;
2025-08-02 12:09:34 +08:00
} ;
2026-05-06 17:32:44 +08:00
_AST _static = new WeakSet ( ) ;
parseAST _fn = function ( str , ast , pos , opt ) {
var _a , _b ;
let escaping = false ;
let inBrace = false ;
let braceStart = - 1 ;
let braceNeg = false ;
if ( ast . type === null ) {
let i2 = pos ;
let acc2 = "" ;
while ( i2 < str . length ) {
const c = str . charAt ( i2 ++ ) ;
if ( escaping || c === "\\" ) {
escaping = ! escaping ;
acc2 += c ;
continue ;
}
if ( inBrace ) {
if ( i2 === braceStart + 1 ) {
if ( c === "^" || c === "!" ) {
braceNeg = true ;
}
} else if ( c === "]" && ! ( i2 === braceStart + 2 && braceNeg ) ) {
inBrace = false ;
}
acc2 += c ;
continue ;
} else if ( c === "[" ) {
inBrace = true ;
braceStart = i2 ;
braceNeg = false ;
acc2 += c ;
continue ;
}
if ( ! opt . noext && isExtglobType ( c ) && str . charAt ( i2 ) === "(" ) {
ast . push ( acc2 ) ;
acc2 = "" ;
const ext2 = new _AST ( c , ast ) ;
i2 = _ _privateMethod ( _a = _AST , _AST _static , parseAST _fn ) . call ( _a , str , ext2 , i2 , opt ) ;
ast . push ( ext2 ) ;
continue ;
}
acc2 += c ;
}
ast . push ( acc2 ) ;
return i2 ;
}
let i = pos + 1 ;
let part = new _AST ( null , ast ) ;
const parts = [ ] ;
let acc = "" ;
while ( i < str . length ) {
const c = str . charAt ( i ++ ) ;
if ( escaping || c === "\\" ) {
escaping = ! escaping ;
acc += c ;
continue ;
}
if ( inBrace ) {
if ( i === braceStart + 1 ) {
if ( c === "^" || c === "!" ) {
braceNeg = true ;
}
} else if ( c === "]" && ! ( i === braceStart + 2 && braceNeg ) ) {
inBrace = false ;
}
acc += c ;
continue ;
} else if ( c === "[" ) {
inBrace = true ;
braceStart = i ;
braceNeg = false ;
acc += c ;
continue ;
}
if ( isExtglobType ( c ) && str . charAt ( i ) === "(" ) {
part . push ( acc ) ;
acc = "" ;
const ext2 = new _AST ( c , part ) ;
part . push ( ext2 ) ;
i = _ _privateMethod ( _b = _AST , _AST _static , parseAST _fn ) . call ( _b , str , ext2 , i , opt ) ;
continue ;
}
if ( c === "|" ) {
part . push ( acc ) ;
acc = "" ;
parts . push ( part ) ;
part = new _AST ( null , ast ) ;
continue ;
}
if ( c === ")" ) {
if ( acc === "" && _ _privateGet ( ast , _parts ) . length === 0 ) {
_ _privateSet ( ast , _emptyExt , true ) ;
}
part . push ( acc ) ;
acc = "" ;
ast . push ( ... parts , part ) ;
return i ;
}
acc += c ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
ast . type = null ;
_ _privateSet ( ast , _hasMagic , void 0 ) ;
_ _privateSet ( ast , _parts , [ str . substring ( pos - 1 ) ] ) ;
return i ;
} ;
partsToRegExp _fn = function ( dot ) {
return _ _privateGet ( this , _parts ) . map ( ( p ) => {
if ( typeof p === "string" ) {
throw new Error ( "string type in extglob ast??" ) ;
}
const [ re , _ , _hasMagic2 , uflag ] = p . toRegExpSource ( dot ) ;
_ _privateSet ( this , _uflag , _ _privateGet ( this , _uflag ) || uflag ) ;
return re ;
} ) . filter ( ( p ) => ! ( this . isStart ( ) && this . isEnd ( ) ) || ! ! p ) . join ( "|" ) ;
} ;
parseGlob _fn = function ( glob , hasMagic , noEmpty = false ) {
let escaping = false ;
let re = "" ;
let uflag = false ;
for ( let i = 0 ; i < glob . length ; i ++ ) {
const c = glob . charAt ( i ) ;
if ( escaping ) {
escaping = false ;
re += ( reSpecials . has ( c ) ? "\\" : "" ) + c ;
continue ;
}
if ( c === "\\" ) {
if ( i === glob . length - 1 ) {
re += "\\\\" ;
} else {
escaping = true ;
}
continue ;
}
if ( c === "[" ) {
const [ src , needUflag , consumed , magic ] = parseClass ( glob , i ) ;
if ( consumed ) {
re += src ;
uflag = uflag || needUflag ;
i += consumed - 1 ;
hasMagic = hasMagic || magic ;
continue ;
}
}
if ( c === "*" ) {
re += noEmpty && glob === "*" ? starNoEmpty : star ;
hasMagic = true ;
continue ;
}
if ( c === "?" ) {
re += qmark ;
hasMagic = true ;
continue ;
}
re += regExpEscape ( c ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
return [ re , unescape ( glob ) , ! ! hasMagic , uflag ] ;
} ;
_ _privateAdd ( _AST , _AST _static ) ;
var AST = _AST ;
// node_modules/.pnpm/minimatch@10.1.1/node_modules/minimatch/dist/esm/escape.js
var escape = ( s , { windowsPathsNoEscape = false , magicalBraces = false } = { } ) => {
if ( magicalBraces ) {
return windowsPathsNoEscape ? s . replace ( /[?*()[\]{}]/g , "[$&]" ) : s . replace ( /[?*()[\]\\{}]/g , "\\$&" ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
return windowsPathsNoEscape ? s . replace ( /[?*()[\]]/g , "[$&]" ) : s . replace ( /[?*()[\]\\]/g , "\\$&" ) ;
2025-08-02 12:09:34 +08:00
} ;
2026-05-06 17:32:44 +08:00
// node_modules/.pnpm/minimatch@10.1.1/node_modules/minimatch/dist/esm/index.js
var minimatch = ( p , pattern , options = { } ) => {
assertValidPattern ( pattern ) ;
if ( ! options . nocomment && pattern . charAt ( 0 ) === "#" ) {
return false ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
return new Minimatch ( pattern , options ) . match ( p ) ;
} ;
var starDotExtRE = /^\*+([^+@!?\*\[\(]*)$/ ;
var starDotExtTest = ( ext2 ) => ( f ) => ! f . startsWith ( "." ) && f . endsWith ( ext2 ) ;
var starDotExtTestDot = ( ext2 ) => ( f ) => f . endsWith ( ext2 ) ;
var starDotExtTestNocase = ( ext2 ) => {
ext2 = ext2 . toLowerCase ( ) ;
return ( f ) => ! f . startsWith ( "." ) && f . toLowerCase ( ) . endsWith ( ext2 ) ;
} ;
var starDotExtTestNocaseDot = ( ext2 ) => {
ext2 = ext2 . toLowerCase ( ) ;
return ( f ) => f . toLowerCase ( ) . endsWith ( ext2 ) ;
} ;
var starDotStarRE = /^\*+\.\*+$/ ;
var starDotStarTest = ( f ) => ! f . startsWith ( "." ) && f . includes ( "." ) ;
var starDotStarTestDot = ( f ) => f !== "." && f !== ".." && f . includes ( "." ) ;
var dotStarRE = /^\.\*+$/ ;
var dotStarTest = ( f ) => f !== "." && f !== ".." && f . startsWith ( "." ) ;
var starRE = /^\*+$/ ;
var starTest = ( f ) => f . length !== 0 && ! f . startsWith ( "." ) ;
var starTestDot = ( f ) => f . length !== 0 && f !== "." && f !== ".." ;
var qmarksRE = /^\?+([^+@!?\*\[\(]*)?$/ ;
var qmarksTestNocase = ( [ $0 , ext2 = "" ] ) => {
const noext = qmarksTestNoExt ( [ $0 ] ) ;
if ( ! ext2 )
return noext ;
ext2 = ext2 . toLowerCase ( ) ;
return ( f ) => noext ( f ) && f . toLowerCase ( ) . endsWith ( ext2 ) ;
} ;
var qmarksTestNocaseDot = ( [ $0 , ext2 = "" ] ) => {
const noext = qmarksTestNoExtDot ( [ $0 ] ) ;
if ( ! ext2 )
return noext ;
ext2 = ext2 . toLowerCase ( ) ;
return ( f ) => noext ( f ) && f . toLowerCase ( ) . endsWith ( ext2 ) ;
} ;
var qmarksTestDot = ( [ $0 , ext2 = "" ] ) => {
const noext = qmarksTestNoExtDot ( [ $0 ] ) ;
return ! ext2 ? noext : ( f ) => noext ( f ) && f . endsWith ( ext2 ) ;
} ;
var qmarksTest = ( [ $0 , ext2 = "" ] ) => {
const noext = qmarksTestNoExt ( [ $0 ] ) ;
return ! ext2 ? noext : ( f ) => noext ( f ) && f . endsWith ( ext2 ) ;
} ;
var qmarksTestNoExt = ( [ $0 ] ) => {
const len = $0 . length ;
return ( f ) => f . length === len && ! f . startsWith ( "." ) ;
} ;
var qmarksTestNoExtDot = ( [ $0 ] ) => {
const len = $0 . length ;
return ( f ) => f . length === len && f !== "." && f !== ".." ;
} ;
var defaultPlatform = typeof process === "object" && process ? typeof process . env === "object" && process . env && process . env . _ _MINIMATCH _TESTING _PLATFORM _ _ || process . platform : "posix" ;
var path = {
win32 : { sep : "\\" } ,
posix : { sep : "/" }
} ;
var sep = defaultPlatform === "win32" ? path . win32 . sep : path . posix . sep ;
minimatch . sep = sep ;
var GLOBSTAR = /* @__PURE__ */ Symbol ( "globstar **" ) ;
minimatch . GLOBSTAR = GLOBSTAR ;
var qmark2 = "[^/]" ;
var star2 = qmark2 + "*?" ;
var twoStarDot = "(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?" ;
var twoStarNoDot = "(?:(?!(?:\\/|^)\\.).)*?" ;
var filter = ( pattern , options = { } ) => ( p ) => minimatch ( p , pattern , options ) ;
minimatch . filter = filter ;
var ext = ( a , b = { } ) => Object . assign ( { } , a , b ) ;
var defaults = ( def ) => {
if ( ! def || typeof def !== "object" || ! Object . keys ( def ) . length ) {
return minimatch ;
}
const orig = minimatch ;
const m = ( p , pattern , options = { } ) => orig ( p , pattern , ext ( def , options ) ) ;
return Object . assign ( m , {
Minimatch : class Minimatch extends orig . Minimatch {
constructor ( pattern , options = { } ) {
super ( pattern , ext ( def , options ) ) ;
}
static defaults ( options ) {
return orig . defaults ( ext ( def , options ) ) . Minimatch ;
}
} ,
AST : class AST extends orig . AST {
/* c8 ignore start */
constructor ( type , parent , options = { } ) {
super ( type , parent , ext ( def , options ) ) ;
}
/* c8 ignore stop */
static fromGlob ( pattern , options = { } ) {
return orig . AST . fromGlob ( pattern , ext ( def , options ) ) ;
}
} ,
unescape : ( s , options = { } ) => orig . unescape ( s , ext ( def , options ) ) ,
escape : ( s , options = { } ) => orig . escape ( s , ext ( def , options ) ) ,
filter : ( pattern , options = { } ) => orig . filter ( pattern , ext ( def , options ) ) ,
defaults : ( options ) => orig . defaults ( ext ( def , options ) ) ,
makeRe : ( pattern , options = { } ) => orig . makeRe ( pattern , ext ( def , options ) ) ,
braceExpand : ( pattern , options = { } ) => orig . braceExpand ( pattern , ext ( def , options ) ) ,
match : ( list , pattern , options = { } ) => orig . match ( list , pattern , ext ( def , options ) ) ,
sep : orig . sep ,
GLOBSTAR
} ) ;
} ;
minimatch . defaults = defaults ;
var braceExpand = ( pattern , options = { } ) => {
assertValidPattern ( pattern ) ;
if ( options . nobrace || ! /\{(?:(?!\{).)*\}/ . test ( pattern ) ) {
return [ pattern ] ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
return expand ( pattern ) ;
} ;
minimatch . braceExpand = braceExpand ;
var makeRe = ( pattern , options = { } ) => new Minimatch ( pattern , options ) . makeRe ( ) ;
minimatch . makeRe = makeRe ;
var match = ( list , pattern , options = { } ) => {
const mm = new Minimatch ( pattern , options ) ;
list = list . filter ( ( f ) => mm . match ( f ) ) ;
if ( mm . options . nonull && ! list . length ) {
list . push ( pattern ) ;
}
return list ;
} ;
minimatch . match = match ;
var globMagic = /[?*]|[+@!]\(.*?\)|\[|\]/ ;
var regExpEscape2 = ( s ) => s . replace ( /[-[\]{}()*+?.,\\^$|#\s]/g , "\\$&" ) ;
var Minimatch = class {
constructor ( pattern , options = { } ) {
_ _publicField ( this , "options" ) ;
_ _publicField ( this , "set" ) ;
_ _publicField ( this , "pattern" ) ;
_ _publicField ( this , "windowsPathsNoEscape" ) ;
_ _publicField ( this , "nonegate" ) ;
_ _publicField ( this , "negate" ) ;
_ _publicField ( this , "comment" ) ;
_ _publicField ( this , "empty" ) ;
_ _publicField ( this , "preserveMultipleSlashes" ) ;
_ _publicField ( this , "partial" ) ;
_ _publicField ( this , "globSet" ) ;
_ _publicField ( this , "globParts" ) ;
_ _publicField ( this , "nocase" ) ;
_ _publicField ( this , "isWindows" ) ;
_ _publicField ( this , "platform" ) ;
_ _publicField ( this , "windowsNoMagicRoot" ) ;
_ _publicField ( this , "regexp" ) ;
assertValidPattern ( pattern ) ;
options = options || { } ;
this . options = options ;
this . pattern = pattern ;
this . platform = options . platform || defaultPlatform ;
this . isWindows = this . platform === "win32" ;
this . windowsPathsNoEscape = ! ! options . windowsPathsNoEscape || options . allowWindowsEscape === false ;
if ( this . windowsPathsNoEscape ) {
this . pattern = this . pattern . replace ( /\\/g , "/" ) ;
}
this . preserveMultipleSlashes = ! ! options . preserveMultipleSlashes ;
this . regexp = null ;
this . negate = false ;
this . nonegate = ! ! options . nonegate ;
this . comment = false ;
this . empty = false ;
this . partial = ! ! options . partial ;
this . nocase = ! ! this . options . nocase ;
this . windowsNoMagicRoot = options . windowsNoMagicRoot !== void 0 ? options . windowsNoMagicRoot : ! ! ( this . isWindows && this . nocase ) ;
this . globSet = [ ] ;
this . globParts = [ ] ;
this . set = [ ] ;
this . make ( ) ;
}
hasMagic ( ) {
if ( this . options . magicalBraces && this . set . length > 1 ) {
return true ;
}
for ( const pattern of this . set ) {
for ( const part of pattern ) {
if ( typeof part !== "string" )
return true ;
}
}
return false ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
debug ( ... _ ) {
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
make ( ) {
const pattern = this . pattern ;
const options = this . options ;
if ( ! options . nocomment && pattern . charAt ( 0 ) === "#" ) {
this . comment = true ;
return ;
}
if ( ! pattern ) {
this . empty = true ;
return ;
}
this . parseNegate ( ) ;
this . globSet = [ ... new Set ( this . braceExpand ( ) ) ] ;
if ( options . debug ) {
this . debug = ( ... args ) => console . error ( ... args ) ;
}
this . debug ( this . pattern , this . globSet ) ;
const rawGlobParts = this . globSet . map ( ( s ) => this . slashSplit ( s ) ) ;
this . globParts = this . preprocess ( rawGlobParts ) ;
this . debug ( this . pattern , this . globParts ) ;
let set = this . globParts . map ( ( s , _ , _ _ ) => {
if ( this . isWindows && this . windowsNoMagicRoot ) {
const isUNC = s [ 0 ] === "" && s [ 1 ] === "" && ( s [ 2 ] === "?" || ! globMagic . test ( s [ 2 ] ) ) && ! globMagic . test ( s [ 3 ] ) ;
const isDrive = /^[a-z]:/i . test ( s [ 0 ] ) ;
if ( isUNC ) {
return [ ... s . slice ( 0 , 4 ) , ... s . slice ( 4 ) . map ( ( ss ) => this . parse ( ss ) ) ] ;
} else if ( isDrive ) {
return [ s [ 0 ] , ... s . slice ( 1 ) . map ( ( ss ) => this . parse ( ss ) ) ] ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
}
return s . map ( ( ss ) => this . parse ( ss ) ) ;
} ) ;
this . debug ( this . pattern , set ) ;
this . set = set . filter ( ( s ) => s . indexOf ( false ) === - 1 ) ;
if ( this . isWindows ) {
for ( let i = 0 ; i < this . set . length ; i ++ ) {
const p = this . set [ i ] ;
if ( p [ 0 ] === "" && p [ 1 ] === "" && this . globParts [ i ] [ 2 ] === "?" && typeof p [ 3 ] === "string" && /^[a-z]:$/i . test ( p [ 3 ] ) ) {
p [ 2 ] = "?" ;
2025-08-02 12:09:34 +08:00
}
}
2026-05-06 17:32:44 +08:00
}
this . debug ( this . pattern , this . set ) ;
}
// various transforms to equivalent pattern sets that are
// faster to process in a filesystem walk. The goal is to
// eliminate what we can, and push all ** patterns as far
// to the right as possible, even if it increases the number
// of patterns that we have to process.
preprocess ( globParts ) {
if ( this . options . noglobstar ) {
for ( let i = 0 ; i < globParts . length ; i ++ ) {
for ( let j = 0 ; j < globParts [ i ] . length ; j ++ ) {
if ( globParts [ i ] [ j ] === "**" ) {
globParts [ i ] [ j ] = "*" ;
}
}
2025-08-02 12:09:34 +08:00
}
}
2026-05-06 17:32:44 +08:00
const { optimizationLevel = 1 } = this . options ;
if ( optimizationLevel >= 2 ) {
globParts = this . firstPhasePreProcess ( globParts ) ;
globParts = this . secondPhasePreProcess ( globParts ) ;
} else if ( optimizationLevel >= 1 ) {
globParts = this . levelOneOptimize ( globParts ) ;
} else {
globParts = this . adjascentGlobstarOptimize ( globParts ) ;
}
return globParts ;
}
// just get rid of adjascent ** portions
adjascentGlobstarOptimize ( globParts ) {
return globParts . map ( ( parts ) => {
let gs = - 1 ;
while ( - 1 !== ( gs = parts . indexOf ( "**" , gs + 1 ) ) ) {
let i = gs ;
while ( parts [ i + 1 ] === "**" ) {
i ++ ;
}
if ( i !== gs ) {
parts . splice ( gs , i - gs ) ;
}
}
return parts ;
} ) ;
}
// get rid of adjascent ** and resolve .. portions
levelOneOptimize ( globParts ) {
return globParts . map ( ( parts ) => {
parts = parts . reduce ( ( set , part ) => {
const prev = set [ set . length - 1 ] ;
if ( part === "**" && prev === "**" ) {
return set ;
}
if ( part === ".." ) {
if ( prev && prev !== ".." && prev !== "." && prev !== "**" ) {
set . pop ( ) ;
return set ;
}
}
set . push ( part ) ;
return set ;
} , [ ] ) ;
return parts . length === 0 ? [ "" ] : parts ;
} ) ;
}
levelTwoFileOptimize ( parts ) {
if ( ! Array . isArray ( parts ) ) {
parts = this . slashSplit ( parts ) ;
}
let didSomething = false ;
do {
didSomething = false ;
if ( ! this . preserveMultipleSlashes ) {
for ( let i = 1 ; i < parts . length - 1 ; i ++ ) {
const p = parts [ i ] ;
if ( i === 1 && p === "" && parts [ 0 ] === "" )
continue ;
if ( p === "." || p === "" ) {
didSomething = true ;
parts . splice ( i , 1 ) ;
i -- ;
}
}
if ( parts [ 0 ] === "." && parts . length === 2 && ( parts [ 1 ] === "." || parts [ 1 ] === "" ) ) {
didSomething = true ;
parts . pop ( ) ;
}
}
let dd = 0 ;
while ( - 1 !== ( dd = parts . indexOf ( ".." , dd + 1 ) ) ) {
const p = parts [ dd - 1 ] ;
if ( p && p !== "." && p !== ".." && p !== "**" ) {
didSomething = true ;
parts . splice ( dd - 1 , 2 ) ;
dd -= 2 ;
}
}
} while ( didSomething ) ;
return parts . length === 0 ? [ "" ] : parts ;
}
// First phase: single-pattern processing
// <pre> is 1 or more portions
// <rest> is 1 or more portions
// <p> is any portion other than ., .., '', or **
// <e> is . or ''
//
// **/.. is *brutal* for filesystem walking performance, because
// it effectively resets the recursive walk each time it occurs,
// and ** cannot be reduced out by a .. pattern part like a regexp
// or most strings (other than .., ., and '') can be.
//
// <pre>/**/../<p>/<p>/<rest> -> {<pre>/../<p>/<p>/<rest>,<pre>/**/<p>/<p>/<rest>}
// <pre>/<e>/<rest> -> <pre>/<rest>
// <pre>/<p>/../<rest> -> <pre>/<rest>
// **/**/<rest> -> **/<rest>
//
// **/*/<rest> -> */**/<rest> <== not valid because ** doesn't follow
// this WOULD be allowed if ** did follow symlinks, or * didn't
firstPhasePreProcess ( globParts ) {
let didSomething = false ;
do {
didSomething = false ;
for ( let parts of globParts ) {
let gs = - 1 ;
while ( - 1 !== ( gs = parts . indexOf ( "**" , gs + 1 ) ) ) {
let gss = gs ;
while ( parts [ gss + 1 ] === "**" ) {
gss ++ ;
}
if ( gss > gs ) {
parts . splice ( gs + 1 , gss - gs ) ;
}
let next = parts [ gs + 1 ] ;
const p = parts [ gs + 2 ] ;
const p2 = parts [ gs + 3 ] ;
if ( next !== ".." )
continue ;
if ( ! p || p === "." || p === ".." || ! p2 || p2 === "." || p2 === ".." ) {
continue ;
}
didSomething = true ;
parts . splice ( gs , 1 ) ;
const other = parts . slice ( 0 ) ;
other [ gs ] = "**" ;
globParts . push ( other ) ;
gs -- ;
}
if ( ! this . preserveMultipleSlashes ) {
for ( let i = 1 ; i < parts . length - 1 ; i ++ ) {
const p = parts [ i ] ;
if ( i === 1 && p === "" && parts [ 0 ] === "" )
continue ;
if ( p === "." || p === "" ) {
didSomething = true ;
parts . splice ( i , 1 ) ;
i -- ;
2025-08-02 12:09:34 +08:00
}
}
2026-05-06 17:32:44 +08:00
if ( parts [ 0 ] === "." && parts . length === 2 && ( parts [ 1 ] === "." || parts [ 1 ] === "" ) ) {
didSomething = true ;
parts . pop ( ) ;
2025-08-02 12:09:34 +08:00
}
}
2026-05-06 17:32:44 +08:00
let dd = 0 ;
while ( - 1 !== ( dd = parts . indexOf ( ".." , dd + 1 ) ) ) {
const p = parts [ dd - 1 ] ;
if ( p && p !== "." && p !== ".." && p !== "**" ) {
didSomething = true ;
const needDot = dd === 1 && parts [ dd + 1 ] === "**" ;
const splin = needDot ? [ "." ] : [ ] ;
parts . splice ( dd - 1 , 2 , ... splin ) ;
if ( parts . length === 0 )
parts . push ( "" ) ;
dd -= 2 ;
}
}
}
} while ( didSomething ) ;
return globParts ;
}
// second phase: multi-pattern dedupes
// {<pre>/*/<rest>,<pre>/<p>/<rest>} -> <pre>/*/<rest>
// {<pre>/<rest>,<pre>/<rest>} -> <pre>/<rest>
// {<pre>/**/<rest>,<pre>/<rest>} -> <pre>/**/<rest>
//
// {<pre>/**/<rest>,<pre>/**/<p>/<rest>} -> <pre>/**/<rest>
// ^-- not valid because ** doens't follow symlinks
secondPhasePreProcess ( globParts ) {
for ( let i = 0 ; i < globParts . length - 1 ; i ++ ) {
for ( let j = i + 1 ; j < globParts . length ; j ++ ) {
const matched = this . partsMatch ( globParts [ i ] , globParts [ j ] , ! this . preserveMultipleSlashes ) ;
if ( matched ) {
globParts [ i ] = [ ] ;
globParts [ j ] = matched ;
break ;
2025-08-02 12:09:34 +08:00
}
}
}
2026-05-06 17:32:44 +08:00
return globParts . filter ( ( gs ) => gs . length ) ;
}
partsMatch ( a , b , emptyGSMatch = false ) {
let ai = 0 ;
let bi = 0 ;
let result = [ ] ;
let which = "" ;
while ( ai < a . length && bi < b . length ) {
if ( a [ ai ] === b [ bi ] ) {
result . push ( which === "b" ? b [ bi ] : a [ ai ] ) ;
ai ++ ;
bi ++ ;
} else if ( emptyGSMatch && a [ ai ] === "**" && b [ bi ] === a [ ai + 1 ] ) {
result . push ( a [ ai ] ) ;
ai ++ ;
} else if ( emptyGSMatch && b [ bi ] === "**" && a [ ai ] === b [ bi + 1 ] ) {
result . push ( b [ bi ] ) ;
bi ++ ;
} else if ( a [ ai ] === "*" && b [ bi ] && ( this . options . dot || ! b [ bi ] . startsWith ( "." ) ) && b [ bi ] !== "**" ) {
if ( which === "b" )
return false ;
which = "a" ;
result . push ( a [ ai ] ) ;
ai ++ ;
bi ++ ;
} else if ( b [ bi ] === "*" && a [ ai ] && ( this . options . dot || ! a [ ai ] . startsWith ( "." ) ) && a [ ai ] !== "**" ) {
if ( which === "a" )
return false ;
which = "b" ;
result . push ( b [ bi ] ) ;
ai ++ ;
bi ++ ;
} else {
return false ;
}
}
return a . length === b . length && result ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
parseNegate ( ) {
if ( this . nonegate )
return ;
const pattern = this . pattern ;
let negate = false ;
let negateOffset = 0 ;
for ( let i = 0 ; i < pattern . length && pattern . charAt ( i ) === "!" ; i ++ ) {
negate = ! negate ;
negateOffset ++ ;
}
if ( negateOffset )
this . pattern = pattern . slice ( negateOffset ) ;
this . negate = negate ;
}
// set partial to true to test if, for example,
// "/a/b" matches the start of "/*/b/*/d"
// Partial means, if you run out of file before you run
// out of pattern, then that's fine, as long as all
// the parts match.
matchOne ( file , pattern , partial = false ) {
const options = this . options ;
if ( this . isWindows ) {
const fileDrive = typeof file [ 0 ] === "string" && /^[a-z]:$/i . test ( file [ 0 ] ) ;
const fileUNC = ! fileDrive && file [ 0 ] === "" && file [ 1 ] === "" && file [ 2 ] === "?" && /^[a-z]:$/i . test ( file [ 3 ] ) ;
const patternDrive = typeof pattern [ 0 ] === "string" && /^[a-z]:$/i . test ( pattern [ 0 ] ) ;
const patternUNC = ! patternDrive && pattern [ 0 ] === "" && pattern [ 1 ] === "" && pattern [ 2 ] === "?" && typeof pattern [ 3 ] === "string" && /^[a-z]:$/i . test ( pattern [ 3 ] ) ;
const fdi = fileUNC ? 3 : fileDrive ? 0 : void 0 ;
const pdi = patternUNC ? 3 : patternDrive ? 0 : void 0 ;
if ( typeof fdi === "number" && typeof pdi === "number" ) {
const [ fd , pd ] = [ file [ fdi ] , pattern [ pdi ] ] ;
if ( fd . toLowerCase ( ) === pd . toLowerCase ( ) ) {
pattern [ pdi ] = fd ;
if ( pdi > fdi ) {
pattern = pattern . slice ( pdi ) ;
} else if ( fdi > pdi ) {
file = file . slice ( fdi ) ;
}
}
}
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
const { optimizationLevel = 1 } = this . options ;
if ( optimizationLevel >= 2 ) {
file = this . levelTwoFileOptimize ( file ) ;
}
this . debug ( "matchOne" , this , { file , pattern } ) ;
this . debug ( "matchOne" , file . length , pattern . length ) ;
for ( var fi = 0 , pi = 0 , fl = file . length , pl = pattern . length ; fi < fl && pi < pl ; fi ++ , pi ++ ) {
this . debug ( "matchOne loop" ) ;
var p = pattern [ pi ] ;
var f = file [ fi ] ;
this . debug ( pattern , p , f ) ;
if ( p === false ) {
return false ;
}
if ( p === GLOBSTAR ) {
this . debug ( "GLOBSTAR" , [ pattern , p , f ] ) ;
var fr = fi ;
var pr = pi + 1 ;
if ( pr === pl ) {
this . debug ( "** at the end" ) ;
for ( ; fi < fl ; fi ++ ) {
if ( file [ fi ] === "." || file [ fi ] === ".." || ! options . dot && file [ fi ] . charAt ( 0 ) === "." )
return false ;
}
return true ;
}
while ( fr < fl ) {
var swallowee = file [ fr ] ;
this . debug ( "\nglobstar while" , file , fr , pattern , pr , swallowee ) ;
if ( this . matchOne ( file . slice ( fr ) , pattern . slice ( pr ) , partial ) ) {
this . debug ( "globstar found match!" , fr , fl , swallowee ) ;
return true ;
} else {
if ( swallowee === "." || swallowee === ".." || ! options . dot && swallowee . charAt ( 0 ) === "." ) {
this . debug ( "dot detected!" , file , fr , pattern , pr ) ;
break ;
}
this . debug ( "globstar swallow a segment, and continue" ) ;
fr ++ ;
}
}
if ( partial ) {
this . debug ( "\n>>> no match, partial?" , file , fr , pattern , pr ) ;
if ( fr === fl ) {
return true ;
}
}
return false ;
}
let hit ;
if ( typeof p === "string" ) {
hit = f === p ;
this . debug ( "string match" , p , f , hit ) ;
} else {
hit = p . test ( f ) ;
this . debug ( "pattern match" , p , f , hit ) ;
}
if ( ! hit )
return false ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
if ( fi === fl && pi === pl ) {
return true ;
} else if ( fi === fl ) {
return partial ;
} else if ( pi === pl ) {
return fi === fl - 1 && file [ fi ] === "" ;
2025-08-02 12:09:34 +08:00
} else {
2026-05-06 17:32:44 +08:00
throw new Error ( "wtf?" ) ;
}
}
braceExpand ( ) {
return braceExpand ( this . pattern , this . options ) ;
}
parse ( pattern ) {
assertValidPattern ( pattern ) ;
const options = this . options ;
if ( pattern === "**" )
return GLOBSTAR ;
if ( pattern === "" )
return "" ;
let m ;
let fastTest = null ;
if ( m = pattern . match ( starRE ) ) {
fastTest = options . dot ? starTestDot : starTest ;
} else if ( m = pattern . match ( starDotExtRE ) ) {
fastTest = ( options . nocase ? options . dot ? starDotExtTestNocaseDot : starDotExtTestNocase : options . dot ? starDotExtTestDot : starDotExtTest ) ( m [ 1 ] ) ;
} else if ( m = pattern . match ( qmarksRE ) ) {
fastTest = ( options . nocase ? options . dot ? qmarksTestNocaseDot : qmarksTestNocase : options . dot ? qmarksTestDot : qmarksTest ) ( m ) ;
} else if ( m = pattern . match ( starDotStarRE ) ) {
fastTest = options . dot ? starDotStarTestDot : starDotStarTest ;
} else if ( m = pattern . match ( dotStarRE ) ) {
fastTest = dotStarTest ;
}
const re = AST . fromGlob ( pattern , this . options ) . toMMPattern ( ) ;
if ( fastTest && typeof re === "object" ) {
Reflect . defineProperty ( re , "test" , { value : fastTest } ) ;
}
return re ;
}
makeRe ( ) {
if ( this . regexp || this . regexp === false )
return this . regexp ;
const set = this . set ;
if ( ! set . length ) {
this . regexp = false ;
return this . regexp ;
}
const options = this . options ;
const twoStar = options . noglobstar ? star2 : options . dot ? twoStarDot : twoStarNoDot ;
const flags = new Set ( options . nocase ? [ "i" ] : [ ] ) ;
let re = set . map ( ( pattern ) => {
const pp = pattern . map ( ( p ) => {
if ( p instanceof RegExp ) {
for ( const f of p . flags . split ( "" ) )
flags . add ( f ) ;
}
return typeof p === "string" ? regExpEscape2 ( p ) : p === GLOBSTAR ? GLOBSTAR : p . _src ;
} ) ;
pp . forEach ( ( p , i ) => {
const next = pp [ i + 1 ] ;
const prev = pp [ i - 1 ] ;
if ( p !== GLOBSTAR || prev === GLOBSTAR ) {
return ;
}
if ( prev === void 0 ) {
if ( next !== void 0 && next !== GLOBSTAR ) {
pp [ i + 1 ] = "(?:\\/|" + twoStar + "\\/)?" + next ;
} else {
pp [ i ] = twoStar ;
}
} else if ( next === void 0 ) {
pp [ i - 1 ] = prev + "(?:\\/|\\/" + twoStar + ")?" ;
} else if ( next !== GLOBSTAR ) {
pp [ i - 1 ] = prev + "(?:\\/|\\/" + twoStar + "\\/)" + next ;
pp [ i + 1 ] = GLOBSTAR ;
}
} ) ;
const filtered = pp . filter ( ( p ) => p !== GLOBSTAR ) ;
if ( this . partial && filtered . length >= 1 ) {
const prefixes = [ ] ;
for ( let i = 1 ; i <= filtered . length ; i ++ ) {
prefixes . push ( filtered . slice ( 0 , i ) . join ( "/" ) ) ;
}
return "(?:" + prefixes . join ( "|" ) + ")" ;
}
return filtered . join ( "/" ) ;
} ) . join ( "|" ) ;
const [ open2 , close ] = set . length > 1 ? [ "(?:" , ")" ] : [ "" , "" ] ;
re = "^" + open2 + re + close + "$" ;
if ( this . partial ) {
re = "^(?:\\/|" + open2 + re . slice ( 1 , - 1 ) + close + ")$" ;
}
if ( this . negate )
re = "^(?!" + re + ").+$" ;
try {
this . regexp = new RegExp ( re , [ ... flags ] . join ( "" ) ) ;
} catch ( ex ) {
this . regexp = false ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
return this . regexp ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
slashSplit ( p ) {
if ( this . preserveMultipleSlashes ) {
return p . split ( "/" ) ;
} else if ( this . isWindows && /^\/\/[^\/]+/ . test ( p ) ) {
return [ "" , ... p . split ( /\/+/ ) ] ;
} else {
return p . split ( /\/+/ ) ;
2025-08-02 12:09:34 +08:00
}
}
2026-05-06 17:32:44 +08:00
match ( f , partial = this . partial ) {
this . debug ( "match" , f , this . pattern ) ;
if ( this . comment ) {
return false ;
}
if ( this . empty ) {
return f === "" ;
}
if ( f === "/" && partial ) {
return true ;
}
const options = this . options ;
if ( this . isWindows ) {
f = f . split ( "\\" ) . join ( "/" ) ;
}
const ff = this . slashSplit ( f ) ;
this . debug ( this . pattern , "split" , ff ) ;
const set = this . set ;
this . debug ( this . pattern , "set" , set ) ;
let filename = ff [ ff . length - 1 ] ;
if ( ! filename ) {
for ( let i = ff . length - 2 ; ! filename && i >= 0 ; i -- ) {
filename = ff [ i ] ;
}
}
for ( let i = 0 ; i < set . length ; i ++ ) {
const pattern = set [ i ] ;
let file = ff ;
if ( options . matchBase && pattern . length === 1 ) {
file = [ filename ] ;
}
const hit = this . matchOne ( file , pattern , partial ) ;
if ( hit ) {
if ( options . flipNegate ) {
return true ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
return ! this . negate ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
}
if ( options . flipNegate ) {
return false ;
}
return this . negate ;
}
static defaults ( def ) {
return minimatch . defaults ( def ) . Minimatch ;
2025-08-02 12:09:34 +08:00
}
} ;
2026-05-06 17:32:44 +08:00
minimatch . AST = AST ;
minimatch . Minimatch = Minimatch ;
minimatch . escape = escape ;
minimatch . unescape = unescape ;
2025-08-02 12:09:34 +08:00
2026-05-06 17:32:44 +08:00
// src/util/glob.ts
function isMatchedGlobPatterns ( path2 , patterns ) {
if ( patterns . length === 0 ) {
return false ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
try {
return patterns . some ( ( p ) => minimatch ( path2 , p ) ) ;
} catch ( error ) {
console . warn ( ` Invalid glob pattern detected: ${ error } ` ) ;
2025-08-02 12:09:34 +08:00
return false ;
}
}
2026-05-06 17:32:44 +08:00
// src/provider/CurrentVaultWordProvider.ts
var CurrentVaultWordProvider = class {
constructor ( app , appHelper ) {
this . app = app ;
this . appHelper = appHelper ;
this . wordsByFirstLetter = { } ;
this . words = [ ] ;
}
async refreshWords ( option ) {
var _a ;
this . clearWords ( ) ;
const currentDirname = this . appHelper . getCurrentDirname ( ) ;
const markdownFilePaths = this . app . vault . getMarkdownFiles ( ) . map ( ( x ) => x . path ) . filter ( ( p ) => this . includePrefixPatterns . every ( ( x ) => p . startsWith ( x ) ) ) . filter ( ( p ) => this . excludePrefixPatterns . every ( ( x ) => ! p . startsWith ( x ) ) ) . filter ( ( p ) => ! isMatchedGlobPatterns ( p , this . excludePathGlobPatterns ) ) . filter (
( p ) => ! this . onlyUnderCurrentDirectory || dirname ( p ) === currentDirname
) ;
const excludePatterns = option . excludeWordPatterns . map (
( x ) => new RegExp ( ` ^ ${ x } $ ` )
) ;
let wordByValue = { } ;
for ( const path2 of markdownFilePaths ) {
const content = await this . app . vault . adapter . read ( path2 ) ;
const tokens = this . tokenizer . tokenize ( content ) . filter (
( x ) => x . length >= option . minNumberOfCharacters && ! this . tokenizer . shouldIgnoreOnCurrent ( x )
) . map ( ( x ) => startsSmallLetterOnlyFirst ( x ) ? x . toLowerCase ( ) : x ) . filter ( ( x ) => ! excludePatterns . some ( ( rp ) => x . match ( rp ) ) ) ;
for ( const token of tokens ) {
wordByValue [ token ] = {
value : token ,
type : "currentVault" ,
createdPath : path2 ,
description : path2 ,
aliases : synonymAliases ( token , {
emoji : option . makeSynonymAboutEmoji ,
accentsDiacritics : option . makeSynonymAboutAccentsDiacritics
} )
} ;
}
}
this . words = Object . values ( wordByValue ) ;
for ( const word of this . words ) {
pushWord ( this . wordsByFirstLetter , word . value . charAt ( 0 ) , word ) ;
( _a = word . aliases ) == null ? void 0 : _a . forEach (
( a ) => pushWord ( this . wordsByFirstLetter , a . charAt ( 0 ) , word )
) ;
}
}
clearWords ( ) {
this . words = [ ] ;
this . wordsByFirstLetter = { } ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
get wordCount ( ) {
return this . words . length ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
setSettings ( tokenizer , includePrefixPatterns , excludePrefixPatterns , excludePathGlobPatterns , onlyUnderCurrentDirectory ) {
this . tokenizer = tokenizer ;
this . includePrefixPatterns = includePrefixPatterns ;
this . excludePrefixPatterns = excludePrefixPatterns ;
this . excludePathGlobPatterns = excludePathGlobPatterns ;
this . onlyUnderCurrentDirectory = onlyUnderCurrentDirectory ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
} ;
// src/provider/CustomDictionaryWordProvider.ts
var import _obsidian4 = require ( "obsidian" ) ;
function escape2 ( value ) {
return value . replace ( /\\/g , "__VariousComplementsEscape__" ) . replace ( /\n/g , "\\n" ) . replace ( /\t/g , "\\t" ) . replace ( /__VariousComplementsEscape__/g , "\\\\" ) ;
}
function unescape2 ( value ) {
return value . replace ( /\\\\/g , "__VariousComplementsEscape__" ) . replace ( /\\n/g , "\n" ) . replace ( /\\t/g , " " ) . replace ( /__VariousComplementsEscape__/g , "\\" ) ;
}
function jsonToWords ( json , path2 , systemCaretSymbol ) {
return json . words . map ( ( x ) => {
var _a ;
return {
value : x . displayed || x . value ,
description : x . description ,
aliases : x . aliases ,
type : "customDictionary" ,
createdPath : path2 ,
insertedText : x . displayed ? x . value : void 0 ,
caretSymbol : ( _a = json . caretSymbol ) != null ? _a : systemCaretSymbol ,
ignoreSpaceAfterCompletion : json . ignoreSpaceAfterCompletion
} ;
} ) ;
}
function lineToWord ( line , delimiter , path2 , delimiterForDisplay , delimiterForHide , systemCaretSymbol ) {
const [ v , description , ... aliases ] = line . split ( delimiter . value ) ;
let value = unescape2 ( v ) ;
let insertedText ;
let displayedText = value ;
if ( delimiterForDisplay && value . includes ( delimiterForDisplay ) ) {
[ displayedText , insertedText ] = value . split ( delimiterForDisplay ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
if ( delimiterForHide && value . includes ( delimiterForHide ) ) {
insertedText = value . replace ( delimiterForHide , "" ) ;
displayedText = ` ${ value . split ( delimiterForHide ) [ 0 ] } ... ` ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
return {
value : displayedText ,
description ,
aliases ,
type : "customDictionary" ,
createdPath : path2 ,
insertedText ,
caretSymbol : systemCaretSymbol
2025-08-02 12:09:34 +08:00
} ;
}
2026-05-06 17:32:44 +08:00
function wordToLine ( word , delimiter , dividerForDisplay ) {
const value = word . insertedText && dividerForDisplay ? ` ${ word . value } ${ dividerForDisplay } ${ word . insertedText } ` : word . value ;
const escapedValue = escape2 ( value ) ;
if ( ! word . description && ! word . aliases ) {
return escapedValue ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
if ( ! word . aliases ) {
return [ escapedValue , word . description ] . join ( delimiter . value ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
return [ escapedValue , word . description , ... word . aliases ] . join (
delimiter . value
2025-08-02 12:09:34 +08:00
) ;
}
2026-05-06 17:32:44 +08:00
var CustomDictionaryWordProvider = class {
constructor ( app , appHelper ) {
this . words = [ ] ;
this . wordByValue = { } ;
this . wordsByFirstLetter = { } ;
this . appHelper = appHelper ;
this . fileSystemAdapter = app . vault . adapter ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
get editablePaths ( ) {
return this . paths . filter ( ( x ) => ! isURL ( x ) && ! x . endsWith ( ".json" ) ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
async loadWords ( path2 , option ) {
const contents = isURL ( path2 ) ? await ( 0 , import _obsidian4 . request ) ( { url : path2 } ) : await this . fileSystemAdapter . read ( path2 ) ;
const words = path2 . endsWith ( ".json" ) ? jsonToWords ( JSON . parse ( contents ) , path2 , option . caretSymbol ) : contents . split ( /\r\n|\n/ ) . map ( ( x ) => x . replace ( /%%.*%%/g , "" ) ) . filter ( ( x ) => x ) . map (
( x ) => lineToWord (
x ,
this . delimiter ,
path2 ,
option . delimiterForDisplay ,
option . delimiterForHide ,
option . caretSymbol
)
) ;
return words . filter (
( x ) => ! option . regexp || x . value . match ( new RegExp ( option . regexp ) )
) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
async refreshCustomWords ( option ) {
this . clearWords ( ) ;
for ( const path2 of this . paths ) {
try {
const words = await this . loadWords ( path2 , option ) ;
words . forEach (
( x ) => this . addWord ( x , {
emoji : option . makeSynonymAboutEmoji ,
accentsDiacritics : option . makeSynonymAboutAccentsDiacritics
} )
) ;
} catch ( e ) {
new import _obsidian4 . Notice (
` \u 26A0 Fail to load ${ path2 } -- Various Complements Plugin --
$ { e } ` ,
0
) ;
}
}
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
async addWordWithDictionary ( word , dictionaryPath , synonymOption ) {
this . addWord ( word , synonymOption ) ;
await this . fileSystemAdapter . append (
dictionaryPath ,
"\n" + wordToLine ( word , this . delimiter , this . dividerForDisplay )
) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
addWord ( word , synonymOption ) {
var _a , _b ;
this . words . push ( word ) ;
const wordWithSynonym = {
... word ,
aliases : [
... ( _a = word . aliases ) != null ? _a : [ ] ,
... synonymAliases ( word . value , synonymOption )
]
} ;
this . wordByValue [ wordWithSynonym . value ] = wordWithSynonym ;
pushWord (
this . wordsByFirstLetter ,
wordWithSynonym . value . charAt ( 0 ) ,
wordWithSynonym
) ;
( _b = wordWithSynonym . aliases ) == null ? void 0 : _b . forEach (
( a ) => pushWord ( this . wordsByFirstLetter , a . charAt ( 0 ) , wordWithSynonym )
) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
clearWords ( ) {
this . words = [ ] ;
this . wordByValue = { } ;
this . wordsByFirstLetter = { } ;
}
get wordCount ( ) {
return this . words . length ;
}
setSettings ( paths , delimiter , dividerForDisplay ) {
this . paths = paths ;
this . delimiter = delimiter ;
this . dividerForDisplay = dividerForDisplay ;
}
} ;
// src/provider/FrontMatterWordProvider.ts
function synonymAliases2 ( name ) {
const lessEmojiValue = excludeEmoji ( name ) ;
return name === lessEmojiValue ? [ ] : [ lessEmojiValue ] ;
}
function frontMatterToWords ( file , key , values ) {
return values . map ( ( x ) => ( {
key ,
value : x ,
type : "frontMatter" ,
createdPath : file . path ,
aliases : synonymAliases2 ( x )
} ) ) ;
}
function pickWords ( file , fm ) {
return Object . entries ( fm ) . filter (
( [ _key , value ] ) => value != null && ( typeof value === "string" || typeof value [ 0 ] === "string" )
) . flatMap ( ( [ key , value ] ) => frontMatterToWords ( file , key , value ) ) ;
}
function extractAndUniqWords ( wordsByCreatedPath ) {
return uniqBy (
Object . values ( wordsByCreatedPath ) . flat ( ) ,
( w ) => w . key + w . value . toLowerCase ( )
2025-08-02 12:09:34 +08:00
) ;
}
2026-05-06 17:32:44 +08:00
function indexingWords ( words ) {
const wordsByKey = groupBy ( words , ( x ) => x . key ) ;
return Object . fromEntries (
Object . entries ( wordsByKey ) . map (
( [ key , words2 ] ) => [
key ,
groupBy ( words2 , ( w ) => w . value . charAt ( 0 ) )
]
)
) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
var FrontMatterWordProvider = class {
constructor ( app , appHelper ) {
this . app = app ;
this . appHelper = appHelper ;
this . wordsByCreatedPath = { } ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
refreshWords ( ) {
this . clearWords ( ) ;
this . app . vault . getMarkdownFiles ( ) . forEach ( ( f ) => {
const fm = this . appHelper . getFrontMatter ( f ) ;
if ( ! fm ) {
return ;
}
this . wordsByCreatedPath [ f . path ] = pickWords ( f , fm ) ;
} ) ;
this . words = extractAndUniqWords ( this . wordsByCreatedPath ) ;
this . wordsByFirstLetterByKey = indexingWords ( this . words ) ;
}
updateWordIndex ( file ) {
const fm = this . appHelper . getFrontMatter ( file ) ;
if ( ! fm ) {
2025-08-02 12:09:34 +08:00
return ;
}
2026-05-06 17:32:44 +08:00
this . wordsByCreatedPath [ file . path ] = pickWords ( file , fm ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
updateWords ( ) {
this . words = extractAndUniqWords ( this . wordsByCreatedPath ) ;
this . wordsByFirstLetterByKey = indexingWords ( this . words ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
clearWords ( ) {
this . wordsByCreatedPath = { } ;
this . words = [ ] ;
this . wordsByFirstLetterByKey = { } ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
get wordCount ( ) {
return this . words . length ;
}
} ;
// src/provider/InternalLinkWordProvider.ts
var InternalLinkWordProvider = class {
constructor ( app , appHelper ) {
this . app = app ;
this . appHelper = appHelper ;
this . words = [ ] ;
this . wordsByFirstLetter = { } ;
}
refreshWords ( option ) {
var _a ;
this . clearWords ( ) ;
const resolvedInternalLinkWords = this . app . vault . getMarkdownFiles ( ) . filter ( ( f ) => {
if ( option . excludePathPrefixPatterns . some ( ( x ) => f . path . startsWith ( x ) ) ) {
return false ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
if ( isMatchedGlobPatterns ( f . path , option . excludePathGlobPatterns ) ) {
return false ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
const fmkfc = option . frontMatterKeyForExclusion ;
if ( fmkfc && this . appHelper . getBoolFrontMatter ( f , fmkfc ) ) {
return false ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
if ( option . tagsForExclusion . length > 0 ) {
const tags = this . appHelper . getTagsProperty ( f ) ;
if ( hasSameElement ( option . tagsForExclusion , tags ) ) {
return false ;
2025-08-02 12:09:34 +08:00
}
}
2026-05-06 17:32:44 +08:00
return true ;
} ) . flatMap ( ( x ) => {
const aliases = this . appHelper . getAliases ( x ) ;
if ( option . wordAsInternalLinkAlias ) {
return [
{
value : x . basename ,
type : "internalLink" ,
createdPath : x . path ,
aliases : synonymAliases ( x . basename , {
emoji : option . makeSynonymAboutEmoji ,
accentsDiacritics : option . makeSynonymAboutAccentsDiacritics
} ) ,
description : x . path
} ,
... aliases . map ( ( a ) => ( {
value : a ,
type : "internalLink" ,
createdPath : x . path ,
aliases : synonymAliases ( a , {
emoji : option . makeSynonymAboutEmoji ,
accentsDiacritics : option . makeSynonymAboutAccentsDiacritics
} ) ,
description : x . path ,
aliasMeta : {
origin : x . path
}
} ) )
] ;
} else {
return [
{
value : x . basename ,
type : "internalLink" ,
createdPath : x . path ,
aliases : [
... synonymAliases ( x . basename , {
emoji : option . makeSynonymAboutEmoji ,
accentsDiacritics : option . makeSynonymAboutAccentsDiacritics
} ) ,
... aliases ,
... aliases . flatMap (
( al ) => synonymAliases ( al , {
emoji : option . makeSynonymAboutEmoji ,
accentsDiacritics : option . makeSynonymAboutAccentsDiacritics
} )
)
] ,
description : x . path
}
] ;
}
2025-08-02 12:09:34 +08:00
} ) ;
2026-05-06 17:32:44 +08:00
const unresolvedInternalLinkWords = option . excludeUnresolvedLinks ? [ ] : this . appHelper . searchPhantomLinks ( ) . map ( ( { path : path2 , link } ) => {
return {
value : link ,
type : "internalLink" ,
createdPath : path2 ,
aliases : synonymAliases ( link , {
emoji : option . makeSynonymAboutEmoji ,
accentsDiacritics : option . makeSynonymAboutAccentsDiacritics
} ) ,
description : ` Appeared in -> ${ path2 } ` ,
phantom : true
} ;
2025-08-02 12:09:34 +08:00
} ) ;
2026-05-06 17:32:44 +08:00
this . words = [ ... resolvedInternalLinkWords , ... unresolvedInternalLinkWords ] ;
for ( const word of this . words ) {
pushWord ( this . wordsByFirstLetter , word . value . charAt ( 0 ) , word ) ;
( _a = word . aliases ) == null ? void 0 : _a . forEach (
( a ) => pushWord ( this . wordsByFirstLetter , a . charAt ( 0 ) , word )
) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
}
clearWords ( ) {
this . words = [ ] ;
this . wordsByFirstLetter = { } ;
}
get wordCount ( ) {
return this . words . length ;
}
} ;
// src/storage/SelectionHistoryStorage.ts
var SEC = 1e3 ;
var MIN = SEC * 60 ;
var HOUR = MIN * 60 ;
var DAY = HOUR * 24 ;
var WEEK = DAY * 7 ;
function calcScore ( history , latestUpdated ) {
if ( ! history ) {
return 0 ;
}
if ( history . lastUpdated === latestUpdated ) {
return Number . MAX _SAFE _INTEGER ;
}
const behind = Date . now ( ) - history . lastUpdated ;
if ( behind < MIN ) {
return 8 * history . count ;
} else if ( behind < HOUR ) {
return 4 * history . count ;
} else if ( behind < DAY ) {
return 2 * history . count ;
} else if ( behind < WEEK ) {
return 0.5 * history . count ;
} else {
return 0.25 * history . count ;
}
}
var SelectionHistoryStorage = class {
constructor ( data = { } , maxDaysToKeepHistory , maxNumberOfHistoryToKeep ) {
this . data = data ;
const now2 = Date . now ( ) ;
this . version = now2 ;
this . persistedVersion = now2 ;
this . maxDaysToKeepHistory = maxDaysToKeepHistory ;
this . maxNumberOfHistoryToKeep = maxNumberOfHistoryToKeep ;
}
// noinspection FunctionWithMultipleLoopsJS
purge ( ) {
var _a ;
const now2 = Date . now ( ) ;
const times = [ ] ;
for ( const hit of Object . keys ( this . data ) ) {
for ( const value of Object . keys ( this . data [ hit ] ) ) {
for ( const kind of Object . keys ( this . data [ hit ] [ value ] ) ) {
if ( this . maxDaysToKeepHistory && now2 - this . data [ hit ] [ value ] [ kind ] . lastUpdated > this . maxDaysToKeepHistory * DAY ) {
delete this . data [ hit ] [ value ] [ kind ] ;
} else {
times . push ( this . data [ hit ] [ value ] [ kind ] . lastUpdated ) ;
}
}
if ( Object . isEmpty ( this . data [ hit ] [ value ] ) ) {
delete this . data [ hit ] [ value ] ;
}
}
if ( Object . isEmpty ( this . data [ hit ] ) ) {
delete this . data [ hit ] ;
}
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
if ( this . maxNumberOfHistoryToKeep ) {
const threshold = ( _a = times . sort ( ( a , b ) => a > b ? - 1 : 1 ) . slice ( 0 , this . maxNumberOfHistoryToKeep ) . last ( ) ) != null ? _a : 0 ;
for ( const hit of Object . keys ( this . data ) ) {
for ( const value of Object . keys ( this . data [ hit ] ) ) {
for ( const kind of Object . keys ( this . data [ hit ] [ value ] ) ) {
if ( this . data [ hit ] [ value ] [ kind ] . lastUpdated < threshold ) {
delete this . data [ hit ] [ value ] [ kind ] ;
}
}
if ( Object . isEmpty ( this . data [ hit ] [ value ] ) ) {
delete this . data [ hit ] [ value ] ;
}
}
if ( Object . isEmpty ( this . data [ hit ] ) ) {
delete this . data [ hit ] ;
}
}
2025-08-02 12:09:34 +08:00
}
}
2026-05-06 17:32:44 +08:00
getSelectionHistory ( word ) {
var _a , _b ;
return ( _b = ( _a = this . data [ word . hit ] ) == null ? void 0 : _a [ word . value ] ) == null ? void 0 : _b [ word . type ] ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
increment ( word ) {
if ( ! this . data [ word . hit ] ) {
this . data [ word . hit ] = { } ;
}
let valueRef ;
if ( word . valueForHistory ) {
if ( ! this . data [ word . hit ] [ word . valueForHistory ] ) {
this . data [ word . hit ] [ word . valueForHistory ] = { } ;
}
valueRef = this . data [ word . hit ] [ word . valueForHistory ] ;
} else {
if ( ! this . data [ word . hit ] [ word . value ] ) {
this . data [ word . hit ] [ word . value ] = { } ;
}
valueRef = this . data [ word . hit ] [ word . value ] ;
}
if ( valueRef [ word . type ] ) {
valueRef [ word . type ] = {
count : valueRef [ word . type ] . count + 1 ,
lastUpdated : Date . now ( )
} ;
} else {
valueRef [ word . type ] = {
count : 1 ,
lastUpdated : Date . now ( )
} ;
}
this . version = Date . now ( ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
compare ( w1 , w2 , latestUpdated ) {
const score1 = calcScore ( this . getSelectionHistory ( w1 ) , latestUpdated ) ;
const score2 = calcScore ( this . getSelectionHistory ( w2 ) , latestUpdated ) ;
if ( score1 === score2 ) {
return 0 ;
}
return score1 > score2 ? - 1 : 1 ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
get shouldPersist ( ) {
return this . version > this . persistedVersion ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
syncPersistVersion ( ) {
this . persistedVersion = this . version ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
} ;
// src/errors.ts
var ExhaustiveError = class extends Error {
constructor ( value , message = ` Unsupported type: ${ value } ` ) {
super ( message ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
} ;
// src/tokenizer/tokenizers/AbstractTokenizer.ts
var INPUT _TRIM _CHAR _PATTERN = /[\r\n\t\[\]$/:?!=()<>"',|;*~ `_“„«»‹ › ‚ ‘ ’ ”]/g ;
var INDEXING _TRIM _CHAR _PATTERN = /[\r\n\t\[\]/:?!=()<>"',|;*~ `_“„«»‹ › ‚ ‘ ’ ”]/g ;
var AbstractTokenizer = class {
constructor ( args ) {
this . inputTrimCharPattern = ( args == null ? void 0 : args . treatUnderscoreAsPartOfWord ) ? removeFromPattern ( INPUT _TRIM _CHAR _PATTERN , "_" ) : INPUT _TRIM _CHAR _PATTERN ;
this . indexingTrimCharPattern = ( args == null ? void 0 : args . treatUnderscoreAsPartOfWord ) ? removeFromPattern ( INDEXING _TRIM _CHAR _PATTERN , "_" ) : INDEXING _TRIM _CHAR _PATTERN ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
getTrimPattern ( target ) {
switch ( target ) {
case "input" :
return this . inputTrimCharPattern ;
case "indexing" :
return this . indexingTrimCharPattern ;
default :
throw new ExhaustiveError ( target ) ;
2025-08-02 12:09:34 +08:00
}
}
2026-05-06 17:32:44 +08:00
shouldIgnoreOnCurrent ( _str ) {
return false ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
} ;
// src/tokenizer/tokenizers/DefaultTokenizer.ts
var DefaultTokenizer = class extends AbstractTokenizer {
tokenize ( content , raw ) {
const tokenized = Array . from ( this . _ _tokenize ( content , "indexing" ) ) ;
return raw ? tokenized . map ( ( x ) => x . word ) : tokenized . map ( ( x ) => x . word ) . filter ( ( x ) => ! x . match ( this . getTrimPattern ( "indexing" ) ) ) . map ( ( x ) => x . replace ( /\.+$/g , "" ) ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
recursiveTokenize ( content ) {
const offsets = Array . from ( this . _ _tokenize ( content , "input" ) ) . filter ( ( x ) => ! x . word . match ( this . getTrimPattern ( "input" ) ) ) . map ( ( x ) => x . offset ) ;
const results = offsets . map ( ( i ) => ( {
word : content . slice ( i ) ,
offset : i
} ) ) ;
if ( results . length === 0 ) {
return [ { word : content , offset : 0 } ] ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
return results [ 0 ] . offset === 0 ? results : [ { word : content , offset : 0 } , ... results ] ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
// Diffirent with _tokenize of other tokenizers
* _ _tokenize ( content , target ) {
let startIndex = 0 ;
let previousType = "none" ;
for ( let i = 0 ; i < content . length ; i ++ ) {
if ( content [ i ] . match ( super . getTrimPattern ( target ) ) ) {
const word = content . slice ( startIndex , i ) ;
if ( word !== "" ) {
yield { word , offset : startIndex } ;
}
previousType = "trim" ;
startIndex = i ;
continue ;
}
if ( previousType === "others" || previousType === "none" ) {
previousType = "others" ;
continue ;
}
yield { word : content . slice ( startIndex , i ) , offset : startIndex } ;
previousType = "others" ;
startIndex = i ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
yield {
word : content . slice ( startIndex , content . length ) ,
offset : startIndex
} ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
} ;
// src/tokenizer/tokenizers/ArabicTokenizer.ts
var INPUT _ARABIC _TRIM _CHAR _PATTERN = /[\r\n\t\[\]/:?!=()<>"'.,|;*~ `،؛]/g ;
var INDEXING _ARABIC _TRIM _CHAR _PATTERN = /[\r\n\t\[\]$/:?!=()<>"'.,|;*~ `،؛]/g ;
var ArabicTokenizer = class extends DefaultTokenizer {
constructor ( _args ) {
super ( ) ;
this . inputTrimCharPattern = INPUT _ARABIC _TRIM _CHAR _PATTERN ;
this . indexingTrimCharPattern = INDEXING _ARABIC _TRIM _CHAR _PATTERN ;
}
} ;
// src/tokenizer/tokenizers/ChineseTokenizer.ts
var import _chinese _tokenizer = _ _toESM ( require _main ( ) ) ;
var ChineseTokenizer = class _ChineseTokenizer extends AbstractTokenizer {
static create ( dict ) {
const ins = new _ChineseTokenizer ( ) ;
ins . _tokenize = import _chinese _tokenizer . default . load ( dict ) ;
return ins ;
}
tokenize ( content , raw ) {
return content . split ( raw ? / /g : this . getTrimPattern ( "indexing" ) ) . filter ( ( x ) => x !== "" ) . flatMap ( ( x ) => this . _tokenize ( x ) ) . map ( ( x ) => x . text ) ;
}
recursiveTokenize ( content ) {
const tokens = this . _tokenize ( content ) . map ( ( x ) => x . text ) ;
const ret = [ ] ;
for ( let i = 0 ; i < tokens . length ; i ++ ) {
if ( i === 0 || tokens [ i ] . length !== 1 || ! Boolean ( tokens [ i ] . match ( this . getTrimPattern ( "input" ) ) ) ) {
ret . push ( {
word : tokens . slice ( i ) . join ( "" ) ,
offset : tokens . slice ( 0 , i ) . join ( "" ) . length
} ) ;
}
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
return ret ;
}
} ;
// src/tokenizer/tokenizers/EnglishOnlyTokenizer.ts
var ENGLISH _PATTERN = /[a-zA-Z0-9_\-\\]/ ;
var EnglishOnlyTokenizer = class extends DefaultTokenizer {
tokenize ( content , raw ) {
const tokenized = Array . from ( this . _tokenize ( content , "indexing" ) ) . filter (
( x ) => x . word . match ( ENGLISH _PATTERN )
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
return raw ? tokenized . map ( ( x ) => x . word ) : tokenized . map ( ( x ) => x . word ) . filter ( ( x ) => ! x . match ( this . getTrimPattern ( "indexing" ) ) ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
recursiveTokenize ( content ) {
const offsets = Array . from ( this . _tokenize ( content , "input" ) ) . filter ( ( x ) => ! x . word . match ( this . getTrimPattern ( "input" ) ) ) . map ( ( x ) => x . offset ) ;
return [
... offsets . map ( ( i ) => ( {
word : content . slice ( i ) ,
offset : i
} ) )
] ;
}
* _tokenize ( content , target ) {
let startIndex = 0 ;
let previousType = "none" ;
for ( let i = 0 ; i < content . length ; i ++ ) {
if ( content [ i ] . match ( super . getTrimPattern ( target ) ) ) {
yield { word : content . slice ( startIndex , i ) , offset : startIndex } ;
previousType = "trim" ;
startIndex = i ;
continue ;
}
if ( content [ i ] . match ( ENGLISH _PATTERN ) ) {
if ( previousType === "english" || previousType === "none" ) {
previousType = "english" ;
continue ;
}
yield { word : content . slice ( startIndex , i ) , offset : startIndex } ;
previousType = "english" ;
startIndex = i ;
continue ;
}
if ( previousType === "others" || previousType === "none" ) {
previousType = "others" ;
continue ;
}
yield { word : content . slice ( startIndex , i ) , offset : startIndex } ;
previousType = "others" ;
startIndex = i ;
}
yield {
word : content . slice ( startIndex , content . length ) ,
offset : startIndex
} ;
}
} ;
// src/external/tiny-segmenter.ts
function TinySegmenter ( ) {
var patterns = {
"[\u4E00\u4E8C\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D\u5341\u767E\u5343\u4E07\u5104\u5146]" : "M" ,
"[\u4E00-\u9FA0\u3005\u3006\u30F5\u30F6]" : "H" ,
"[\u3041-\u3093]" : "I" ,
"[\u30A1-\u30F4\u30FC\uFF71-\uFF9D\uFF9E\uFF70]" : "K" ,
"[a-zA-Z\uFF41-\uFF5A\uFF21-\uFF3A]" : "A" ,
"[0-9\uFF10-\uFF19]" : "N"
} ;
this . chartype _ = [ ] ;
for ( var i in patterns ) {
var regexp = new RegExp ( ) ;
regexp . compile ( i ) ;
this . chartype _ . push ( [ regexp , patterns [ i ] ] ) ;
}
this . BIAS _ _ = - 332 ;
this . BC1 _ _ = { HH : 6 , II : 2461 , KH : 406 , OH : - 1378 } ;
this . BC2 _ _ = {
AA : - 3267 ,
AI : 2744 ,
AN : - 878 ,
HH : - 4070 ,
HM : - 1711 ,
HN : 4012 ,
HO : 3761 ,
IA : 1327 ,
IH : - 1184 ,
II : - 1332 ,
IK : 1721 ,
IO : 5492 ,
KI : 3831 ,
KK : - 8741 ,
MH : - 3132 ,
MK : 3334 ,
OO : - 2920
} ;
this . BC3 _ _ = {
HH : 996 ,
HI : 626 ,
HK : - 721 ,
HN : - 1307 ,
HO : - 836 ,
IH : - 301 ,
KK : 2762 ,
MK : 1079 ,
MM : 4034 ,
OA : - 1652 ,
OH : 266
} ;
this . BP1 _ _ = { BB : 295 , OB : 304 , OO : - 125 , UB : 352 } ;
this . BP2 _ _ = { BO : 60 , OO : - 1762 } ;
this . BQ1 _ _ = {
BHH : 1150 ,
BHM : 1521 ,
BII : - 1158 ,
BIM : 886 ,
BMH : 1208 ,
BNH : 449 ,
BOH : - 91 ,
BOO : - 2597 ,
OHI : 451 ,
OIH : - 296 ,
OKA : 1851 ,
OKH : - 1020 ,
OKK : 904 ,
OOO : 2965
} ;
this . BQ2 _ _ = {
BHH : 118 ,
BHI : - 1159 ,
BHM : 466 ,
BIH : - 919 ,
BKK : - 1720 ,
BKO : 864 ,
OHH : - 1139 ,
OHM : - 181 ,
OIH : 153 ,
UHI : - 1146
} ;
this . BQ3 _ _ = {
BHH : - 792 ,
BHI : 2664 ,
BII : - 299 ,
BKI : 419 ,
BMH : 937 ,
BMM : 8335 ,
BNN : 998 ,
BOH : 775 ,
OHH : 2174 ,
OHM : 439 ,
OII : 280 ,
OKH : 1798 ,
OKI : - 793 ,
OKO : - 2242 ,
OMH : - 2402 ,
OOO : 11699
} ;
this . BQ4 _ _ = {
BHH : - 3895 ,
BIH : 3761 ,
BII : - 4654 ,
BIK : 1348 ,
BKK : - 1806 ,
BMI : - 3385 ,
BOO : - 12396 ,
OAH : 926 ,
OHH : 266 ,
OHK : - 2036 ,
ONN : - 973
} ;
this . BW1 _ _ = {
",\u3068" : 660 ,
",\u540C" : 727 ,
B1\u3042 : 1404 ,
B1\u540C : 542 ,
"\u3001\u3068" : 660 ,
"\u3001\u540C" : 727 ,
"\u300D\u3068" : 1682 ,
\u3042\u3063 : 1505 ,
\u3044\u3046 : 1743 ,
\u3044\u3063 : - 2055 ,
\u3044\u308B : 672 ,
\u3046\u3057 : - 4817 ,
\u3046\u3093 : 665 ,
\u304B\u3089 : 3472 ,
\u304C\u3089 : 600 ,
\u3053\u3046 : - 790 ,
\u3053\u3068 : 2083 ,
\u3053\u3093 : - 1262 ,
\u3055\u3089 : - 4143 ,
\u3055\u3093 : 4573 ,
\u3057\u305F : 2641 ,
\u3057\u3066 : 1104 ,
\u3059\u3067 : - 3399 ,
\u305D\u3053 : 1977 ,
\u305D\u308C : - 871 ,
\u305F\u3061 : 1122 ,
\u305F\u3081 : 601 ,
\u3063\u305F : 3463 ,
\u3064\u3044 : - 802 ,
\u3066\u3044 : 805 ,
\u3066\u304D : 1249 ,
\u3067\u304D : 1127 ,
\u3067\u3059 : 3445 ,
\u3067\u306F : 844 ,
\u3068\u3044 : - 4915 ,
\u3068\u307F : 1922 ,
\u3069\u3053 : 3887 ,
\u306A\u3044 : 5713 ,
\u306A\u3063 : 3015 ,
\u306A\u3069 : 7379 ,
\u306A\u3093 : - 1113 ,
\u306B\u3057 : 2468 ,
\u306B\u306F : 1498 ,
\u306B\u3082 : 1671 ,
\u306B\u5BFE : - 912 ,
\u306E\u4E00 : - 501 ,
\u306E\u4E2D : 741 ,
\u307E\u305B : 2448 ,
\u307E\u3067 : 1711 ,
\u307E\u307E : 2600 ,
\u307E\u308B : - 2155 ,
\u3084\u3080 : - 1947 ,
\u3088\u3063 : - 2565 ,
\u308C\u305F : 2369 ,
\u308C\u3067 : - 913 ,
\u3092\u3057 : 1860 ,
\u3092\u898B : 731 ,
\u4EA1\u304F : - 1886 ,
\u4EAC\u90FD : 2558 ,
\u53D6\u308A : - 2784 ,
\u5927\u304D : - 2604 ,
\u5927\u962A : 1497 ,
\u5E73\u65B9 : - 2314 ,
\u5F15\u304D : - 1336 ,
\u65E5\u672C : - 195 ,
\u672C\u5F53 : - 2423 ,
\u6BCE\u65E5 : - 2113 ,
\u76EE\u6307 : - 724 ,
\uFF22\uFF11\u3042 : 1404 ,
\uFF22\uFF11\u540C : 542 ,
"\uFF63\u3068" : 1682
} ;
this . BW2 _ _ = {
".." : - 11822 ,
11 : - 669 ,
"\u2015\u2015" : - 5730 ,
"\u2212\u2212" : - 13175 ,
\u3044\u3046 : - 1609 ,
\u3046\u304B : 2490 ,
\u304B\u3057 : - 1350 ,
\u304B\u3082 : - 602 ,
\u304B\u3089 : - 7194 ,
\u304B\u308C : 4612 ,
\u304C\u3044 : 853 ,
\u304C\u3089 : - 3198 ,
\u304D\u305F : 1941 ,
\u304F\u306A : - 1597 ,
\u3053\u3068 : - 8392 ,
\u3053\u306E : - 4193 ,
\u3055\u305B : 4533 ,
\u3055\u308C : 13168 ,
\u3055\u3093 : - 3977 ,
\u3057\u3044 : - 1819 ,
\u3057\u304B : - 545 ,
\u3057\u305F : 5078 ,
\u3057\u3066 : 972 ,
\u3057\u306A : 939 ,
\u305D\u306E : - 3744 ,
\u305F\u3044 : - 1253 ,
\u305F\u305F : - 662 ,
\u305F\u3060 : - 3857 ,
\u305F\u3061 : - 786 ,
\u305F\u3068 : 1224 ,
\u305F\u306F : - 939 ,
\u3063\u305F : 4589 ,
\u3063\u3066 : 1647 ,
\u3063\u3068 : - 2094 ,
\u3066\u3044 : 6144 ,
\u3066\u304D : 3640 ,
\u3066\u304F : 2551 ,
\u3066\u306F : - 3110 ,
\u3066\u3082 : - 3065 ,
\u3067\u3044 : 2666 ,
\u3067\u304D : - 1528 ,
\u3067\u3057 : - 3828 ,
\u3067\u3059 : - 4761 ,
\u3067\u3082 : - 4203 ,
\u3068\u3044 : 1890 ,
\u3068\u3053 : - 1746 ,
\u3068\u3068 : - 2279 ,
\u3068\u306E : 720 ,
\u3068\u307F : 5168 ,
\u3068\u3082 : - 3941 ,
\u306A\u3044 : - 2488 ,
\u306A\u304C : - 1313 ,
\u306A\u3069 : - 6509 ,
\u306A\u306E : 2614 ,
\u306A\u3093 : 3099 ,
\u306B\u304A : - 1615 ,
\u306B\u3057 : 2748 ,
\u306B\u306A : 2454 ,
\u306B\u3088 : - 7236 ,
\u306B\u5BFE : - 14943 ,
\u306B\u5F93 : - 4688 ,
\u306B\u95A2 : - 11388 ,
\u306E\u304B : 2093 ,
\u306E\u3067 : - 7059 ,
\u306E\u306B : - 6041 ,
\u306E\u306E : - 6125 ,
\u306F\u3044 : 1073 ,
\u306F\u304C : - 1033 ,
\u306F\u305A : - 2532 ,
\u3070\u308C : 1813 ,
\u307E\u3057 : - 1316 ,
\u307E\u3067 : - 6621 ,
\u307E\u308C : 5409 ,
\u3081\u3066 : - 3153 ,
\u3082\u3044 : 2230 ,
\u3082\u306E : - 10713 ,
\u3089\u304B : - 944 ,
\u3089\u3057 : - 1611 ,
\u3089\u306B : - 1897 ,
\u308A\u3057 : 651 ,
\u308A\u307E : 1620 ,
\u308C\u305F : 4270 ,
\u308C\u3066 : 849 ,
\u308C\u3070 : 4114 ,
\u308D\u3046 : 6067 ,
\u308F\u308C : 7901 ,
\u3092\u901A : - 11877 ,
\u3093\u3060 : 728 ,
\u3093\u306A : - 4115 ,
\u4E00\u4EBA : 602 ,
\u4E00\u65B9 : - 1375 ,
\u4E00\u65E5 : 970 ,
\u4E00\u90E8 : - 1051 ,
\u4E0A\u304C : - 4479 ,
\u4F1A\u793E : - 1116 ,
\u51FA\u3066 : 2163 ,
\u5206\u306E : - 7758 ,
\u540C\u515A : 970 ,
\u540C\u65E5 : - 913 ,
\u5927\u962A : - 2471 ,
\u59D4\u54E1 : - 1250 ,
\u5C11\u306A : - 1050 ,
\u5E74\u5EA6 : - 8669 ,
\u5E74\u9593 : - 1626 ,
\u5E9C\u770C : - 2363 ,
\u624B\u6A29 : - 1982 ,
\u65B0\u805E : - 4066 ,
\u65E5\u65B0 : - 722 ,
\u65E5\u672C : - 7068 ,
\u65E5\u7C73 : 3372 ,
\u66DC\u65E5 : - 601 ,
\u671D\u9BAE : - 2355 ,
\u672C\u4EBA : - 2697 ,
\u6771\u4EAC : - 1543 ,
\u7136\u3068 : - 1384 ,
\u793E\u4F1A : - 1276 ,
\u7ACB\u3066 : - 990 ,
\u7B2C\u306B : - 1612 ,
\u7C73\u56FD : - 4268 ,
"\uFF11\uFF11" : - 669
} ;
this . BW3 _ _ = {
\u3042\u305F : - 2194 ,
\u3042\u308A : 719 ,
\u3042\u308B : 3846 ,
"\u3044." : - 1185 ,
"\u3044\u3002" : - 1185 ,
\u3044\u3044 : 5308 ,
\u3044\u3048 : 2079 ,
\u3044\u304F : 3029 ,
\u3044\u305F : 2056 ,
\u3044\u3063 : 1883 ,
\u3044\u308B : 5600 ,
\u3044\u308F : 1527 ,
\u3046\u3061 : 1117 ,
\u3046\u3068 : 4798 ,
\u3048\u3068 : 1454 ,
"\u304B." : 2857 ,
"\u304B\u3002" : 2857 ,
\u304B\u3051 : - 743 ,
\u304B\u3063 : - 4098 ,
\u304B\u306B : - 669 ,
\u304B\u3089 : 6520 ,
\u304B\u308A : - 2670 ,
"\u304C," : 1816 ,
"\u304C\u3001" : 1816 ,
\u304C\u304D : - 4855 ,
\u304C\u3051 : - 1127 ,
\u304C\u3063 : - 913 ,
\u304C\u3089 : - 4977 ,
\u304C\u308A : - 2064 ,
\u304D\u305F : 1645 ,
\u3051\u3069 : 1374 ,
\u3053\u3068 : 7397 ,
\u3053\u306E : 1542 ,
\u3053\u308D : - 2757 ,
\u3055\u3044 : - 714 ,
\u3055\u3092 : 976 ,
"\u3057," : 1557 ,
"\u3057\u3001" : 1557 ,
\u3057\u3044 : - 3714 ,
\u3057\u305F : 3562 ,
\u3057\u3066 : 1449 ,
\u3057\u306A : 2608 ,
\u3057\u307E : 1200 ,
"\u3059." : - 1310 ,
"\u3059\u3002" : - 1310 ,
\u3059\u308B : 6521 ,
"\u305A," : 3426 ,
"\u305A\u3001" : 3426 ,
\u305A\u306B : 841 ,
\u305D\u3046 : 428 ,
"\u305F." : 8875 ,
"\u305F\u3002" : 8875 ,
\u305F\u3044 : - 594 ,
\u305F\u306E : 812 ,
\u305F\u308A : - 1183 ,
\u305F\u308B : - 853 ,
"\u3060." : 4098 ,
"\u3060\u3002" : 4098 ,
\u3060\u3063 : 1004 ,
\u3063\u305F : - 4748 ,
\u3063\u3066 : 300 ,
\u3066\u3044 : 6240 ,
\u3066\u304A : 855 ,
\u3066\u3082 : 302 ,
\u3067\u3059 : 1437 ,
\u3067\u306B : - 1482 ,
\u3067\u306F : 2295 ,
\u3068\u3046 : - 1387 ,
\u3068\u3057 : 2266 ,
\u3068\u306E : 541 ,
\u3068\u3082 : - 3543 ,
\u3069\u3046 : 4664 ,
\u306A\u3044 : 1796 ,
\u306A\u304F : - 903 ,
\u306A\u3069 : 2135 ,
"\u306B," : - 1021 ,
"\u306B\u3001" : - 1021 ,
\u306B\u3057 : 1771 ,
\u306B\u306A : 1906 ,
\u306B\u306F : 2644 ,
"\u306E," : - 724 ,
"\u306E\u3001" : - 724 ,
\u306E\u5B50 : - 1e3 ,
"\u306F," : 1337 ,
"\u306F\u3001" : 1337 ,
\u3079\u304D : 2181 ,
\u307E\u3057 : 1113 ,
\u307E\u3059 : 6943 ,
\u307E\u3063 : - 1549 ,
\u307E\u3067 : 6154 ,
\u307E\u308C : - 793 ,
\u3089\u3057 : 1479 ,
\u3089\u308C : 6820 ,
\u308B\u308B : 3818 ,
"\u308C," : 854 ,
"\u308C\u3001" : 854 ,
\u308C\u305F : 1850 ,
\u308C\u3066 : 1375 ,
\u308C\u3070 : - 3246 ,
\u308C\u308B : 1091 ,
\u308F\u308C : - 605 ,
\u3093\u3060 : 606 ,
\u3093\u3067 : 798 ,
\u30AB\u6708 : 990 ,
\u4F1A\u8B70 : 860 ,
\u5165\u308A : 1232 ,
\u5927\u4F1A : 2217 ,
\u59CB\u3081 : 1681 ,
\u5E02 : 965 ,
\u65B0\u805E : - 5055 ,
"\u65E5," : 974 ,
"\u65E5\u3001" : 974 ,
\u793E\u4F1A : 2024 ,
\uFF76\u6708 : 990
} ;
this . TC1 _ _ = {
AAA : 1093 ,
HHH : 1029 ,
HHM : 580 ,
HII : 998 ,
HOH : - 390 ,
HOM : - 331 ,
IHI : 1169 ,
IOH : - 142 ,
IOI : - 1015 ,
IOM : 467 ,
MMH : 187 ,
OOI : - 1832
} ;
this . TC2 _ _ = {
HHO : 2088 ,
HII : - 1023 ,
HMM : - 1154 ,
IHI : - 1965 ,
KKH : 703 ,
OII : - 2649
} ;
this . TC3 _ _ = {
AAA : - 294 ,
HHH : 346 ,
HHI : - 341 ,
HII : - 1088 ,
HIK : 731 ,
HOH : - 1486 ,
IHH : 128 ,
IHI : - 3041 ,
IHO : - 1935 ,
IIH : - 825 ,
IIM : - 1035 ,
IOI : - 542 ,
KHH : - 1216 ,
KKA : 491 ,
KKH : - 1217 ,
KOK : - 1009 ,
MHH : - 2694 ,
MHM : - 457 ,
MHO : 123 ,
MMH : - 471 ,
NNH : - 1689 ,
NNO : 662 ,
OHO : - 3393
} ;
this . TC4 _ _ = {
HHH : - 203 ,
HHI : 1344 ,
HHK : 365 ,
HHM : - 122 ,
HHN : 182 ,
HHO : 669 ,
HIH : 804 ,
HII : 679 ,
HOH : 446 ,
IHH : 695 ,
IHO : - 2324 ,
IIH : 321 ,
III : 1497 ,
IIO : 656 ,
IOO : 54 ,
KAK : 4845 ,
KKA : 3386 ,
KKK : 3065 ,
MHH : - 405 ,
MHI : 201 ,
MMH : - 241 ,
MMM : 661 ,
MOM : 841
} ;
this . TQ1 _ _ = {
BHHH : - 227 ,
BHHI : 316 ,
BHIH : - 132 ,
BIHH : 60 ,
BIII : 1595 ,
BNHH : - 744 ,
BOHH : 225 ,
BOOO : - 908 ,
OAKK : 482 ,
OHHH : 281 ,
OHIH : 249 ,
OIHI : 200 ,
OIIH : - 68
} ;
this . TQ2 _ _ = { BIHH : - 1401 , BIII : - 1033 , BKAK : - 543 , BOOO : - 5591 } ;
this . TQ3 _ _ = {
BHHH : 478 ,
BHHM : - 1073 ,
BHIH : 222 ,
BHII : - 504 ,
BIIH : - 116 ,
BIII : - 105 ,
BMHI : - 863 ,
BMHM : - 464 ,
BOMH : 620 ,
OHHH : 346 ,
OHHI : 1729 ,
OHII : 997 ,
OHMH : 481 ,
OIHH : 623 ,
OIIH : 1344 ,
OKAK : 2792 ,
OKHH : 587 ,
OKKA : 679 ,
OOHH : 110 ,
OOII : - 685
} ;
this . TQ4 _ _ = {
BHHH : - 721 ,
BHHM : - 3604 ,
BHII : - 966 ,
BIIH : - 607 ,
BIII : - 2181 ,
OAAA : - 2763 ,
OAKK : 180 ,
OHHH : - 294 ,
OHHI : 2446 ,
OHHO : 480 ,
OHIH : - 1573 ,
OIHH : 1935 ,
OIHI : - 493 ,
OIIH : 626 ,
OIII : - 4007 ,
OKAK : - 8156
} ;
this . TW1 _ _ = { \u306B\u3064\u3044 : - 4681 , \u6771\u4EAC\u90FD : 2026 } ;
this . TW2 _ _ = {
\u3042\u308B\u7A0B : - 2049 ,
\u3044\u3063\u305F : - 1256 ,
\u3053\u308D\u304C : - 2434 ,
\u3057\u3087\u3046 : 3873 ,
\u305D\u306E\u5F8C : - 4430 ,
\u3060\u3063\u3066 : - 1049 ,
\u3066\u3044\u305F : 1833 ,
\u3068\u3057\u3066 : - 4657 ,
\u3068\u3082\u306B : - 4517 ,
\u3082\u306E\u3067 : 1882 ,
\u4E00\u6C17\u306B : - 792 ,
\u521D\u3081\u3066 : - 1512 ,
\u540C\u6642\u306B : - 8097 ,
\u5927\u304D\u306A : - 1255 ,
\u5BFE\u3057\u3066 : - 2721 ,
\u793E\u4F1A\u515A : - 3216
} ;
this . TW3 _ _ = {
\u3044\u305F\u3060 : - 1734 ,
\u3057\u3066\u3044 : 1314 ,
\u3068\u3057\u3066 : - 4314 ,
\u306B\u3064\u3044 : - 5483 ,
\u306B\u3068\u3063 : - 5989 ,
\u306B\u5F53\u305F : - 6247 ,
"\u306E\u3067," : - 727 ,
"\u306E\u3067\u3001" : - 727 ,
\u306E\u3082\u306E : - 600 ,
\u308C\u304B\u3089 : - 3752 ,
\u5341\u4E8C\u6708 : - 2287
} ;
this . TW4 _ _ = {
"\u3044\u3046." : 8576 ,
"\u3044\u3046\u3002" : 8576 ,
\u304B\u3089\u306A : - 2348 ,
\u3057\u3066\u3044 : 2958 ,
"\u305F\u304C," : 1516 ,
"\u305F\u304C\u3001" : 1516 ,
\u3066\u3044\u308B : 1538 ,
\u3068\u3044\u3046 : 1349 ,
\u307E\u3057\u305F : 5543 ,
\u307E\u305B\u3093 : 1097 ,
\u3088\u3046\u3068 : - 4258 ,
\u3088\u308B\u3068 : 5865
} ;
this . UC1 _ _ = { A : 484 , K : 93 , M : 645 , O : - 505 } ;
this . UC2 _ _ = { A : 819 , H : 1059 , I : 409 , M : 3987 , N : 5775 , O : 646 } ;
this . UC3 _ _ = { A : - 1370 , I : 2311 } ;
this . UC4 _ _ = {
A : - 2643 ,
H : 1809 ,
I : - 1032 ,
K : - 3450 ,
M : 3565 ,
N : 3876 ,
O : 6646
} ;
this . UC5 _ _ = { H : 313 , I : - 1238 , K : - 799 , M : 539 , O : - 831 } ;
this . UC6 _ _ = { H : - 506 , I : - 253 , K : 87 , M : 247 , O : - 387 } ;
this . UP1 _ _ = { O : - 214 } ;
this . UP2 _ _ = { B : 69 , O : 935 } ;
this . UP3 _ _ = { B : 189 } ;
this . UQ1 _ _ = {
BH : 21 ,
BI : - 12 ,
BK : - 99 ,
BN : 142 ,
BO : - 56 ,
OH : - 95 ,
OI : 477 ,
OK : 410 ,
OO : - 2422
} ;
this . UQ2 _ _ = { BH : 216 , BI : 113 , OK : 1759 } ;
this . UQ3 _ _ = {
BA : - 479 ,
BH : 42 ,
BI : 1913 ,
BK : - 7198 ,
BM : 3160 ,
BN : 6427 ,
BO : 14761 ,
OI : - 827 ,
ON : - 3212
} ;
this . UW1 _ _ = {
"," : 156 ,
"\u3001" : 156 ,
"\u300C" : - 463 ,
\u3042 : - 941 ,
\u3046 : - 127 ,
\u304C : - 553 ,
\u304D : 121 ,
\u3053 : 505 ,
\u3067 : - 201 ,
\u3068 : - 547 ,
\u3069 : - 123 ,
\u306B : - 789 ,
\u306E : - 185 ,
\u306F : - 847 ,
\u3082 : - 466 ,
\u3084 : - 470 ,
\u3088 : 182 ,
\u3089 : - 292 ,
\u308A : 208 ,
\u308C : 169 ,
\u3092 : - 446 ,
\u3093 : - 137 ,
"\u30FB" : - 135 ,
\u4E3B : - 402 ,
\u4EAC : - 268 ,
\u533A : - 912 ,
\u5348 : 871 ,
\u56FD : - 460 ,
\u5927 : 561 ,
\u59D4 : 729 ,
\u5E02 : - 411 ,
\u65E5 : - 141 ,
\u7406 : 361 ,
\u751F : - 408 ,
\u770C : - 386 ,
\u90FD : - 718 ,
"\uFF62" : - 463 ,
"\uFF65" : - 135
} ;
this . UW2 _ _ = {
"," : - 829 ,
"\u3001" : - 829 ,
"\u3007" : 892 ,
"\u300C" : - 645 ,
"\u300D" : 3145 ,
\u3042 : - 538 ,
\u3044 : 505 ,
\u3046 : 134 ,
\u304A : - 502 ,
\u304B : 1454 ,
\u304C : - 856 ,
\u304F : - 412 ,
\u3053 : 1141 ,
\u3055 : 878 ,
\u3056 : 540 ,
\u3057 : 1529 ,
\u3059 : - 675 ,
\u305B : 300 ,
\u305D : - 1011 ,
\u305F : 188 ,
\u3060 : 1837 ,
\u3064 : - 949 ,
\u3066 : - 291 ,
\u3067 : - 268 ,
\u3068 : - 981 ,
\u3069 : 1273 ,
\u306A : 1063 ,
\u306B : - 1764 ,
\u306E : 130 ,
\u306F : - 409 ,
\u3072 : - 1273 ,
\u3079 : 1261 ,
\u307E : 600 ,
\u3082 : - 1263 ,
\u3084 : - 402 ,
\u3088 : 1639 ,
\u308A : - 579 ,
\u308B : - 694 ,
\u308C : 571 ,
\u3092 : - 2516 ,
\u3093 : 2095 ,
\u30A2 : - 587 ,
\u30AB : 306 ,
\u30AD : 568 ,
\u30C3 : 831 ,
\u4E09 : - 758 ,
\u4E0D : - 2150 ,
\u4E16 : - 302 ,
\u4E2D : - 968 ,
\u4E3B : - 861 ,
\u4E8B : 492 ,
\u4EBA : - 123 ,
\u4F1A : 978 ,
\u4FDD : 362 ,
\u5165 : 548 ,
\u521D : - 3025 ,
\u526F : - 1566 ,
\u5317 : - 3414 ,
\u533A : - 422 ,
\u5927 : - 1769 ,
\u5929 : - 865 ,
\u592A : - 483 ,
\u5B50 : - 1519 ,
\u5B66 : 760 ,
\u5B9F : 1023 ,
\u5C0F : - 2009 ,
\u5E02 : - 813 ,
\u5E74 : - 1060 ,
\u5F37 : 1067 ,
\u624B : - 1519 ,
\u63FA : - 1033 ,
\u653F : 1522 ,
\u6587 : - 1355 ,
\u65B0 : - 1682 ,
\u65E5 : - 1815 ,
\u660E : - 1462 ,
\u6700 : - 630 ,
\u671D : - 1843 ,
\u672C : - 1650 ,
\u6771 : - 931 ,
\u679C : - 665 ,
\u6B21 : - 2378 ,
\u6C11 : - 180 ,
\u6C17 : - 1740 ,
\u7406 : 752 ,
\u767A : 529 ,
\u76EE : - 1584 ,
\u76F8 : - 242 ,
\u770C : - 1165 ,
\u7ACB : - 763 ,
\u7B2C : 810 ,
\u7C73 : 509 ,
\u81EA : - 1353 ,
\u884C : 838 ,
\u897F : - 744 ,
\u898B : - 3874 ,
\u8ABF : 1010 ,
\u8B70 : 1198 ,
\u8FBC : 3041 ,
\u958B : 1758 ,
\u9593 : - 1257 ,
"\uFF62" : - 645 ,
"\uFF63" : 3145 ,
\uFF6F : 831 ,
\uFF71 : - 587 ,
\uFF76 : 306 ,
\uFF77 : 568
} ;
this . UW3 _ _ = {
"," : 4889 ,
1 : - 800 ,
"\u2212" : - 1723 ,
"\u3001" : 4889 ,
\u3005 : - 2311 ,
"\u3007" : 5827 ,
"\u300D" : 2670 ,
"\u3013" : - 3573 ,
\u3042 : - 2696 ,
\u3044 : 1006 ,
\u3046 : 2342 ,
\u3048 : 1983 ,
\u304A : - 4864 ,
\u304B : - 1163 ,
\u304C : 3271 ,
\u304F : 1004 ,
\u3051 : 388 ,
\u3052 : 401 ,
\u3053 : - 3552 ,
\u3054 : - 3116 ,
\u3055 : - 1058 ,
\u3057 : - 395 ,
\u3059 : 584 ,
\u305B : 3685 ,
\u305D : - 5228 ,
\u305F : 842 ,
\u3061 : - 521 ,
\u3063 : - 1444 ,
\u3064 : - 1081 ,
\u3066 : 6167 ,
\u3067 : 2318 ,
\u3068 : 1691 ,
\u3069 : - 899 ,
\u306A : - 2788 ,
\u306B : 2745 ,
\u306E : 4056 ,
\u306F : 4555 ,
\u3072 : - 2171 ,
\u3075 : - 1798 ,
\u3078 : 1199 ,
\u307B : - 5516 ,
\u307E : - 4384 ,
\u307F : - 120 ,
\u3081 : 1205 ,
\u3082 : 2323 ,
\u3084 : - 788 ,
\u3088 : - 202 ,
\u3089 : 727 ,
\u308A : 649 ,
\u308B : 5905 ,
\u308C : 2773 ,
\u308F : - 1207 ,
\u3092 : 6620 ,
\u3093 : - 518 ,
\u30A2 : 551 ,
\u30B0 : 1319 ,
\u30B9 : 874 ,
\u30C3 : - 1350 ,
\u30C8 : 521 ,
\u30E0 : 1109 ,
\u30EB : 1591 ,
\u30ED : 2201 ,
\u30F3 : 278 ,
"\u30FB" : - 3794 ,
\u4E00 : - 1619 ,
\u4E0B : - 1759 ,
\u4E16 : - 2087 ,
\u4E21 : 3815 ,
\u4E2D : 653 ,
\u4E3B : - 758 ,
\u4E88 : - 1193 ,
\u4E8C : 974 ,
\u4EBA : 2742 ,
\u4ECA : 792 ,
\u4ED6 : 1889 ,
\u4EE5 : - 1368 ,
\u4F4E : 811 ,
\u4F55 : 4265 ,
\u4F5C : - 361 ,
\u4FDD : - 2439 ,
\u5143 : 4858 ,
\u515A : 3593 ,
\u5168 : 1574 ,
\u516C : - 3030 ,
\u516D : 755 ,
\u5171 : - 1880 ,
\u5186 : 5807 ,
\u518D : 3095 ,
\u5206 : 457 ,
\u521D : 2475 ,
\u5225 : 1129 ,
\u524D : 2286 ,
\u526F : 4437 ,
\u529B : 365 ,
\u52D5 : - 949 ,
\u52D9 : - 1872 ,
\u5316 : 1327 ,
\u5317 : - 1038 ,
\u533A : 4646 ,
\u5343 : - 2309 ,
\u5348 : - 783 ,
\u5354 : - 1006 ,
\u53E3 : 483 ,
\u53F3 : 1233 ,
\u5404 : 3588 ,
\u5408 : - 241 ,
\u540C : 3906 ,
\u548C : - 837 ,
\u54E1 : 4513 ,
\u56FD : 642 ,
\u578B : 1389 ,
\u5834 : 1219 ,
\u5916 : - 241 ,
\u59BB : 2016 ,
\u5B66 : - 1356 ,
\u5B89 : - 423 ,
\u5B9F : - 1008 ,
\u5BB6 : 1078 ,
\u5C0F : - 513 ,
\u5C11 : - 3102 ,
\u5DDE : 1155 ,
\u5E02 : 3197 ,
\u5E73 : - 1804 ,
\u5E74 : 2416 ,
\u5E83 : - 1030 ,
\u5E9C : 1605 ,
\u5EA6 : 1452 ,
\u5EFA : - 2352 ,
\u5F53 : - 3885 ,
\u5F97 : 1905 ,
\u601D : - 1291 ,
\u6027 : 1822 ,
\u6238 : - 488 ,
\u6307 : - 3973 ,
\u653F : - 2013 ,
\u6559 : - 1479 ,
\u6570 : 3222 ,
\u6587 : - 1489 ,
\u65B0 : 1764 ,
\u65E5 : 2099 ,
\u65E7 : 5792 ,
\u6628 : - 661 ,
\u6642 : - 1248 ,
\u66DC : - 951 ,
\u6700 : - 937 ,
\u6708 : 4125 ,
\u671F : 360 ,
\u674E : 3094 ,
\u6751 : 364 ,
\u6771 : - 805 ,
\u6838 : 5156 ,
\u68EE : 2438 ,
\u696D : 484 ,
\u6C0F : 2613 ,
\u6C11 : - 1694 ,
\u6C7A : - 1073 ,
\u6CD5 : 1868 ,
\u6D77 : - 495 ,
\u7121 : 979 ,
\u7269 : 461 ,
\u7279 : - 3850 ,
\u751F : - 273 ,
\u7528 : 914 ,
\u753A : 1215 ,
\u7684 : 7313 ,
\u76F4 : - 1835 ,
\u7701 : 792 ,
\u770C : 6293 ,
\u77E5 : - 1528 ,
\u79C1 : 4231 ,
\u7A0E : 401 ,
\u7ACB : - 960 ,
\u7B2C : 1201 ,
\u7C73 : 7767 ,
\u7CFB : 3066 ,
\u7D04 : 3663 ,
\u7D1A : 1384 ,
\u7D71 : - 4229 ,
\u7DCF : 1163 ,
\u7DDA : 1255 ,
\u8005 : 6457 ,
\u80FD : 725 ,
\u81EA : - 2869 ,
\u82F1 : 785 ,
\u898B : 1044 ,
\u8ABF : - 562 ,
\u8CA1 : - 733 ,
\u8CBB : 1777 ,
\u8ECA : 1835 ,
\u8ECD : 1375 ,
\u8FBC : - 1504 ,
\u901A : - 1136 ,
\u9078 : - 681 ,
\u90CE : 1026 ,
\u90E1 : 4404 ,
\u90E8 : 1200 ,
\u91D1 : 2163 ,
\u9577 : 421 ,
\u958B : - 1432 ,
\u9593 : 1302 ,
\u95A2 : - 1282 ,
\u96E8 : 2009 ,
\u96FB : - 1045 ,
\u975E : 2066 ,
\u99C5 : 1620 ,
"\uFF11" : - 800 ,
"\uFF63" : 2670 ,
"\uFF65" : - 3794 ,
\uFF6F : - 1350 ,
\uFF71 : 551 ,
\uFF78\uFF9E : 1319 ,
\uFF7D : 874 ,
\uFF84 : 521 ,
\uFF91 : 1109 ,
\uFF99 : 1591 ,
\uFF9B : 2201 ,
\uFF9D : 278
} ;
this . UW4 _ _ = {
"," : 3930 ,
"." : 3508 ,
"\u2015" : - 4841 ,
"\u3001" : 3930 ,
"\u3002" : 3508 ,
"\u3007" : 4999 ,
"\u300C" : 1895 ,
"\u300D" : 3798 ,
"\u3013" : - 5156 ,
\u3042 : 4752 ,
\u3044 : - 3435 ,
\u3046 : - 640 ,
\u3048 : - 2514 ,
\u304A : 2405 ,
\u304B : 530 ,
\u304C : 6006 ,
\u304D : - 4482 ,
\u304E : - 3821 ,
\u304F : - 3788 ,
\u3051 : - 4376 ,
\u3052 : - 4734 ,
\u3053 : 2255 ,
\u3054 : 1979 ,
\u3055 : 2864 ,
\u3057 : - 843 ,
\u3058 : - 2506 ,
\u3059 : - 731 ,
\u305A : 1251 ,
\u305B : 181 ,
\u305D : 4091 ,
\u305F : 5034 ,
\u3060 : 5408 ,
\u3061 : - 3654 ,
\u3063 : - 5882 ,
\u3064 : - 1659 ,
\u3066 : 3994 ,
\u3067 : 7410 ,
\u3068 : 4547 ,
\u306A : 5433 ,
\u306B : 6499 ,
\u306C : 1853 ,
\u306D : 1413 ,
\u306E : 7396 ,
\u306F : 8578 ,
\u3070 : 1940 ,
\u3072 : 4249 ,
\u3073 : - 4134 ,
\u3075 : 1345 ,
\u3078 : 6665 ,
\u3079 : - 744 ,
\u307B : 1464 ,
\u307E : 1051 ,
\u307F : - 2082 ,
\u3080 : - 882 ,
\u3081 : - 5046 ,
\u3082 : 4169 ,
\u3083 : - 2666 ,
\u3084 : 2795 ,
\u3087 : - 1544 ,
\u3088 : 3351 ,
\u3089 : - 2922 ,
\u308A : - 9726 ,
\u308B : - 14896 ,
\u308C : - 2613 ,
\u308D : - 4570 ,
\u308F : - 1783 ,
\u3092 : 13150 ,
\u3093 : - 2352 ,
\u30AB : 2145 ,
\u30B3 : 1789 ,
\u30BB : 1287 ,
\u30C3 : - 724 ,
\u30C8 : - 403 ,
\u30E1 : - 1635 ,
\u30E9 : - 881 ,
\u30EA : - 541 ,
\u30EB : - 856 ,
\u30F3 : - 3637 ,
"\u30FB" : - 4371 ,
\u30FC : - 11870 ,
\u4E00 : - 2069 ,
\u4E2D : 2210 ,
\u4E88 : 782 ,
\u4E8B : - 190 ,
\u4E95 : - 1768 ,
\u4EBA : 1036 ,
\u4EE5 : 544 ,
\u4F1A : 950 ,
\u4F53 : - 1286 ,
\u4F5C : 530 ,
\u5074 : 4292 ,
\u5148 : 601 ,
\u515A : - 2006 ,
\u5171 : - 1212 ,
\u5185 : 584 ,
\u5186 : 788 ,
\u521D : 1347 ,
\u524D : 1623 ,
\u526F : 3879 ,
\u529B : - 302 ,
\u52D5 : - 740 ,
\u52D9 : - 2715 ,
\u5316 : 776 ,
\u533A : 4517 ,
\u5354 : 1013 ,
\u53C2 : 1555 ,
\u5408 : - 1834 ,
\u548C : - 681 ,
\u54E1 : - 910 ,
\u5668 : - 851 ,
\u56DE : 1500 ,
\u56FD : - 619 ,
\u5712 : - 1200 ,
\u5730 : 866 ,
\u5834 : - 1410 ,
\u5841 : - 2094 ,
\u58EB : - 1413 ,
\u591A : 1067 ,
\u5927 : 571 ,
\u5B50 : - 4802 ,
\u5B66 : - 1397 ,
\u5B9A : - 1057 ,
\u5BFA : - 809 ,
\u5C0F : 1910 ,
\u5C4B : - 1328 ,
\u5C71 : - 1500 ,
\u5CF6 : - 2056 ,
\u5DDD : - 2667 ,
\u5E02 : 2771 ,
\u5E74 : 374 ,
\u5E81 : - 4556 ,
\u5F8C : 456 ,
\u6027 : 553 ,
\u611F : 916 ,
\u6240 : - 1566 ,
\u652F : 856 ,
\u6539 : 787 ,
\u653F : 2182 ,
\u6559 : 704 ,
\u6587 : 522 ,
\u65B9 : - 856 ,
\u65E5 : 1798 ,
\u6642 : 1829 ,
\u6700 : 845 ,
\u6708 : - 9066 ,
\u6728 : - 485 ,
\u6765 : - 442 ,
\u6821 : - 360 ,
\u696D : - 1043 ,
\u6C0F : 5388 ,
\u6C11 : - 2716 ,
\u6C17 : - 910 ,
\u6CA2 : - 939 ,
\u6E08 : - 543 ,
\u7269 : - 735 ,
\u7387 : 672 ,
\u7403 : - 1267 ,
\u751F : - 1286 ,
\u7523 : - 1101 ,
\u7530 : - 2900 ,
\u753A : 1826 ,
\u7684 : 2586 ,
\u76EE : 922 ,
\u7701 : - 3485 ,
\u770C : 2997 ,
\u7A7A : - 867 ,
\u7ACB : - 2112 ,
\u7B2C : 788 ,
\u7C73 : 2937 ,
\u7CFB : 786 ,
\u7D04 : 2171 ,
\u7D4C : 1146 ,
\u7D71 : - 1169 ,
\u7DCF : 940 ,
\u7DDA : - 994 ,
\u7F72 : 749 ,
\u8005 : 2145 ,
\u80FD : - 730 ,
\u822C : - 852 ,
\u884C : - 792 ,
\u898F : 792 ,
\u8B66 : - 1184 ,
\u8B70 : - 244 ,
\u8C37 : - 1e3 ,
\u8CDE : 730 ,
\u8ECA : - 1481 ,
\u8ECD : 1158 ,
\u8F2A : - 1433 ,
\u8FBC : - 3370 ,
\u8FD1 : 929 ,
\u9053 : - 1291 ,
\u9078 : 2596 ,
\u90CE : - 4866 ,
\u90FD : 1192 ,
\u91CE : - 1100 ,
\u9280 : - 2213 ,
\u9577 : 357 ,
\u9593 : - 2344 ,
\u9662 : - 2297 ,
\u969B : - 2604 ,
\u96FB : - 878 ,
\u9818 : - 1659 ,
\u984C : - 792 ,
\u9928 : - 1984 ,
\u9996 : 1749 ,
\u9AD8 : 2120 ,
"\uFF62" : 1895 ,
"\uFF63" : 3798 ,
"\uFF65" : - 4371 ,
\uFF6F : - 724 ,
\uFF70 : - 11870 ,
\uFF76 : 2145 ,
\uFF7A : 1789 ,
\uFF7E : 1287 ,
\uFF84 : - 403 ,
\uFF92 : - 1635 ,
\uFF97 : - 881 ,
\uFF98 : - 541 ,
\uFF99 : - 856 ,
\uFF9D : - 3637
} ;
this . UW5 _ _ = {
"," : 465 ,
"." : - 299 ,
1 : - 514 ,
E2 : - 32768 ,
"]" : - 2762 ,
"\u3001" : 465 ,
"\u3002" : - 299 ,
"\u300C" : 363 ,
\u3042 : 1655 ,
\u3044 : 331 ,
\u3046 : - 503 ,
\u3048 : 1199 ,
\u304A : 527 ,
\u304B : 647 ,
\u304C : - 421 ,
\u304D : 1624 ,
\u304E : 1971 ,
\u304F : 312 ,
\u3052 : - 983 ,
\u3055 : - 1537 ,
\u3057 : - 1371 ,
\u3059 : - 852 ,
\u3060 : - 1186 ,
\u3061 : 1093 ,
\u3063 : 52 ,
\u3064 : 921 ,
\u3066 : - 18 ,
\u3067 : - 850 ,
\u3068 : - 127 ,
\u3069 : 1682 ,
\u306A : - 787 ,
\u306B : - 1224 ,
\u306E : - 635 ,
\u306F : - 578 ,
\u3079 : 1001 ,
\u307F : 502 ,
\u3081 : 865 ,
\u3083 : 3350 ,
\u3087 : 854 ,
\u308A : - 208 ,
\u308B : 429 ,
\u308C : 504 ,
\u308F : 419 ,
\u3092 : - 1264 ,
\u3093 : 327 ,
\u30A4 : 241 ,
\u30EB : 451 ,
\u30F3 : - 343 ,
\u4E2D : - 871 ,
\u4EAC : 722 ,
\u4F1A : - 1153 ,
\u515A : - 654 ,
\u52D9 : 3519 ,
\u533A : - 901 ,
\u544A : 848 ,
\u54E1 : 2104 ,
\u5927 : - 1296 ,
\u5B66 : - 548 ,
\u5B9A : 1785 ,
\u5D50 : - 1304 ,
\u5E02 : - 2991 ,
\u5E2D : 921 ,
\u5E74 : 1763 ,
\u601D : 872 ,
\u6240 : - 814 ,
\u6319 : 1618 ,
\u65B0 : - 1682 ,
\u65E5 : 218 ,
\u6708 : - 4353 ,
\u67FB : 932 ,
\u683C : 1356 ,
\u6A5F : - 1508 ,
\u6C0F : - 1347 ,
\u7530 : 240 ,
\u753A : - 3912 ,
\u7684 : - 3149 ,
\u76F8 : 1319 ,
\u7701 : - 1052 ,
\u770C : - 4003 ,
\u7814 : - 997 ,
\u793E : - 278 ,
\u7A7A : - 813 ,
\u7D71 : 1955 ,
\u8005 : - 2233 ,
\u8868 : 663 ,
\u8A9E : - 1073 ,
\u8B70 : 1219 ,
\u9078 : - 1018 ,
\u90CE : - 368 ,
\u9577 : 786 ,
\u9593 : 1191 ,
\u984C : 2368 ,
\u9928 : - 689 ,
"\uFF11" : - 514 ,
\uFF25\uFF12 : - 32768 ,
"\uFF62" : 363 ,
\uFF72 : 241 ,
\uFF99 : 451 ,
\uFF9D : - 343
} ;
this . UW6 _ _ = {
"," : 227 ,
"." : 808 ,
1 : - 270 ,
E1 : 306 ,
"\u3001" : 227 ,
"\u3002" : 808 ,
\u3042 : - 307 ,
\u3046 : 189 ,
\u304B : 241 ,
\u304C : - 73 ,
\u304F : - 121 ,
\u3053 : - 200 ,
\u3058 : 1782 ,
\u3059 : 383 ,
\u305F : - 428 ,
\u3063 : 573 ,
\u3066 : - 1014 ,
\u3067 : 101 ,
\u3068 : - 105 ,
\u306A : - 253 ,
\u306B : - 149 ,
\u306E : - 417 ,
\u306F : - 236 ,
\u3082 : - 206 ,
\u308A : 187 ,
\u308B : - 135 ,
\u3092 : 195 ,
\u30EB : - 673 ,
\u30F3 : - 496 ,
\u4E00 : - 277 ,
\u4E2D : 201 ,
\u4EF6 : - 800 ,
\u4F1A : 624 ,
\u524D : 302 ,
\u533A : 1792 ,
\u54E1 : - 1212 ,
\u59D4 : 798 ,
\u5B66 : - 960 ,
\u5E02 : 887 ,
\u5E83 : - 695 ,
\u5F8C : 535 ,
\u696D : - 697 ,
\u76F8 : 753 ,
\u793E : - 507 ,
\u798F : 974 ,
\u7A7A : - 822 ,
\u8005 : 1811 ,
\u9023 : 463 ,
\u90CE : 1082 ,
"\uFF11" : - 270 ,
\uFF25\uFF11 : 306 ,
\uFF99 : - 673 ,
\uFF9D : - 496
} ;
return this ;
}
TinySegmenter . prototype . ctype _ = function ( str ) {
for ( var i in this . chartype _ ) {
if ( str . match ( this . chartype _ [ i ] [ 0 ] ) ) {
return this . chartype _ [ i ] [ 1 ] ;
2025-08-02 12:09:34 +08:00
}
}
2026-05-06 17:32:44 +08:00
return "O" ;
} ;
TinySegmenter . prototype . ts _ = function ( v ) {
if ( v ) {
return v ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
return 0 ;
} ;
TinySegmenter . prototype . segment = function ( input ) {
if ( input == null || input == void 0 || input == "" ) {
return [ ] ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
var result = [ ] ;
var seg = [ "B3" , "B2" , "B1" ] ;
var ctype = [ "O" , "O" , "O" ] ;
var o = input . split ( "" ) ;
for ( i = 0 ; i < o . length ; ++ i ) {
seg . push ( o [ i ] ) ;
ctype . push ( this . ctype _ ( o [ i ] ) ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
seg . push ( "E1" ) ;
seg . push ( "E2" ) ;
seg . push ( "E3" ) ;
ctype . push ( "O" ) ;
ctype . push ( "O" ) ;
ctype . push ( "O" ) ;
var word = seg [ 3 ] ;
var p1 = "U" ;
var p2 = "U" ;
var p3 = "U" ;
for ( var i = 4 ; i < seg . length - 3 ; ++ i ) {
var score = this . BIAS _ _ ;
var w1 = seg [ i - 3 ] ;
var w2 = seg [ i - 2 ] ;
var w3 = seg [ i - 1 ] ;
var w4 = seg [ i ] ;
var w5 = seg [ i + 1 ] ;
var w6 = seg [ i + 2 ] ;
var c1 = ctype [ i - 3 ] ;
var c2 = ctype [ i - 2 ] ;
var c3 = ctype [ i - 1 ] ;
var c4 = ctype [ i ] ;
var c5 = ctype [ i + 1 ] ;
var c6 = ctype [ i + 2 ] ;
score += this . ts _ ( this . UP1 _ _ [ p1 ] ) ;
score += this . ts _ ( this . UP2 _ _ [ p2 ] ) ;
score += this . ts _ ( this . UP3 _ _ [ p3 ] ) ;
score += this . ts _ ( this . BP1 _ _ [ p1 + p2 ] ) ;
score += this . ts _ ( this . BP2 _ _ [ p2 + p3 ] ) ;
score += this . ts _ ( this . UW1 _ _ [ w1 ] ) ;
score += this . ts _ ( this . UW2 _ _ [ w2 ] ) ;
score += this . ts _ ( this . UW3 _ _ [ w3 ] ) ;
score += this . ts _ ( this . UW4 _ _ [ w4 ] ) ;
score += this . ts _ ( this . UW5 _ _ [ w5 ] ) ;
score += this . ts _ ( this . UW6 _ _ [ w6 ] ) ;
score += this . ts _ ( this . BW1 _ _ [ w2 + w3 ] ) ;
score += this . ts _ ( this . BW2 _ _ [ w3 + w4 ] ) ;
score += this . ts _ ( this . BW3 _ _ [ w4 + w5 ] ) ;
score += this . ts _ ( this . TW1 _ _ [ w1 + w2 + w3 ] ) ;
score += this . ts _ ( this . TW2 _ _ [ w2 + w3 + w4 ] ) ;
score += this . ts _ ( this . TW3 _ _ [ w3 + w4 + w5 ] ) ;
score += this . ts _ ( this . TW4 _ _ [ w4 + w5 + w6 ] ) ;
score += this . ts _ ( this . UC1 _ _ [ c1 ] ) ;
score += this . ts _ ( this . UC2 _ _ [ c2 ] ) ;
score += this . ts _ ( this . UC3 _ _ [ c3 ] ) ;
score += this . ts _ ( this . UC4 _ _ [ c4 ] ) ;
score += this . ts _ ( this . UC5 _ _ [ c5 ] ) ;
score += this . ts _ ( this . UC6 _ _ [ c6 ] ) ;
score += this . ts _ ( this . BC1 _ _ [ c2 + c3 ] ) ;
score += this . ts _ ( this . BC2 _ _ [ c3 + c4 ] ) ;
score += this . ts _ ( this . BC3 _ _ [ c4 + c5 ] ) ;
score += this . ts _ ( this . TC1 _ _ [ c1 + c2 + c3 ] ) ;
score += this . ts _ ( this . TC2 _ _ [ c2 + c3 + c4 ] ) ;
score += this . ts _ ( this . TC3 _ _ [ c3 + c4 + c5 ] ) ;
score += this . ts _ ( this . TC4 _ _ [ c4 + c5 + c6 ] ) ;
score += this . ts _ ( this . UQ1 _ _ [ p1 + c1 ] ) ;
score += this . ts _ ( this . UQ2 _ _ [ p2 + c2 ] ) ;
score += this . ts _ ( this . UQ3 _ _ [ p3 + c3 ] ) ;
score += this . ts _ ( this . BQ1 _ _ [ p2 + c2 + c3 ] ) ;
score += this . ts _ ( this . BQ2 _ _ [ p2 + c3 + c4 ] ) ;
score += this . ts _ ( this . BQ3 _ _ [ p3 + c2 + c3 ] ) ;
score += this . ts _ ( this . BQ4 _ _ [ p3 + c3 + c4 ] ) ;
score += this . ts _ ( this . TQ1 _ _ [ p2 + c1 + c2 + c3 ] ) ;
score += this . ts _ ( this . TQ2 _ _ [ p2 + c2 + c3 + c4 ] ) ;
score += this . ts _ ( this . TQ3 _ _ [ p3 + c1 + c2 + c3 ] ) ;
score += this . ts _ ( this . TQ4 _ _ [ p3 + c2 + c3 + c4 ] ) ;
var p = "O" ;
if ( score > 0 ) {
result . push ( word ) ;
word = "" ;
p = "B" ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
p1 = p2 ;
p2 = p3 ;
p3 = p ;
word += seg [ i ] ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
result . push ( word ) ;
return result ;
} ;
var tiny _segmenter _default = TinySegmenter ;
// src/tokenizer/tokenizers/JapaneseTokenizer.ts
var segmenter = new tiny _segmenter _default ( ) ;
function pickTokensAsJapanese ( content , trimPattern ) {
return content . split ( trimPattern ) . filter ( ( x ) => x !== "" ) . flatMap ( ( x ) => joinNumberWithSymbol ( segmenter . segment ( x ) ) ) ;
}
var JapaneseTokenizer = class extends AbstractTokenizer {
tokenize ( content , raw ) {
return pickTokensAsJapanese (
content ,
raw ? / /g : this . getTrimPattern ( "indexing" )
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
}
recursiveTokenize ( content ) {
const tokens = joinNumberWithSymbol (
segmenter . segment ( content ) . flatMap (
( x ) => x === " " ? x : x . split ( " " ) . map ( ( t ) => t === "" ? " " : t )
)
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
const ret = [ ] ;
for ( let i = 0 ; i < tokens . length ; i ++ ) {
if ( i === 0 || tokens [ i ] . length !== 1 || tokens [ i ] !== " " ) {
ret . push ( {
word : tokens . slice ( i ) . join ( "" ) ,
offset : tokens . slice ( 0 , i ) . join ( "" ) . length
} ) ;
}
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
return ret ;
}
shouldIgnoreOnCurrent ( str ) {
return Boolean ( str . match ( /^[ぁ-んa-z A -Z。、ー ]*$/ ) ) ;
}
} ;
// src/tokenizer/tokenizers/KoreanTokenizer.ts
var INPUT _TRIM _CHAR _PATTERN2 = /[\r\n\t\[\]$/:?!=()<>"',|;*~ `_“„«»‹ › ‚ ‘ ’ ”。、·ㆍ∼ 《》〈〉『』「」≪≫「」<>―~…]/ ;
var INDEXING _TRIM _CHAR _PATTERN2 = /[\r\n\t\[\]/:?!=()<>"',|;*~ `_“„«»‹ › ‚ ‘ ’ ”。、·ㆍ∼ 《》〈〉『』「」≪≫「」<>―~…]/ ;
var HANGUL _JAMO = "\u1100-\u11FF" ;
var HANGUL _COMPATIBILITY _JAMO = "\u3130-\u318F" ;
var ENCLOSED _JAMO = "\u3200-\u321E\u3260-\u327F" ;
var CJK _COMPAT _KO = "\u3371-\u33FF" ;
var HANGUL _JAMO _EXTENDED _A = "\uA960-\uA97F" ;
var HANGUL _SYLLABLES = "\uAC00-\uD7AF" ;
var HANGUL _JAMO _EXTENDED _B = "\uD7B0-\uD7FF" ;
var HALFWIDTH _FULLWIDTH _FORMS _KO = "\uFFA0-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC\uFFE0-\uFFE6\uFFE8-\uFFEE" ;
var EXTRA _WORD _CHARACTERS = "\u25CB\xD7\u25A1" ;
var KOREAN _PATTERN = new RegExp (
` [a-zA-Z0-9_ \\ - \\ \\ ${ HANGUL _JAMO } ${ HANGUL _COMPATIBILITY _JAMO } ${ ENCLOSED _JAMO } ${ CJK _COMPAT _KO } ${ HANGUL _JAMO _EXTENDED _A } ${ HANGUL _JAMO } ${ HANGUL _SYLLABLES } ${ HANGUL _JAMO _EXTENDED _B } ${ HALFWIDTH _FULLWIDTH _FORMS _KO } ${ EXTRA _WORD _CHARACTERS } ] `
) ;
var HANJA _PATTERN = /[\u4E00-\u9FFF0-9]/ ;
var KoreanTokenizer = class extends DefaultTokenizer {
constructor ( args ) {
super ( ) ;
this . inputTrimCharPattern = ( args == null ? void 0 : args . treatUnderscoreAsPartOfWord ) ? removeFromPattern ( INPUT _TRIM _CHAR _PATTERN2 , "_" ) : INPUT _TRIM _CHAR _PATTERN2 ;
this . indexingTrimCharPattern = ( args == null ? void 0 : args . treatUnderscoreAsPartOfWord ) ? removeFromPattern ( INDEXING _TRIM _CHAR _PATTERN2 , "_" ) : INDEXING _TRIM _CHAR _PATTERN2 ;
}
tokenize ( content , raw ) {
const tokenized = Array . from ( this . _tokenize ( content , "indexing" ) ) . filter (
( x ) => x . type === "korean" || x . type === "hanja"
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
return raw ? tokenized . map ( ( x ) => x . word ) : tokenized . map ( ( x ) => x . word ) . filter ( ( x ) => ! this . indexingTrimCharPattern . test ( x ) ) ;
}
recursiveTokenize ( content ) {
const offsets = Array . from ( this . _tokenize ( content , "input" ) ) . filter ( ( x ) => ! this . inputTrimCharPattern . test ( x . word ) ) . map ( ( x ) => x . offset ) ;
return [
... offsets . map ( ( i ) => ( {
word : content . slice ( i ) ,
offset : i
} ) )
] ;
}
* _tokenize ( content , target ) {
let startIndex = 0 ;
let previousType = "none" ;
const trimPattern = super . getTrimPattern ( target ) ;
for ( let i = 0 ; i < content . length ; i ++ ) {
const char = content [ i ] ;
if ( trimPattern . test ( char ) ) {
yield {
word : content . slice ( startIndex , i ) ,
offset : startIndex ,
type : previousType
} ;
previousType = "trim" ;
startIndex = i ;
continue ;
}
if ( KOREAN _PATTERN . test ( char ) ) {
if ( previousType === "korean" || previousType === "none" ) {
previousType = "korean" ;
continue ;
}
yield {
word : content . slice ( startIndex , i ) ,
offset : startIndex ,
type : previousType
} ;
previousType = "korean" ;
startIndex = i ;
continue ;
}
if ( HANJA _PATTERN . test ( char ) ) {
if ( previousType === "hanja" || previousType === "none" ) {
previousType = "hanja" ;
continue ;
}
yield {
word : content . slice ( startIndex , i ) ,
offset : startIndex ,
type : previousType
} ;
previousType = "hanja" ;
startIndex = i ;
continue ;
}
if ( previousType === "others" || previousType === "none" ) {
previousType = "others" ;
continue ;
}
yield {
word : content . slice ( startIndex , i ) ,
offset : startIndex ,
type : previousType
} ;
previousType = "others" ;
startIndex = i ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
yield {
word : content . slice ( startIndex , content . length ) ,
offset : startIndex ,
type : previousType
2025-08-02 12:09:34 +08:00
} ;
}
2026-05-06 17:32:44 +08:00
} ;
// src/tokenizer/tokenizer.ts
async function createTokenizer ( strategy , app , settings ) {
switch ( strategy . name ) {
case "default" :
return new DefaultTokenizer ( {
treatUnderscoreAsPartOfWord : settings . treatUnderscoreAsPartOfWord
} ) ;
case "english-only" :
return new EnglishOnlyTokenizer ( {
treatUnderscoreAsPartOfWord : settings . treatUnderscoreAsPartOfWord
} ) ;
case "arabic" :
return new ArabicTokenizer ( ) ;
case "japanese" :
return new JapaneseTokenizer ( ) ;
case "chinese" :
const hasCedict = await app . vault . adapter . exists ( settings . cedictPath ) ;
if ( ! hasCedict ) {
return Promise . reject (
new Error ( ` cedict_ts.u8 doesn't exist in ${ settings . cedictPath } . ` )
) ;
}
const dict = await app . vault . adapter . read ( settings . cedictPath ) ;
return ChineseTokenizer . create ( dict ) ;
case "korean" :
return new KoreanTokenizer ( ) ;
}
}
// src/ui/popup-commands.ts
var import _obsidian6 = require ( "obsidian" ) ;
// src/ui/component/InputDialog.ts
var import _obsidian5 = require ( "obsidian" ) ;
var InputDialog = class extends import _obsidian5 . Modal {
constructor ( args ) {
super ( args . app ) ;
this . args = args ;
this . submitted = false ;
}
onOpen ( ) {
var _a ;
this . titleEl . setText ( this . args . title ) ;
this . inputEl = this . contentEl . createEl ( "input" , {
type : "text" ,
placeholder : ( _a = this . args . placeholder ) != null ? _a : "" ,
cls : "carnelian-input-dialog-input" ,
value : this . args . defaultValue
} ) ;
}
/ * *
* This function returns
* - Promise < string > if submitted not empty string
* - Promise < "" > if submitted empty string
* - Promise < null > if canceled
* /
open ( args ) {
super . open ( ) ;
this . promise = new Promise ( ( resolve ) => {
const listener = ( ev ) => {
if ( ev . isComposing ) {
return ;
}
if ( ev . code === "Enter" ) {
ev . preventDefault ( ) ;
resolve ( this . inputEl . value ) ;
this . submitted = true ;
this . close ( ) ;
}
} ;
this . inputEl . addEventListener ( "keydown" , listener ) ;
this . onClose = ( ) => {
super . onClose ( ) ;
this . inputEl . removeEventListener ( "keydown" , listener ) ;
if ( ! this . submitted ) {
resolve ( null ) ;
}
} ;
if ( args == null ? void 0 : args . initialSelect ) {
this . inputEl . select ( ) ;
}
} ) ;
return this . promise ;
}
} ;
// src/ui/popup-commands.ts
async function selectWithCustomAliasImpl ( popup , evt ) {
var _a , _b ;
if ( ! popup . context || evt . isComposing ) {
return null ;
}
if ( popup . selectionLock ) {
popup . close ( ) ;
return null ;
}
const item = popup . suggestions . values [ popup . suggestions . selectedItem ] ;
if ( item . type !== "internalLink" ) {
return null ;
}
const input = await new InputDialog ( {
app : popup . app ,
title : "Type custom alias" ,
defaultValue : item . value
} ) . open ( { initialSelect : true } ) ;
if ( ! input ) {
return null ;
}
if ( item . value === input ) {
return { item , input , changed : false } ;
}
item . aliasMeta = {
origin : ( _b = ( _a = item . aliasMeta ) == null ? void 0 : _a . origin ) != null ? _b : item . value
} ;
item . value = input ;
return { item , input , changed : true } ;
}
function select ( popup , evt , index ) {
if ( evt . isComposing ) {
return ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
if ( index !== void 0 ) {
popup . setSelectionLock ( false ) ;
popup . suggestions . setSelectedItem ( index , evt ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
if ( popup . selectionLock ) {
popup . close ( ) ;
return true ;
} else {
popup . suggestions . useSelectedItem ( { } ) ;
return false ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
}
async function selectWithCustomAlias ( popup , evt ) {
var _a ;
const result = await selectWithCustomAliasImpl ( popup , evt ) ;
return ( _a = result == null ? void 0 : result . item ) != null ? _a : null ;
}
async function selectWithCustomAliasAndAddToAliases ( popup , evt ) {
const result = await selectWithCustomAliasImpl ( popup , evt ) ;
if ( ! result ) {
return null ;
}
const { item , input , changed } = result ;
if ( ! changed || item . phantom ) {
return item ;
}
const markdownFile = popup . appHelper . getMarkdownFileByPath ( item . createdPath ) ;
if ( ! markdownFile ) {
return item ;
}
let updated = false ;
await popup . app . fileManager . processFrontMatter (
markdownFile ,
( frontmatter ) => {
var _a ;
const aliases = ( _a = ( 0 , import _obsidian6 . parseFrontMatterAliases ) ( frontmatter ) ) != null ? _a : [ ] ;
if ( ! aliases . includes ( input ) ) {
frontmatter . aliases = [ ... aliases , input ] ;
updated = true ;
2025-08-02 12:09:34 +08:00
}
}
2026-05-06 17:32:44 +08:00
) ;
if ( updated ) {
const refreshedRef = popup . app . metadataCache . on ( "changed" , ( f ) => {
popup . refreshInternalLinkTokens ( ) ;
popup . app . metadataCache . offref ( refreshedRef ) ;
} ) ;
}
return item ;
}
function selectWithQueryAlias ( popup , evt ) {
var _a , _b ;
if ( ! popup . context || evt . isComposing ) {
return null ;
}
if ( popup . selectionLock ) {
popup . close ( ) ;
return null ;
}
const item = popup . suggestions . values [ popup . suggestions . selectedItem ] ;
if ( item . type !== "internalLink" ) {
select ( popup , evt ) ;
return null ;
}
item . aliasMeta = {
origin : ( _b = ( _a = item . aliasMeta ) == null ? void 0 : _a . origin ) != null ? _b : item . value
} ;
item . valueForHistory = item . value ;
item . value = item . query ;
return item ;
}
function insertAsText ( popup , evt ) {
if ( ! popup . context || evt . isComposing ) {
return ;
}
if ( popup . selectionLock ) {
popup . close ( ) ;
return true ;
}
const item = popup . suggestions . values [ popup . suggestions . selectedItem ] ;
const editor = popup . context . editor ;
editor . replaceRange (
item . value ,
{
... popup . context . start ,
ch : popup . contextStartCh + item . offset
} ,
popup . context . end
) ;
return false ;
}
function selectNext ( popup , evt ) {
if ( popup . settings . noAutoFocusUntilCycle && popup . selectionLock ) {
popup . setSelectionLock ( false ) ;
} else {
popup . suggestions . setSelectedItem ( popup . suggestions . selectedItem + 1 , evt ) ;
}
return false ;
}
function selectPrevious ( popup , evt ) {
if ( popup . settings . noAutoFocusUntilCycle && popup . selectionLock ) {
popup . setSelectionLock ( false ) ;
} else {
popup . suggestions . setSelectedItem ( popup . suggestions . selectedItem - 1 , evt ) ;
}
return false ;
}
function open ( popup ) {
const item = popup . suggestions . values [ popup . suggestions . selectedItem ] ;
if ( item . type !== "currentVault" && item . type !== "internalLink" && item . type !== "frontMatter" ) {
return false ;
}
const markdownFile = popup . appHelper . getMarkdownFileByPath ( item . createdPath ) ;
if ( ! markdownFile ) {
new import _obsidian6 . Notice ( ` Can't open ${ item . createdPath } ` ) ;
return false ;
}
popup . appHelper . openMarkdownFile ( markdownFile , true ) ;
return false ;
}
function completion ( popup ) {
if ( ! popup . context ) {
return ;
}
const editor = popup . context . editor ;
const currentPhrase = editor . getRange (
{
... popup . context . start ,
ch : popup . contextStartCh
} ,
popup . context . end
) ;
const tokens = popup . tokenizer . recursiveTokenize ( currentPhrase ) ;
const commonPrefixWithToken = tokens . map ( ( t ) => ( {
token : t ,
commonPrefix : findCommonPrefix (
popup . suggestions . values . map ( ( x ) => excludeEmoji ( x . value ) ) . filter ( ( x ) => x . toLowerCase ( ) . startsWith ( t . word . toLowerCase ( ) ) )
)
} ) ) . find ( ( x ) => x . commonPrefix != null ) ;
if ( ! commonPrefixWithToken || currentPhrase === commonPrefixWithToken . commonPrefix ) {
return false ;
}
editor . replaceRange (
commonPrefixWithToken . commonPrefix ,
{
... popup . context . start ,
ch : popup . contextStartCh + commonPrefixWithToken . token . offset
} ,
popup . context . end
) ;
return true ;
}
// src/ui/AutoCompleteSuggest.ts
function buildLogMessage ( message , msec ) {
return ` ${ message } : ${ Math . round ( msec ) } [ms] ` ;
}
var AutoCompleteSuggest = class _AutoCompleteSuggest extends import _obsidian7 . EditorSuggest {
constructor ( app , statusBar ) {
super ( app ) ;
this . selectionLock = false ;
this . pastCurrentTokenSeparatedWhiteSpace = "" ;
this . previousCurrentLine = "" ;
this . previousLinksCacheInActiveFile = /* @__PURE__ */ new Set ( ) ;
this . keymapEventHandler = [ ] ;
this . spareEditorSuggestContext = null ;
this . predictableCycleState = null ;
this . appHelper = new AppHelper ( app ) ;
this . statusBar = statusBar ;
}
triggerComplete ( opt ) {
const editor = this . appHelper . getCurrentEditor ( ) ;
const activeFile = this . app . workspace . getActiveFile ( ) ;
if ( ! editor || ! activeFile ) {
return ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
this . runManually = true ;
if ( opt == null ? void 0 : opt . fallbackLinkify ) {
this . completionMode = this . completionMode === "prefix" ? "partial" : "new" ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
this . trigger ( editor , activeFile , true ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
hideCompletion ( ) {
this . close ( ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
/ * *
* This method update settings
* /
async unsafeLoadHistoryData ( ) {
const historyPath = ( 0 , import _obsidian7 . normalizePath ) (
this . settings . intelligentSuggestionPrioritization . historyFilePath || DEFAULT _HISTORIES _PATH
) ;
if ( await this . appHelper . exists ( historyPath ) ) {
return this . appHelper . loadJson ( historyPath ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
return { } ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
static async new ( app , settings , statusBar , onPersistSelectionHistory ) {
const ins = new _AutoCompleteSuggest ( app , statusBar ) ;
ins . currentFileWordProvider = new CurrentFileWordProvider (
ins . app ,
ins . appHelper
) ;
ins . currentVaultWordProvider = new CurrentVaultWordProvider (
ins . app ,
ins . appHelper
) ;
ins . customDictionaryWordProvider = new CustomDictionaryWordProvider (
ins . app ,
ins . appHelper
) ;
ins . internalLinkWordProvider = new InternalLinkWordProvider (
ins . app ,
ins . appHelper
) ;
ins . frontMatterWordProvider = new FrontMatterWordProvider (
ins . app ,
ins . appHelper
) ;
await ins . updateSettings ( settings ) ;
await ins . refreshIntelligentSuggestionPrioritization ( ) ;
ins . modifyEventRef = app . vault . on ( "modify" , async ( _ ) => {
var _a ;
await ins . refreshCurrentFileTokens ( ) ;
if ( ( _a = ins . selectionHistoryStorage ) == null ? void 0 : _a . shouldPersist ) {
ins . selectionHistoryStorage . syncPersistVersion ( ) ;
onPersistSelectionHistory ( ) ;
2025-08-02 12:09:34 +08:00
}
} ) ;
2026-05-06 17:32:44 +08:00
ins . activeLeafChangeRef = app . workspace . on (
"active-leaf-change" ,
async ( _ ) => {
ins . predictableCycleState = null ;
await ins . refreshCurrentFileTokens ( ) ;
ins . refreshInternalLinkTokens ( ) ;
ins . updateFrontMatterToken ( ) ;
}
) ;
ins . metadataCacheChangeRef = app . metadataCache . on ( "changed" , async ( f ) => {
ins . updateFrontMatterTokenIndex ( f ) ;
if ( ! ins . appHelper . isActiveFile ( f ) ) {
ins . updateFrontMatterToken ( ) ;
}
if ( settings . updateInternalLinksOnSave ) {
await sleep ( 50 ) ;
const currentCache = ins . appHelper . getUnresolvedLinks ( f ) ;
if ( ! setEquals ( ins . previousLinksCacheInActiveFile , currentCache ) ) {
ins . refreshInternalLinkTokens ( ) ;
ins . previousLinksCacheInActiveFile = currentCache ;
}
}
} ) ;
const cacheResolvedRef = app . metadataCache . on ( "resolved" , async ( ) => {
ins . refreshInternalLinkTokens ( ) ;
ins . refreshFrontMatterTokens ( ) ;
ins . refreshCustomDictionaryTokens ( ) ;
ins . refreshCurrentVaultTokens ( ) ;
ins . app . metadataCache . offref ( cacheResolvedRef ) ;
} ) ;
ins . completionMode = ins . matchStrategy . name ;
return ins ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
predictableComplete ( ) {
const editor = this . appHelper . getCurrentEditor ( ) ;
if ( ! editor ) {
return ;
}
const cursor = editor . getCursor ( ) ;
if ( this . predictableCycleState ) {
const state = this . predictableCycleState ;
const currentCandidate = state . candidates [ state . currentIndex ] ;
const expectedCh = state . replacementStartCh + currentCandidate . length ;
if ( cursor . line === state . line && cursor . ch === expectedCh ) {
state . currentIndex = ( state . currentIndex + 1 ) % state . candidates . length ;
const nextCandidate = state . candidates [ state . currentIndex ] ;
editor . replaceRange (
nextCandidate ,
{ line : state . line , ch : state . replacementStartCh } ,
cursor
) ;
this . close ( ) ;
this . debounceClose ( ) ;
return ;
}
this . predictableCycleState = null ;
}
const currentToken = this . tokenizer . tokenize ( editor . getLine ( cursor . line ) . slice ( 0 , cursor . ch ) ) . last ( ) ;
if ( ! currentToken ) {
return ;
}
const candidates = this . collectPredictableCandidates (
editor ,
cursor ,
currentToken
) ;
if ( candidates . length <= 1 ) {
return ;
}
const replacementStartCh = cursor . ch - currentToken . length ;
this . predictableCycleState = {
originalToken : currentToken ,
replacementStartCh ,
line : cursor . line ,
candidates ,
currentIndex : 0
} ;
const suggestion = candidates [ 0 ] ;
editor . replaceRange (
suggestion ,
{ line : cursor . line , ch : replacementStartCh } ,
cursor
) ;
this . close ( ) ;
this . debounceClose ( ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
collectPredictableCandidates ( editor , cursor , originalToken ) {
var _a , _b ;
const seen = /* @__PURE__ */ new Set ( ) ;
const candidates = [ ] ;
const addIfNew = ( token ) => {
if ( token . startsWith ( originalToken ) && token !== originalToken && ! seen . has ( token ) ) {
seen . add ( token ) ;
candidates . push ( token ) ;
}
} ;
const visibleRange = this . appHelper . getVisibleLineRange ( ) ;
const rangeStart = ( _a = visibleRange == null ? void 0 : visibleRange . from ) != null ? _a : Math . max ( cursor . line - 50 , 0 ) ;
const rangeEnd = ( _b = visibleRange == null ? void 0 : visibleRange . to ) != null ? _b : Math . min ( cursor . line + 50 , editor . lineCount ( ) - 1 ) ;
const textAbove = editor . getRange ( { line : rangeStart , ch : 0 } , cursor ) ;
this . tokenizer . tokenize ( textAbove ) . reverse ( ) . slice ( 1 ) . forEach ( addIfNew ) ;
const textBelow = editor . getRange ( cursor , {
line : rangeEnd ,
ch : editor . getLine ( rangeEnd ) . length
2025-08-02 12:09:34 +08:00
} ) ;
2026-05-06 17:32:44 +08:00
this . tokenizer . tokenize ( textBelow ) . forEach ( addIfNew ) ;
candidates . push ( originalToken ) ;
return candidates ;
}
unregister ( ) {
this . app . vault . offref ( this . modifyEventRef ) ;
this . app . workspace . offref ( this . activeLeafChangeRef ) ;
this . app . metadataCache . offref ( this . metadataCacheChangeRef ) ;
}
// settings getters
get tokenizerStrategy ( ) {
return TokenizeStrategy . fromName ( this . settings . strategy ) ;
}
get matchStrategy ( ) {
return MatchStrategy . fromName ( this . settings . matchStrategy ) ;
}
get frontMatterComplementStrategy ( ) {
return SpecificMatchStrategy . fromName (
this . settings . frontMatterComplementMatchStrategy
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
}
get minNumberTriggered ( ) {
const globalMinChars = this . settings . minNumberOfCharactersTriggered || this . tokenizerStrategy . triggerThreshold ;
const providerMinChars = [
this . settings . currentFileMinNumberOfCharactersForTrigger ,
this . settings . currentVaultMinNumberOfCharactersForTrigger ,
this . settings . customDictionaryMinNumberOfCharactersForTrigger ,
this . settings . internalLinkMinNumberOfCharactersForTrigger
] . filter ( ( x ) => x > 0 ) ;
if ( providerMinChars . length === 0 ) {
return globalMinChars ;
}
return Math . min ( globalMinChars , ... providerMinChars ) ;
}
get currentFileMinNumberOfCharacters ( ) {
return this . settings . currentFileMinNumberOfCharacters || this . tokenizerStrategy . indexingThreshold ;
}
get currentVaultMinNumberOfCharacters ( ) {
return this . settings . currentVaultMinNumberOfCharacters || this . tokenizerStrategy . indexingThreshold ;
}
get descriptionOnSuggestion ( ) {
return DescriptionOnSuggestion . fromName (
this . settings . descriptionOnSuggestion
) ;
}
get excludeInternalLinkPrefixPathPatterns ( ) {
return this . settings . excludeInternalLinkPathPrefixPatterns . split ( "\n" ) . filter ( ( x ) => x ) ;
}
// --- end ---
get indexedWords ( ) {
return {
currentFile : this . currentFileWordProvider . wordsByFirstLetter ,
currentVault : this . currentVaultWordProvider . wordsByFirstLetter ,
customDictionary : this . customDictionaryWordProvider . wordsByFirstLetter ,
internalLink : this . internalLinkWordProvider . wordsByFirstLetter ,
frontMatter : this . frontMatterWordProvider . wordsByFirstLetterByKey
} ;
}
async updateSettings ( settings ) {
this . settings = settings ;
this . statusBar . setMatchStrategy ( this . matchStrategy ) ;
this . statusBar . setComplementAutomatically (
this . settings . complementAutomatically
) ;
try {
this . tokenizer = await createTokenizer (
this . tokenizerStrategy ,
this . app ,
this . settings
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
} catch ( e ) {
new import _obsidian7 . Notice ( e . message ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
this . currentFileWordProvider . setSettings ( this . tokenizer ) ;
this . currentVaultWordProvider . setSettings (
this . tokenizer ,
settings . includeCurrentVaultPathPrefixPatterns . split ( "\n" ) . filter ( ( x ) => x ) ,
settings . excludeCurrentVaultPathPrefixPatterns . split ( "\n" ) . filter ( ( x ) => x ) ,
settings . excludeCurrentVaultPathGlobPatterns ,
settings . includeCurrentVaultOnlyFilesUnderCurrentDirectory
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
this . customDictionaryWordProvider . setSettings (
settings . customDictionaryPaths . split ( "\n" ) . filter ( ( x ) => x ) ,
ColumnDelimiter . fromName ( settings . columnDelimiter ) ,
settings . delimiterToDivideSuggestionsForDisplayFromInsertion || null
) ;
this . debounceGetSuggestions = ( 0 , import _obsidian7 . debounce ) (
( context , cb ) => {
const start = performance . now ( ) ;
this . showDebugLog ( ( ) => ` [context.query]: ${ context . query } ` ) ;
const parsedQuery = JSON . parse ( context . query ) ;
const createNewLinkSuggestions = ( ) => parsedQuery . queries . slice ( ) . reverse ( ) . filter ( ( q ) => q . word . length >= this . minNumberTriggered ) . map ( ( q ) => ( {
value : q . word ,
createdPath : "FIXME: " ,
type : "internalLink" ,
phantom : true ,
offset : q . offset
} ) ) ;
if ( parsedQuery . completionMode === "new" ) {
cb ( createNewLinkSuggestions ( ) ) ;
return ;
}
const matchStrategy = MatchStrategy . fromName (
parsedQuery . completionMode
) ;
let words = parsedQuery . queries . filter (
( x , i , xs ) => parsedQuery . currentFrontMatter || this . settings . minNumberOfWordsTriggeredPhrase + i - 1 < xs . length && x . word . length >= this . minNumberTriggered && ! x . word . endsWith ( " " )
) . map ( ( q ) => {
const handler = parsedQuery . currentFrontMatter && this . frontMatterComplementStrategy !== SpecificMatchStrategy . INHERIT ? this . frontMatterComplementStrategy . handler : matchStrategy . handler ;
return handler (
this . indexedWords ,
q . word ,
this . settings . maxNumberOfSuggestions ,
{
frontMatter : parsedQuery . currentFrontMatter ,
selectionHistoryStorage : this . selectionHistoryStorage ,
fuzzy : this . settings . fuzzyMatch ? {
minMatchScore : this . settings . minFuzzyMatchScore
} : void 0 ,
providerMinChars : {
currentFile : this . settings . currentFileMinNumberOfCharactersForTrigger ,
currentVault : this . settings . currentVaultMinNumberOfCharactersForTrigger ,
customDictionary : this . settings . customDictionaryMinNumberOfCharactersForTrigger ,
internalLink : this . settings . internalLinkMinNumberOfCharactersForTrigger
} ,
globalMinChar : this . settings . minNumberOfCharactersTriggered || this . tokenizerStrategy . triggerThreshold
}
) . map ( ( word ) => ( { ... word , offset : q . offset } ) ) ;
} ) . flat ( ) . sort ( ( a , b ) => Number ( a . fuzzy ) - Number ( b . fuzzy ) ) ;
if ( this . completionMode != this . matchStrategy . name && this . completionMode === "partial" ) {
words = words . filter ( ( x ) => x . type === "internalLink" ) ;
if ( words . length === 0 ) {
cb ( createNewLinkSuggestions ( ) ) ;
return ;
}
}
if ( this . settings . excludeSelfInternalLink ) {
words = words . filter (
( x ) => {
var _a ;
return x . type !== "internalLink" || x . createdPath !== ( ( _a = this . appHelper . getActiveFile ( ) ) == null ? void 0 : _a . path ) ;
}
) ;
}
if ( this . settings . excludeExistingInActiveFileInternalLinks ) {
const activeFile = this . appHelper . getActiveFile ( ) ;
const linkPaths = this . appHelper . getResolvedLinks ( activeFile ) ;
words = words . filter (
( x ) => x . type !== "internalLink" || ! linkPaths . includes ( x . createdPath )
) ;
}
cb (
uniqWith ( words , suggestionUniqPredicate ) . slice (
0 ,
this . settings . maxNumberOfSuggestions
)
) ;
this . showDebugLog (
( ) => buildLogMessage ( "Get suggestions" , performance . now ( ) - start )
) ;
} ,
this . settings . delayMilliSeconds ,
true
) ;
this . debounceClose = ( 0 , import _obsidian7 . debounce ) ( ( ) => {
this . close ( ) ;
} , this . settings . delayMilliSeconds + 50 ) ;
this . registerHotkeys ( ) ;
}
registerKeyAsIgnored ( modifiers , key ) {
this . keymapEventHandler . push (
this . scope . register ( modifiers , key , ( evt ) => {
if ( evt . isComposing ) {
return ;
}
this . close ( ) ;
return true ;
2025-08-02 12:09:34 +08:00
} )
) ;
2026-05-06 17:32:44 +08:00
}
setHotKey ( name , handler ) {
this . settings . hotkeys [ name ] . forEach ( ( hk ) => {
this . keymapEventHandler . push (
this . scope . register ( hk . modifiers , hk . key , handler )
) ;
2025-08-02 12:09:34 +08:00
} ) ;
2026-05-06 17:32:44 +08:00
}
setHotKeys ( ... params ) {
params . forEach ( ( args ) => this . setHotKey ( ... args ) ) ;
}
registerHotkeys ( ) {
this . keymapEventHandler . forEach ( ( x ) => this . scope . unregister ( x ) ) ;
this . keymapEventHandler = [ ] ;
const ipKeys = [ "Enter" , "Tab" , "ArrowUp" , "ArrowDown" , "Home" , "End" ] ;
this . scope . keys . filter (
( x ) => {
var _a ;
return ipKeys . map ( ( x2 ) => x2 . toLowerCase ( ) ) . includes ( ( ( _a = x . key ) != null ? _a : "" ) . toLowerCase ( ) ) ;
}
) . forEach ( ( x ) => this . scope . unregister ( x ) ) ;
this . scope . keys . find ( ( x ) => {
var _a ;
return ( ( _a = x . key ) == null ? void 0 : _a . toLowerCase ( ) ) === "escape" ;
} ) . func = ( ) => {
this . close ( ) ;
return this . settings . propagateEsc ;
} ;
this . setHotKeys (
[ "select" , ( evt ) => select ( this , evt ) ] ,
[ "up" , ( evt ) => selectPrevious ( this , evt ) ] ,
[ "down" , ( evt ) => selectNext ( this , evt ) ] ,
[ "select 1st" , ( evt ) => select ( this , evt , 0 ) ] ,
[ "select 2nd" , ( evt ) => select ( this , evt , 1 ) ] ,
[ "select 3rd" , ( evt ) => select ( this , evt , 2 ) ] ,
[ "select 4th" , ( evt ) => select ( this , evt , 3 ) ] ,
[ "select 5th" , ( evt ) => select ( this , evt , 4 ) ] ,
[ "select 6th" , ( evt ) => select ( this , evt , 5 ) ] ,
[ "select 7th" , ( evt ) => select ( this , evt , 6 ) ] ,
[ "select 8th" , ( evt ) => select ( this , evt , 7 ) ] ,
[ "select 9th" , ( evt ) => select ( this , evt , 8 ) ] ,
[
"select with custom alias" ,
( evt ) => {
this . spareEditorSuggestContext = this . context ;
selectWithCustomAlias ( this , evt ) . then ( ( item ) => {
if ( item ) {
this . selectSuggestion ( item ) ;
}
2025-08-02 12:09:34 +08:00
} ) ;
2026-05-06 17:32:44 +08:00
return false ;
}
] ,
[
"select with custom alias and add to aliases" ,
( evt ) => {
this . spareEditorSuggestContext = this . context ;
selectWithCustomAliasAndAddToAliases ( this , evt ) . then ( ( item ) => {
if ( item ) {
this . selectSuggestion ( item ) ;
}
2025-08-02 12:09:34 +08:00
} ) ;
2026-05-06 17:32:44 +08:00
return false ;
}
] ,
[
"select with query alias" ,
( evt ) => {
const item = selectWithQueryAlias ( this , evt ) ;
if ( item ) {
this . selectSuggestion ( item ) ;
}
return false ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
] ,
[ "open" , ( _ ) => open ( this ) ] ,
[ "completion" , ( _ ) => completion ( this ) ] ,
[ "insert as text" , ( evt ) => insertAsText ( this , evt ) ]
) ;
ipKeys . forEach ( ( x ) => this . registerKeyAsIgnored ( [ ] , x ) ) ;
}
async refreshCurrentFileTokens ( ) {
const start = performance . now ( ) ;
this . statusBar . setCurrentFileIndexing ( ) ;
if ( ! this . settings . enableCurrentFileComplement ) {
this . statusBar . setCurrentFileDisabled ( ) ;
this . currentFileWordProvider . clearWords ( ) ;
this . showDebugLog (
( ) => buildLogMessage (
"\u{1F462} Skip: Index current file tokens" ,
performance . now ( ) - start
)
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
return ;
}
await this . currentFileWordProvider . refreshWords ( {
onlyEnglish : this . settings . onlyComplementEnglishOnCurrentFileComplement ,
minNumberOfCharacters : this . currentFileMinNumberOfCharacters ,
makeSynonymAboutEmoji : this . settings . matchingWithoutEmoji ,
makeSynonymAboutAccentsDiacritics : this . settings . treatAccentDiacriticsAsAlphabeticCharacters ,
excludeWordPatterns : this . settings . excludeCurrentFileWordPatterns
2025-08-02 12:09:34 +08:00
} ) ;
2026-05-06 17:32:44 +08:00
this . statusBar . setCurrentFileIndexed (
this . currentFileWordProvider . wordCount
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
this . showDebugLog (
( ) => buildLogMessage ( "Index current file tokens" , performance . now ( ) - start )
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
}
async refreshCurrentVaultTokens ( ) {
const start = performance . now ( ) ;
this . statusBar . setCurrentVaultIndexing ( ) ;
if ( ! this . settings . enableCurrentVaultComplement ) {
this . statusBar . setCurrentVaultDisabled ( ) ;
this . currentVaultWordProvider . clearWords ( ) ;
this . showDebugLog (
( ) => buildLogMessage (
"\u{1F462} Skip: Index current vault tokens" ,
performance . now ( ) - start
)
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
return ;
}
await this . currentVaultWordProvider . refreshWords ( {
minNumberOfCharacters : this . currentVaultMinNumberOfCharacters ,
makeSynonymAboutEmoji : this . settings . matchingWithoutEmoji ,
makeSynonymAboutAccentsDiacritics : this . settings . treatAccentDiacriticsAsAlphabeticCharacters ,
excludeWordPatterns : this . settings . excludeCurrentVaultWordPatterns
2025-08-02 12:09:34 +08:00
} ) ;
2026-05-06 17:32:44 +08:00
this . statusBar . setCurrentVaultIndexed (
this . currentVaultWordProvider . wordCount
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
this . showDebugLog (
( ) => buildLogMessage ( "Index current vault tokens" , performance . now ( ) - start )
) ;
}
async refreshCustomDictionaryTokens ( ) {
const start = performance . now ( ) ;
this . statusBar . setCustomDictionaryIndexing ( ) ;
if ( ! this . settings . enableCustomDictionaryComplement ) {
this . statusBar . setCustomDictionaryDisabled ( ) ;
this . customDictionaryWordProvider . clearWords ( ) ;
this . showDebugLog (
( ) => buildLogMessage (
"\u{1F462}Skip: Index custom dictionary tokens" ,
performance . now ( ) - start
)
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
return ;
}
await this . customDictionaryWordProvider . refreshCustomWords ( {
regexp : this . settings . customDictionaryWordRegexPattern ,
delimiterForHide : this . settings . delimiterToHideSuggestion || void 0 ,
delimiterForDisplay : this . settings . delimiterToDivideSuggestionsForDisplayFromInsertion || void 0 ,
caretSymbol : this . settings . caretLocationSymbolAfterComplement || void 0 ,
makeSynonymAboutEmoji : this . settings . matchingWithoutEmoji ,
makeSynonymAboutAccentsDiacritics : this . settings . treatAccentDiacriticsAsAlphabeticCharacters
2025-08-02 12:09:34 +08:00
} ) ;
2026-05-06 17:32:44 +08:00
this . statusBar . setCustomDictionaryIndexed (
this . customDictionaryWordProvider . wordCount
) ;
this . showDebugLog (
( ) => buildLogMessage (
"Index custom dictionary tokens" ,
performance . now ( ) - start
)
) ;
}
refreshInternalLinkTokens ( ) {
const start = performance . now ( ) ;
this . statusBar . setInternalLinkIndexing ( ) ;
if ( ! this . settings . enableInternalLinkComplement ) {
this . statusBar . setInternalLinkDisabled ( ) ;
this . internalLinkWordProvider . clearWords ( ) ;
this . showDebugLog (
( ) => buildLogMessage (
"\u{1F462}Skip: Index internal link tokens" ,
performance . now ( ) - start
)
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
return ;
}
this . internalLinkWordProvider . refreshWords ( {
wordAsInternalLinkAlias : this . settings . suggestInternalLinkWithAlias ,
excludePathPrefixPatterns : this . excludeInternalLinkPrefixPathPatterns ,
excludePathGlobPatterns : this . settings . excludeInternalLinkPathGlobPatterns ,
makeSynonymAboutEmoji : this . settings . matchingWithoutEmoji ,
makeSynonymAboutAccentsDiacritics : this . settings . treatAccentDiacriticsAsAlphabeticCharacters ,
frontMatterKeyForExclusion : this . settings . frontMatterKeyForExclusionInternalLink ,
tagsForExclusion : this . settings . tagsForExclusionInternalLink ,
excludeUnresolvedLinks : this . settings . excludeUnresolvedInternalLinks
2025-08-02 12:09:34 +08:00
} ) ;
2026-05-06 17:32:44 +08:00
this . statusBar . setInternalLinkIndexed (
this . internalLinkWordProvider . wordCount
) ;
this . showDebugLog (
( ) => buildLogMessage ( "Index internal link tokens" , performance . now ( ) - start )
) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
refreshFrontMatterTokens ( ) {
const start = performance . now ( ) ;
this . statusBar . setFrontMatterIndexing ( ) ;
if ( ! this . settings . enableFrontMatterComplement ) {
this . statusBar . setFrontMatterDisabled ( ) ;
this . frontMatterWordProvider . clearWords ( ) ;
this . showDebugLog (
( ) => buildLogMessage (
"\u{1F462}Skip: Index front matter tokens" ,
performance . now ( ) - start
)
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
return ;
}
this . frontMatterWordProvider . refreshWords ( ) ;
this . statusBar . setFrontMatterIndexed (
this . frontMatterWordProvider . wordCount
) ;
this . showDebugLog (
( ) => buildLogMessage ( "Index front matter tokens" , performance . now ( ) - start )
) ;
}
async refreshIntelligentSuggestionPrioritization ( ) {
if ( this . settings . intelligentSuggestionPrioritization . enabled ) {
this . selectionHistoryStorage = new SelectionHistoryStorage (
await this . unsafeLoadHistoryData ( ) ,
this . settings . intelligentSuggestionPrioritization . maxDaysToKeepHistory ,
this . settings . intelligentSuggestionPrioritization . maxNumberOfHistoryToKeep
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
this . selectionHistoryStorage . purge ( ) ;
} else {
this . selectionHistoryStorage = void 0 ;
}
}
updateFrontMatterTokenIndex ( file ) {
const start = performance . now ( ) ;
if ( ! this . settings . enableFrontMatterComplement ) {
this . showDebugLog (
( ) => buildLogMessage (
"\u{1F462}Skip: Update front matter token index" ,
performance . now ( ) - start
)
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
return ;
}
this . frontMatterWordProvider . updateWordIndex ( file ) ;
this . showDebugLog (
( ) => buildLogMessage (
"Update front matter token index" ,
performance . now ( ) - start
)
2025-08-02 12:09:34 +08:00
) ;
}
2026-05-06 17:32:44 +08:00
updateFrontMatterToken ( ) {
const start = performance . now ( ) ;
if ( ! this . settings . enableFrontMatterComplement ) {
this . showDebugLog (
( ) => buildLogMessage (
"\u{1F462}Skip: Update front matter token" ,
performance . now ( ) - start
)
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
return ;
}
this . frontMatterWordProvider . updateWords ( ) ;
this . statusBar . setFrontMatterIndexed (
this . frontMatterWordProvider . wordCount
) ;
this . showDebugLog (
( ) => buildLogMessage ( "Update front matter token" , performance . now ( ) - start )
) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
onTrigger ( cursor , editor ) {
var _a , _b , _c , _d , _e ;
const start = performance . now ( ) ;
const showDebugLog = ( message ) => {
this . showDebugLog ( ( ) => ` [onTrigger] ${ message } ` ) ;
} ;
const onReturnNull = ( message ) => {
showDebugLog ( message ) ;
this . runManually = false ;
this . completionMode = this . matchStrategy . name ;
this . close ( ) ;
} ;
if ( ! this . settings . complementAutomatically && ! this . isOpen && ! this . runManually ) {
onReturnNull ( "Don't show suggestions" ) ;
return null ;
}
if ( this . settings . disableSuggestionsDuringImeOn && this . appHelper . isIMEOn ( ) && ! this . runManually ) {
onReturnNull ( "Don't show suggestions for IME" ) ;
return null ;
}
const currentFrontMatter = this . settings . enableFrontMatterComplement ? this . appHelper . getCurrentFrontMatter ( ) : void 0 ;
showDebugLog ( ` Current front matter is ${ currentFrontMatter } ` ) ;
const cl = this . appHelper . getCurrentLine ( editor ) ;
if ( equalsAsLiterals ( this . previousCurrentLine , cl ) && ! this . runManually && ! currentFrontMatter && ! this . isOpen ) {
this . previousCurrentLine = cl ;
onReturnNull ( "Don't show suggestions because there are no changes" ) ;
return null ;
}
this . previousCurrentLine = cl ;
const currentLineUntilCursor = this . appHelper . getCurrentLineUntilCursor ( editor ) ;
if ( currentLineUntilCursor . startsWith ( "---" ) ) {
onReturnNull (
"Don't show suggestions because it supposes front matter or horizontal line"
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
return null ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
const suppressedPattern = this . settings . patternsToSuppressTrigger . find (
( p ) => new RegExp ( p ) . test ( currentLineUntilCursor )
) ;
if ( suppressedPattern ) {
onReturnNull (
` Don't show suggestions because it is the ignored pattern: ${ suppressedPattern } `
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
return null ;
}
if ( this . settings . disableSuggestionsInMathBlock && this . appHelper . inMathBlock ( editor ) ) {
onReturnNull (
` Suggestions are disabled while the cursor is inside a Math block. `
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
return null ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
if ( this . settings . disableSuggestionsInCodeBlock && this . appHelper . inCodeBlock ( editor ) ) {
onReturnNull (
` Suggestions are disabled while the cursor is inside a Code block. `
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
return null ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
const tokens = this . tokenizer . tokenize ( currentLineUntilCursor , true ) ;
showDebugLog ( ` tokens is ${ tokens } ` ) ;
const tokenized = this . tokenizer . recursiveTokenize ( currentLineUntilCursor ) ;
let currentTokens = tokenized . slice (
tokenized . length > this . settings . maxNumberOfWordsAsPhrase ? tokenized . length - this . settings . maxNumberOfWordsAsPhrase : 0
) ;
showDebugLog ( ` currentTokens is ${ JSON . stringify ( currentTokens ) } ` ) ;
const currentPhrase = ( _a = currentTokens . first ( ) ) == null ? void 0 : _a . word ;
showDebugLog ( ` currentPhrase is ${ currentPhrase } ` ) ;
if ( ! currentPhrase ) {
onReturnNull ( ` Don't show suggestions because currentPhrase is empty ` ) ;
return null ;
}
const currentTokenSeparatedWhiteSpace = ( _b = currentLineUntilCursor . split ( " " ) . last ( ) ) != null ? _b : "" ;
if ( currentTokenSeparatedWhiteSpace === this . pastCurrentTokenSeparatedWhiteSpace && ! this . runManually && ! this . isOpen ) {
onReturnNull (
` Don't show suggestions because currentTokenSeparatedWhiteSpace doesn't change `
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
return null ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
this . pastCurrentTokenSeparatedWhiteSpace = currentTokenSeparatedWhiteSpace ;
if ( new RegExp ( ` ^[ ${ this . settings . firstCharactersDisableSuggestions } ] ` ) . test (
currentTokenSeparatedWhiteSpace
) ) {
onReturnNull (
` Don't show suggestions for avoiding to conflict with the other commands. `
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
return null ;
}
if ( currentPhrase . length === 1 && Boolean ( currentPhrase . match ( this . tokenizer . getTrimPattern ( "input" ) ) ) ) {
onReturnNull (
` Don't show suggestions because currentPhrase is TRIM_PATTERN `
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
return null ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
if ( ! this . runManually && ! currentFrontMatter && currentPhrase . length < this . minNumberTriggered ) {
onReturnNull (
"Don't show suggestions because currentPhrase is less than minNumberTriggered option"
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
return null ;
}
if ( this . runManually ) {
this . setSelectionLock ( false ) ;
} else {
this . setSelectionLock ( this . settings . noAutoFocusUntilCycle ) ;
}
showDebugLog ( buildLogMessage ( "onTrigger" , performance . now ( ) - start ) ) ;
this . runManually = false ;
const patterns = this . settings . phrasePatternsToSuppressTrigger ;
const suppressedTokens = patterns . length === 0 || currentFrontMatter ? currentTokens : currentTokens . filter (
( t ) => patterns . every ( ( p ) => ! new RegExp ( ` ^ ${ p } $ ` ) . test ( t . word ) )
) ;
if ( suppressedTokens . length === 0 ) {
onReturnNull (
"Don't show suggestions because all tokens are ignored by token pattern"
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
return null ;
}
const currentToken = currentTokens . last ( ) . word ;
if ( currentFrontMatter && currentToken . match ( /[^ ] $/ ) ) {
currentTokens . push ( { word : "" , offset : currentLineUntilCursor . length } ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
this . contextStartCh = cursor . ch - currentPhrase . length ;
return {
start : {
ch : cursor . ch - ( ( _e = ( _d = ( _c = currentTokens . last ( ) ) == null ? void 0 : _c . word ) == null ? void 0 : _d . length ) != null ? _e : 0 ) ,
// For multi-word completion
line : cursor . line
} ,
end : cursor ,
query : JSON . stringify ( {
currentFrontMatter ,
completionMode : this . completionMode ,
queries : suppressedTokens . map ( ( x ) => ( {
... x ,
offset : x . offset - currentTokens [ 0 ] . offset
} ) )
} )
} ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
getSuggestions ( context ) {
return new Promise ( ( resolve ) => {
this . debounceGetSuggestions ( context , ( words ) => {
resolve ( words ) ;
} ) ;
2025-08-02 12:09:34 +08:00
} ) ;
}
2026-05-06 17:32:44 +08:00
renderSuggestion ( word , el ) {
const base = createDiv ( ) ;
let text2 = word . value ;
if ( word . type === "customDictionary" && word . insertedText && this . settings . displayedTextSuffix ) {
text2 += this . settings . displayedTextSuffix ;
}
base . createDiv ( {
text : text2 ,
cls : word . type === "internalLink" && word . aliasMeta ? "various-complements__suggestion-item__content__alias" : void 0
2025-08-02 12:09:34 +08:00
} ) ;
2026-05-06 17:32:44 +08:00
const description = this . descriptionOnSuggestion . toDisplay ( word ) ;
if ( description ) {
base . createDiv ( {
cls : "various-complements__suggestion-item__description" ,
text : ` ${ description } `
2025-08-02 12:09:34 +08:00
} ) ;
2026-05-06 17:32:44 +08:00
}
el . appendChild ( base ) ;
el . addClass ( "various-complements__suggestion-item" ) ;
switch ( word . type ) {
case "currentFile" :
el . addClass ( "various-complements__suggestion-item__current-file" ) ;
2025-08-02 12:09:34 +08:00
break ;
2026-05-06 17:32:44 +08:00
case "currentVault" :
el . addClass ( "various-complements__suggestion-item__current-vault" ) ;
break ;
case "customDictionary" :
el . addClass ( "various-complements__suggestion-item__custom-dictionary" ) ;
break ;
case "internalLink" :
el . addClass ( "various-complements__suggestion-item__internal-link" ) ;
if ( word . phantom ) {
el . addClass ( "various-complements__suggestion-item__phantom" ) ;
}
break ;
case "frontMatter" :
el . addClass ( "various-complements__suggestion-item__front-matter" ) ;
2025-08-02 12:09:34 +08:00
break ;
}
}
2026-05-06 17:32:44 +08:00
constructInternalLinkText ( word , forceWithAlias , option ) {
const query = word . query ;
const preserveFirstLetterCase = Boolean (
( option == null ? void 0 : option . preserveFirstLetterCase ) && query
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
const applyQueryFirstLetterCaseIfNeeded = ( value ) => preserveFirstLetterCase ? applyQueryFirstLetterCase ( value , query ) : value ;
if ( ( this . settings . suggestInternalLinkWithAlias || forceWithAlias ) && word . aliasMeta ) {
const { link : link2 } = this . appHelper . optimizeMarkdownLinkText (
word . aliasMeta . origin
) ;
const displayed2 = applyQueryFirstLetterCaseIfNeeded ( word . value ) ;
return this . appHelper . useWikiLinks ? ` [[ ${ link2 } | ${ displayed2 } ]] ` : ` [ ${ displayed2 } ]( ${ encodeSpace ( link2 ) } .md) ` ;
}
const pattern = this . settings . insertAliasTransformedFromDisplayedInternalLink . enabled ? new RegExp (
this . settings . insertAliasTransformedFromDisplayedInternalLink . beforeRegExp
) : null ;
const match2 = ( value ) => pattern ? Boolean ( value . match ( pattern ) ) : false ;
const replaceByPattern = ( value ) => pattern ? value . replace (
pattern ,
this . settings . insertAliasTransformedFromDisplayedInternalLink . after
) : value ;
const { displayed , link } = this . appHelper . optimizeMarkdownLinkText (
word . phantom ? word . value : word . createdPath
2025-08-02 12:09:34 +08:00
) ;
2026-05-06 17:32:44 +08:00
if ( this . appHelper . newLinkFormat === "shortest" && displayed . includes ( "/" ) ) {
const alias2 = applyQueryFirstLetterCaseIfNeeded ( word . value ) ;
return this . appHelper . useWikiLinks ? ` [[ ${ link } | ${ alias2 } ]] ` : ` [ ${ alias2 } ]( ${ encodeSpace ( link ) } .md) ` ;
}
if ( this . appHelper . useWikiLinks ) {
if ( match2 ( link ) ) {
const alias3 = applyQueryFirstLetterCaseIfNeeded ( replaceByPattern ( link ) ) ;
return ` [[ ${ link } | ${ alias3 } ]] ` ;
}
const alias2 = applyQueryFirstLetterCaseIfNeeded ( displayed ) ;
return alias2 !== link ? ` [[ ${ link } | ${ alias2 } ]] ` : ` [[ ${ link } ]] ` ;
}
const displayedText = match2 ( displayed ) ? replaceByPattern ( displayed ) : displayed ;
const alias = applyQueryFirstLetterCaseIfNeeded ( displayedText ) ;
return ` [ ${ alias } ]( ${ encodeSpace ( link ) } .md) ` ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
selectSuggestion ( word ) {
var _a , _b ;
this . completionMode = this . matchStrategy . name ;
let forceWithAlias = false ;
let context = this . context ;
if ( ! context ) {
context = this . spareEditorSuggestContext ;
this . spareEditorSuggestContext = null ;
forceWithAlias = true ;
}
if ( ! context ) {
return ;
}
let insertedText = word . value ;
if ( word . type === "internalLink" ) {
insertedText = this . constructInternalLinkText ( word , forceWithAlias , {
preserveFirstLetterCase : this . settings . preserveFirstLetterCaseOnInternalLink
} ) ;
}
if ( word . type === "frontMatter" ) {
if ( isInternalLink ( insertedText ) ) {
insertedText = ` " ${ insertedText } " ` ;
}
if ( this . settings . insertCommaAfterFrontMatterCompletion ) {
insertedText = ` ${ insertedText } , ` ;
}
} else {
if ( this . settings . insertSpaceAfterCompletion && ! ( word . type === "customDictionary" && word . ignoreSpaceAfterCompletion ) ) {
insertedText = ` ${ insertedText } ` ;
}
}
let positionToMove = - 1 ;
if ( word . type === "customDictionary" ) {
if ( word . insertedText ) {
insertedText = word . insertedText ;
}
const caret = word . caretSymbol ;
if ( caret ) {
positionToMove = insertedText . indexOf ( caret ) ;
insertedText = insertedText . replace ( caret , "" ) ;
}
}
const editor = context . editor ;
editor . replaceRange (
insertedText ,
{
... context . start ,
ch : this . contextStartCh + word . offset
} ,
context . end
) ;
if ( positionToMove !== - 1 ) {
editor . setCursor (
editor . offsetToPos (
editor . posToOffset ( editor . getCursor ( ) ) - insertedText . length + positionToMove
)
) ;
}
if ( this . appHelper . equalsAsEditorPosition ( context . start , context . end ) ) {
editor . setCursor (
editor . offsetToPos (
editor . posToOffset ( editor . getCursor ( ) ) + insertedText . length
)
) ;
}
( _a = this . selectionHistoryStorage ) == null ? void 0 : _a . increment ( word ) ;
if ( this . settings . showLogAboutPerformanceInConsole ) {
console . log ( "--- history ---" ) ;
console . log ( ( _b = this . selectionHistoryStorage ) == null ? void 0 : _b . data ) ;
}
this . close ( ) ;
this . debounceClose ( ) ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
showDebugLog ( toMessage ) {
if ( this . settings . showLogAboutPerformanceInConsole ) {
console . log ( toMessage ( ) ) ;
}
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
setSelectionLock ( lock ) {
this . selectionLock = lock ;
const lockClass = "various-complements__selection-lock" ;
const body = document . querySelector ( "body" ) ;
if ( lock ) {
body . addClass ( lockClass ) ;
} else {
body . removeClass ( lockClass ) ;
}
2025-08-02 12:09:34 +08:00
}
} ;
// src/ui/CustomDictionaryWordAddModal.ts
var import _obsidian8 = require ( "obsidian" ) ;
2026-05-06 17:32:44 +08:00
// node_modules/.pnpm/svelte@4.2.18/node_modules/svelte/src/runtime/internal/utils.js
2025-08-02 12:09:34 +08:00
function noop ( ) {
}
function assign ( tar , src ) {
2026-05-06 17:32:44 +08:00
for ( const k in src ) tar [ k ] = src [ k ] ;
2025-08-02 12:09:34 +08:00
return (
/** @type {T & S} */
tar
) ;
}
function run ( fn ) {
return fn ( ) ;
}
function blank _object ( ) {
return /* @__PURE__ */ Object . create ( null ) ;
}
function run _all ( fns ) {
fns . forEach ( run ) ;
}
function is _function ( thing ) {
return typeof thing === "function" ;
}
function safe _not _equal ( a , b ) {
return a != a ? b == b : a !== b || a && typeof a === "object" || typeof a === "function" ;
}
function is _empty ( obj ) {
return Object . keys ( obj ) . length === 0 ;
}
function create _slot ( definition , ctx , $$scope , fn ) {
if ( definition ) {
const slot _ctx = get _slot _context ( definition , ctx , $$scope , fn ) ;
return definition [ 0 ] ( slot _ctx ) ;
}
}
function get _slot _context ( definition , ctx , $$scope , fn ) {
return definition [ 1 ] && fn ? assign ( $$scope . ctx . slice ( ) , definition [ 1 ] ( fn ( ctx ) ) ) : $$scope . ctx ;
}
function get _slot _changes ( definition , $$scope , dirty , fn ) {
if ( definition [ 2 ] && fn ) {
const lets = definition [ 2 ] ( fn ( dirty ) ) ;
if ( $$scope . dirty === void 0 ) {
return lets ;
}
if ( typeof lets === "object" ) {
const merged = [ ] ;
const len = Math . max ( $$scope . dirty . length , lets . length ) ;
for ( let i = 0 ; i < len ; i += 1 ) {
merged [ i ] = $$scope . dirty [ i ] | lets [ i ] ;
}
return merged ;
}
return $$scope . dirty | lets ;
}
return $$scope . dirty ;
}
function update _slot _base ( slot , slot _definition , ctx , $$scope , slot _changes , get _slot _context _fn ) {
if ( slot _changes ) {
const slot _context = get _slot _context ( slot _definition , ctx , $$scope , get _slot _context _fn ) ;
slot . p ( slot _context , slot _changes ) ;
}
}
function get _all _dirty _from _scope ( $$scope ) {
if ( $$scope . ctx . length > 32 ) {
const dirty = [ ] ;
const length = $$scope . ctx . length / 32 ;
for ( let i = 0 ; i < length ; i ++ ) {
dirty [ i ] = - 1 ;
}
return dirty ;
}
return - 1 ;
}
function exclude _internal _props ( props ) {
const result = { } ;
2026-05-06 17:32:44 +08:00
for ( const k in props ) if ( k [ 0 ] !== "$" ) result [ k ] = props [ k ] ;
2025-08-02 12:09:34 +08:00
return result ;
}
function compute _rest _props ( props , keys ) {
const rest = { } ;
keys = new Set ( keys ) ;
2026-05-06 17:32:44 +08:00
for ( const k in props ) if ( ! keys . has ( k ) && k [ 0 ] !== "$" ) rest [ k ] = props [ k ] ;
2025-08-02 12:09:34 +08:00
return rest ;
}
function null _to _empty ( value ) {
return value == null ? "" : value ;
}
2026-05-06 17:32:44 +08:00
// node_modules/.pnpm/svelte@4.2.18/node_modules/svelte/src/runtime/internal/globals.js
2025-08-02 12:09:34 +08:00
var globals = typeof window !== "undefined" ? window : typeof globalThis !== "undefined" ? globalThis : (
// @ts-ignore Node typings have this
global
) ;
2026-05-06 17:32:44 +08:00
// node_modules/.pnpm/svelte@4.2.18/node_modules/svelte/src/runtime/internal/ResizeObserverSingleton.js
2025-08-02 12:09:34 +08:00
var ResizeObserverSingleton = class _ResizeObserverSingleton {
/** @param {ResizeObserverOptions} options */
constructor ( options ) {
/ * *
* @ private
* @ readonly
* @ type { WeakMap < Element , import ( './private.js' ) . Listener > }
* /
_ _publicField ( this , "_listeners" , "WeakMap" in globals ? /* @__PURE__ */ new WeakMap ( ) : void 0 ) ;
/ * *
* @ private
* @ type { ResizeObserver }
* /
_ _publicField ( this , "_observer" ) ;
/** @type {ResizeObserverOptions} */
_ _publicField ( this , "options" ) ;
this . options = options ;
}
/ * *
* @ param { Element } element
* @ param { import ( './private.js' ) . Listener } listener
* @ returns { ( ) => void }
* /
observe ( element2 , listener ) {
this . _listeners . set ( element2 , listener ) ;
this . _getObserver ( ) . observe ( element2 , this . options ) ;
return ( ) => {
this . _listeners . delete ( element2 ) ;
this . _observer . unobserve ( element2 ) ;
} ;
}
/ * *
* @ private
* /
_getObserver ( ) {
var _a ;
return ( _a = this . _observer ) != null ? _a : this . _observer = new ResizeObserver ( ( entries ) => {
var _a2 ;
for ( const entry of entries ) {
_ResizeObserverSingleton . entries . set ( entry . target , entry ) ;
( _a2 = this . _listeners . get ( entry . target ) ) == null ? void 0 : _a2 ( entry ) ;
}
} ) ;
}
} ;
ResizeObserverSingleton . entries = "WeakMap" in globals ? /* @__PURE__ */ new WeakMap ( ) : void 0 ;
2026-05-06 17:32:44 +08:00
// node_modules/.pnpm/svelte@4.2.18/node_modules/svelte/src/runtime/internal/dom.js
2025-08-02 12:09:34 +08:00
var is _hydrating = false ;
function start _hydrating ( ) {
is _hydrating = true ;
}
function end _hydrating ( ) {
is _hydrating = false ;
}
function append ( target , node ) {
target . appendChild ( node ) ;
}
function append _styles ( target , style _sheet _id , styles ) {
const append _styles _to = get _root _for _style ( target ) ;
if ( ! append _styles _to . getElementById ( style _sheet _id ) ) {
const style = element ( "style" ) ;
style . id = style _sheet _id ;
style . textContent = styles ;
append _stylesheet ( append _styles _to , style ) ;
}
}
function get _root _for _style ( node ) {
2026-05-06 17:32:44 +08:00
if ( ! node ) return document ;
2025-08-02 12:09:34 +08:00
const root = node . getRootNode ? node . getRootNode ( ) : node . ownerDocument ;
if ( root && /** @type {ShadowRoot} */
root . host ) {
return (
/** @type {ShadowRoot} */
root
) ;
}
return node . ownerDocument ;
}
function append _stylesheet ( node , style ) {
append (
/** @type {Document} */
node . head || node ,
style
) ;
return style . sheet ;
}
function insert ( target , node , anchor ) {
target . insertBefore ( node , anchor || null ) ;
}
function detach ( node ) {
if ( node . parentNode ) {
node . parentNode . removeChild ( node ) ;
}
}
function destroy _each ( iterations , detaching ) {
for ( let i = 0 ; i < iterations . length ; i += 1 ) {
2026-05-06 17:32:44 +08:00
if ( iterations [ i ] ) iterations [ i ] . d ( detaching ) ;
2025-08-02 12:09:34 +08:00
}
}
function element ( name ) {
return document . createElement ( name ) ;
}
function svg _element ( name ) {
return document . createElementNS ( "http://www.w3.org/2000/svg" , name ) ;
}
function text ( data ) {
return document . createTextNode ( data ) ;
}
function space ( ) {
return text ( " " ) ;
}
function listen ( node , event , handler , options ) {
node . addEventListener ( event , handler , options ) ;
return ( ) => node . removeEventListener ( event , handler , options ) ;
}
function attr ( node , attribute , value ) {
2026-05-06 17:32:44 +08:00
if ( value == null ) node . removeAttribute ( attribute ) ;
else if ( node . getAttribute ( attribute ) !== value ) node . setAttribute ( attribute , value ) ;
2025-08-02 12:09:34 +08:00
}
function set _svg _attributes ( node , attributes ) {
for ( const key in attributes ) {
attr ( node , key , attributes [ key ] ) ;
}
}
function children ( element2 ) {
return Array . from ( element2 . childNodes ) ;
}
function set _data ( text2 , data ) {
data = "" + data ;
2026-05-06 17:32:44 +08:00
if ( text2 . data === data ) return ;
2025-08-02 12:09:34 +08:00
text2 . data = /** @type {string} */
data ;
}
function set _input _value ( input , value ) {
input . value = value == null ? "" : value ;
}
function set _style ( node , key , value , important ) {
if ( value == null ) {
node . style . removeProperty ( key ) ;
} else {
node . style . setProperty ( key , value , important ? "important" : "" ) ;
}
}
function select _option ( select2 , value , mounting ) {
for ( let i = 0 ; i < select2 . options . length ; i += 1 ) {
const option = select2 . options [ i ] ;
if ( option . _ _value === value ) {
option . selected = true ;
return ;
}
}
if ( ! mounting || value !== void 0 ) {
select2 . selectedIndex = - 1 ;
}
}
function select _value ( select2 ) {
const selected _option = select2 . querySelector ( ":checked" ) ;
return selected _option && selected _option . _ _value ;
}
function toggle _class ( element2 , name , toggle ) {
element2 . classList . toggle ( name , ! ! toggle ) ;
}
function custom _event ( type , detail , { bubbles = false , cancelable = false } = { } ) {
return new CustomEvent ( type , { detail , bubbles , cancelable } ) ;
}
function get _custom _elements _slots ( element2 ) {
const result = { } ;
element2 . childNodes . forEach (
/** @param {Element} node */
( node ) => {
result [ node . slot || "default" ] = true ;
}
) ;
return result ;
}
2026-05-06 17:32:44 +08:00
// node_modules/.pnpm/svelte@4.2.18/node_modules/svelte/src/runtime/internal/lifecycle.js
2025-08-02 12:09:34 +08:00
var current _component ;
function set _current _component ( component ) {
current _component = component ;
}
function get _current _component ( ) {
2026-05-06 17:32:44 +08:00
if ( ! current _component ) throw new Error ( "Function called outside component initialization" ) ;
2025-08-02 12:09:34 +08:00
return current _component ;
}
function onMount ( fn ) {
get _current _component ( ) . $$ . on _mount . push ( fn ) ;
}
function createEventDispatcher ( ) {
const component = get _current _component ( ) ;
return ( type , detail , { cancelable = false } = { } ) => {
const callbacks = component . $$ . callbacks [ type ] ;
if ( callbacks ) {
const event = custom _event (
/** @type {string} */
type ,
detail ,
{ cancelable }
) ;
callbacks . slice ( ) . forEach ( ( fn ) => {
fn . call ( component , event ) ;
} ) ;
return ! event . defaultPrevented ;
}
return true ;
} ;
}
2026-05-06 17:32:44 +08:00
// node_modules/.pnpm/svelte@4.2.18/node_modules/svelte/src/runtime/internal/scheduler.js
2025-08-02 12:09:34 +08:00
var dirty _components = [ ] ;
var binding _callbacks = [ ] ;
var render _callbacks = [ ] ;
var flush _callbacks = [ ] ;
var resolved _promise = /* @__PURE__ */ Promise . resolve ( ) ;
var update _scheduled = false ;
function schedule _update ( ) {
if ( ! update _scheduled ) {
update _scheduled = true ;
resolved _promise . then ( flush ) ;
}
}
function add _render _callback ( fn ) {
render _callbacks . push ( fn ) ;
}
var seen _callbacks = /* @__PURE__ */ new Set ( ) ;
var flushidx = 0 ;
function flush ( ) {
if ( flushidx !== 0 ) {
return ;
}
const saved _component = current _component ;
do {
try {
while ( flushidx < dirty _components . length ) {
const component = dirty _components [ flushidx ] ;
flushidx ++ ;
set _current _component ( component ) ;
update ( component . $$ ) ;
}
} catch ( e ) {
dirty _components . length = 0 ;
flushidx = 0 ;
throw e ;
}
set _current _component ( null ) ;
dirty _components . length = 0 ;
flushidx = 0 ;
2026-05-06 17:32:44 +08:00
while ( binding _callbacks . length ) binding _callbacks . pop ( ) ( ) ;
2025-08-02 12:09:34 +08:00
for ( let i = 0 ; i < render _callbacks . length ; i += 1 ) {
const callback = render _callbacks [ i ] ;
if ( ! seen _callbacks . has ( callback ) ) {
seen _callbacks . add ( callback ) ;
callback ( ) ;
}
}
render _callbacks . length = 0 ;
} while ( dirty _components . length ) ;
while ( flush _callbacks . length ) {
flush _callbacks . pop ( ) ( ) ;
}
update _scheduled = false ;
seen _callbacks . clear ( ) ;
set _current _component ( saved _component ) ;
}
function update ( $$ ) {
if ( $$ . fragment !== null ) {
$$ . update ( ) ;
run _all ( $$ . before _update ) ;
const dirty = $$ . dirty ;
$$ . dirty = [ - 1 ] ;
$$ . fragment && $$ . fragment . p ( $$ . ctx , dirty ) ;
$$ . after _update . forEach ( add _render _callback ) ;
}
}
function flush _render _callbacks ( fns ) {
const filtered = [ ] ;
const targets = [ ] ;
render _callbacks . forEach ( ( c ) => fns . indexOf ( c ) === - 1 ? filtered . push ( c ) : targets . push ( c ) ) ;
targets . forEach ( ( c ) => c ( ) ) ;
render _callbacks = filtered ;
}
2026-05-06 17:32:44 +08:00
// node_modules/.pnpm/svelte@4.2.18/node_modules/svelte/src/runtime/internal/transitions.js
2025-08-02 12:09:34 +08:00
var outroing = /* @__PURE__ */ new Set ( ) ;
var outros ;
function transition _in ( block , local ) {
if ( block && block . i ) {
outroing . delete ( block ) ;
block . i ( local ) ;
}
}
function transition _out ( block , local , detach2 , callback ) {
if ( block && block . o ) {
2026-05-06 17:32:44 +08:00
if ( outroing . has ( block ) ) return ;
2025-08-02 12:09:34 +08:00
outroing . add ( block ) ;
outros . c . push ( ( ) => {
outroing . delete ( block ) ;
if ( callback ) {
2026-05-06 17:32:44 +08:00
if ( detach2 ) block . d ( 1 ) ;
2025-08-02 12:09:34 +08:00
callback ( ) ;
}
} ) ;
block . o ( local ) ;
} else if ( callback ) {
callback ( ) ;
}
}
2026-05-06 17:32:44 +08:00
// node_modules/.pnpm/svelte@4.2.18/node_modules/svelte/src/runtime/internal/each.js
2025-08-02 12:09:34 +08:00
function ensure _array _like ( array _like _or _iterator ) {
return ( array _like _or _iterator == null ? void 0 : array _like _or _iterator . length ) !== void 0 ? array _like _or _iterator : Array . from ( array _like _or _iterator ) ;
}
2026-05-06 17:32:44 +08:00
// node_modules/.pnpm/svelte@4.2.18/node_modules/svelte/src/runtime/internal/spread.js
2025-08-02 12:09:34 +08:00
function get _spread _update ( levels , updates ) {
const update2 = { } ;
const to _null _out = { } ;
const accounted _for = { $$scope : 1 } ;
let i = levels . length ;
while ( i -- ) {
const o = levels [ i ] ;
const n = updates [ i ] ;
if ( n ) {
for ( const key in o ) {
2026-05-06 17:32:44 +08:00
if ( ! ( key in n ) ) to _null _out [ key ] = 1 ;
2025-08-02 12:09:34 +08:00
}
for ( const key in n ) {
if ( ! accounted _for [ key ] ) {
update2 [ key ] = n [ key ] ;
accounted _for [ key ] = 1 ;
}
}
levels [ i ] = n ;
} else {
for ( const key in o ) {
accounted _for [ key ] = 1 ;
}
}
}
for ( const key in to _null _out ) {
2026-05-06 17:32:44 +08:00
if ( ! ( key in update2 ) ) update2 [ key ] = void 0 ;
2025-08-02 12:09:34 +08:00
}
return update2 ;
}
2026-05-06 17:32:44 +08:00
// node_modules/.pnpm/svelte@4.2.18/node_modules/svelte/src/shared/boolean_attributes.js
2025-08-02 12:09:34 +08:00
var _boolean _attributes = (
/** @type {const} */
[
"allowfullscreen" ,
"allowpaymentrequest" ,
"async" ,
"autofocus" ,
"autoplay" ,
"checked" ,
"controls" ,
"default" ,
"defer" ,
"disabled" ,
"formnovalidate" ,
"hidden" ,
"inert" ,
"ismap" ,
"loop" ,
"multiple" ,
"muted" ,
"nomodule" ,
"novalidate" ,
"open" ,
"playsinline" ,
"readonly" ,
"required" ,
"reversed" ,
"selected"
]
) ;
var boolean _attributes = /* @__PURE__ */ new Set ( [ ... _boolean _attributes ] ) ;
2026-05-06 17:32:44 +08:00
// node_modules/.pnpm/svelte@4.2.18/node_modules/svelte/src/runtime/internal/Component.js
2025-08-02 12:09:34 +08:00
function create _component ( block ) {
block && block . c ( ) ;
}
function mount _component ( component , target , anchor ) {
const { fragment , after _update } = component . $$ ;
fragment && fragment . m ( target , anchor ) ;
add _render _callback ( ( ) => {
const new _on _destroy = component . $$ . on _mount . map ( run ) . filter ( is _function ) ;
if ( component . $$ . on _destroy ) {
component . $$ . on _destroy . push ( ... new _on _destroy ) ;
} else {
run _all ( new _on _destroy ) ;
}
component . $$ . on _mount = [ ] ;
} ) ;
after _update . forEach ( add _render _callback ) ;
}
function destroy _component ( component , detaching ) {
const $$ = component . $$ ;
if ( $$ . fragment !== null ) {
flush _render _callbacks ( $$ . after _update ) ;
run _all ( $$ . on _destroy ) ;
$$ . fragment && $$ . fragment . d ( detaching ) ;
$$ . on _destroy = $$ . fragment = null ;
$$ . ctx = [ ] ;
}
}
function make _dirty ( component , i ) {
if ( component . $$ . dirty [ 0 ] === - 1 ) {
dirty _components . push ( component ) ;
schedule _update ( ) ;
component . $$ . dirty . fill ( 0 ) ;
}
component . $$ . dirty [ i / 31 | 0 ] |= 1 << i % 31 ;
}
function init ( component , options , instance5 , create _fragment5 , not _equal , props , append _styles2 = null , dirty = [ - 1 ] ) {
const parent _component = current _component ;
set _current _component ( component ) ;
const $$ = component . $$ = {
fragment : null ,
ctx : [ ] ,
// state
props ,
update : noop ,
not _equal ,
bound : blank _object ( ) ,
// lifecycle
on _mount : [ ] ,
on _destroy : [ ] ,
on _disconnect : [ ] ,
before _update : [ ] ,
after _update : [ ] ,
context : new Map ( options . context || ( parent _component ? parent _component . $$ . context : [ ] ) ) ,
// everything else
callbacks : blank _object ( ) ,
dirty ,
skip _bound : false ,
root : options . target || parent _component . $$ . root
} ;
append _styles2 && append _styles2 ( $$ . root ) ;
let ready = false ;
$$ . ctx = instance5 ? instance5 ( component , options . props || { } , ( i , ret , ... rest ) => {
const value = rest . length ? rest [ 0 ] : ret ;
if ( $$ . ctx && not _equal ( $$ . ctx [ i ] , $$ . ctx [ i ] = value ) ) {
2026-05-06 17:32:44 +08:00
if ( ! $$ . skip _bound && $$ . bound [ i ] ) $$ . bound [ i ] ( value ) ;
if ( ready ) make _dirty ( component , i ) ;
2025-08-02 12:09:34 +08:00
}
return ret ;
} ) : [ ] ;
$$ . update ( ) ;
ready = true ;
run _all ( $$ . before _update ) ;
$$ . fragment = create _fragment5 ? create _fragment5 ( $$ . ctx ) : false ;
if ( options . target ) {
if ( options . hydrate ) {
start _hydrating ( ) ;
const nodes = children ( options . target ) ;
$$ . fragment && $$ . fragment . l ( nodes ) ;
nodes . forEach ( detach ) ;
} else {
$$ . fragment && $$ . fragment . c ( ) ;
}
2026-05-06 17:32:44 +08:00
if ( options . intro ) transition _in ( component . $$ . fragment ) ;
2025-08-02 12:09:34 +08:00
mount _component ( component , options . target , options . anchor ) ;
end _hydrating ( ) ;
flush ( ) ;
}
set _current _component ( parent _component ) ;
}
var SvelteElement ;
if ( typeof HTMLElement === "function" ) {
SvelteElement = class extends HTMLElement {
constructor ( $$componentCtor , $$slots , use _shadow _dom ) {
super ( ) ;
/** The Svelte component constructor */
_ _publicField ( this , "$$ctor" ) ;
/** Slots */
_ _publicField ( this , "$$s" ) ;
/** The Svelte component instance */
_ _publicField ( this , "$$c" ) ;
/** Whether or not the custom element is connected */
_ _publicField ( this , "$$cn" , false ) ;
/** Component props data */
_ _publicField ( this , "$$d" , { } ) ;
/** `true` if currently in the process of reflecting component props back to attributes */
_ _publicField ( this , "$$r" , false ) ;
/** @type {Record<string, CustomElementPropDefinition>} Props definition (name, reflected, type etc) */
_ _publicField ( this , "$$p_d" , { } ) ;
/** @type {Record<string, Function[]>} Event listeners */
_ _publicField ( this , "$$l" , { } ) ;
/** @type {Map<Function, Function>} Event listener unsubscribe functions */
_ _publicField ( this , "$$l_u" , /* @__PURE__ */ new Map ( ) ) ;
this . $$ctor = $$componentCtor ;
this . $$s = $$slots ;
if ( use _shadow _dom ) {
this . attachShadow ( { mode : "open" } ) ;
}
}
addEventListener ( type , listener , options ) {
this . $$l [ type ] = this . $$l [ type ] || [ ] ;
this . $$l [ type ] . push ( listener ) ;
if ( this . $$c ) {
const unsub = this . $$c . $on ( type , listener ) ;
this . $$l _u . set ( listener , unsub ) ;
}
super . addEventListener ( type , listener , options ) ;
}
removeEventListener ( type , listener , options ) {
super . removeEventListener ( type , listener , options ) ;
if ( this . $$c ) {
const unsub = this . $$l _u . get ( listener ) ;
if ( unsub ) {
unsub ( ) ;
this . $$l _u . delete ( listener ) ;
}
}
}
async connectedCallback ( ) {
this . $$cn = true ;
if ( ! this . $$c ) {
let create _slot2 = function ( name ) {
return ( ) => {
let node ;
const obj = {
c : function create ( ) {
node = element ( "slot" ) ;
if ( name !== "default" ) {
attr ( node , "name" , name ) ;
}
} ,
/ * *
* @ param { HTMLElement } target
* @ param { HTMLElement } [ anchor ]
* /
m : function mount ( target , anchor ) {
insert ( target , node , anchor ) ;
} ,
d : function destroy ( detaching ) {
if ( detaching ) {
detach ( node ) ;
}
}
} ;
return obj ;
} ;
} ;
await Promise . resolve ( ) ;
if ( ! this . $$cn || this . $$c ) {
return ;
}
const $$slots = { } ;
const existing _slots = get _custom _elements _slots ( this ) ;
for ( const name of this . $$s ) {
if ( name in existing _slots ) {
$$slots [ name ] = [ create _slot2 ( name ) ] ;
}
}
for ( const attribute of this . attributes ) {
const name = this . $$g _p ( attribute . name ) ;
if ( ! ( name in this . $$d ) ) {
this . $$d [ name ] = get _custom _element _value ( name , attribute . value , this . $$p _d , "toProp" ) ;
}
}
for ( const key in this . $$p _d ) {
if ( ! ( key in this . $$d ) && this [ key ] !== void 0 ) {
this . $$d [ key ] = this [ key ] ;
delete this [ key ] ;
}
}
this . $$c = new this . $$ctor ( {
target : this . shadowRoot || this ,
props : {
... this . $$d ,
$$slots ,
$$scope : {
ctx : [ ]
}
}
} ) ;
const reflect _attributes = ( ) => {
this . $$r = true ;
for ( const key in this . $$p _d ) {
this . $$d [ key ] = this . $$c . $$ . ctx [ this . $$c . $$ . props [ key ] ] ;
if ( this . $$p _d [ key ] . reflect ) {
const attribute _value = get _custom _element _value (
key ,
this . $$d [ key ] ,
this . $$p _d ,
"toAttribute"
) ;
if ( attribute _value == null ) {
this . removeAttribute ( this . $$p _d [ key ] . attribute || key ) ;
} else {
this . setAttribute ( this . $$p _d [ key ] . attribute || key , attribute _value ) ;
}
}
}
this . $$r = false ;
} ;
this . $$c . $$ . after _update . push ( reflect _attributes ) ;
reflect _attributes ( ) ;
for ( const type in this . $$l ) {
for ( const listener of this . $$l [ type ] ) {
const unsub = this . $$c . $on ( type , listener ) ;
this . $$l _u . set ( listener , unsub ) ;
}
}
this . $$l = { } ;
}
}
// We don't need this when working within Svelte code, but for compatibility of people using this outside of Svelte
// and setting attributes through setAttribute etc, this is helpful
attributeChangedCallback ( attr2 , _oldValue , newValue ) {
var _a ;
2026-05-06 17:32:44 +08:00
if ( this . $$r ) return ;
2025-08-02 12:09:34 +08:00
attr2 = this . $$g _p ( attr2 ) ;
this . $$d [ attr2 ] = get _custom _element _value ( attr2 , newValue , this . $$p _d , "toProp" ) ;
( _a = this . $$c ) == null ? void 0 : _a . $set ( { [ attr2 ] : this . $$d [ attr2 ] } ) ;
}
disconnectedCallback ( ) {
this . $$cn = false ;
Promise . resolve ( ) . then ( ( ) => {
2026-05-06 17:32:44 +08:00
if ( ! this . $$cn && this . $$c ) {
2025-08-02 12:09:34 +08:00
this . $$c . $destroy ( ) ;
this . $$c = void 0 ;
}
} ) ;
}
$$g _p ( attribute _name ) {
return Object . keys ( this . $$p _d ) . find (
( key ) => this . $$p _d [ key ] . attribute === attribute _name || ! this . $$p _d [ key ] . attribute && key . toLowerCase ( ) === attribute _name
) || attribute _name ;
}
} ;
}
function get _custom _element _value ( prop , value , props _definition , transform ) {
var _a ;
const type = ( _a = props _definition [ prop ] ) == null ? void 0 : _a . type ;
value = type === "Boolean" && typeof value !== "boolean" ? value != null : value ;
if ( ! transform || ! props _definition [ prop ] ) {
return value ;
} else if ( transform === "toAttribute" ) {
switch ( type ) {
case "Object" :
case "Array" :
return value == null ? null : JSON . stringify ( value ) ;
case "Boolean" :
return value ? "" : null ;
case "Number" :
return value == null ? null : value ;
default :
return value ;
}
} else {
switch ( type ) {
case "Object" :
case "Array" :
return value && JSON . parse ( value ) ;
case "Boolean" :
return value ;
2026-05-06 17:32:44 +08:00
// conversion already handled above
2025-08-02 12:09:34 +08:00
case "Number" :
return value != null ? + value : value ;
default :
return value ;
}
}
}
var SvelteComponent = class {
constructor ( ) {
/ * *
* # # # PRIVATE API
*
* Do not use , may change at any time
*
* @ type { any }
* /
_ _publicField ( this , "$$" ) ;
/ * *
* # # # PRIVATE API
*
* Do not use , may change at any time
*
* @ type { any }
* /
_ _publicField ( this , "$$set" ) ;
}
/** @returns {void} */
$destroy ( ) {
destroy _component ( this , 1 ) ;
this . $destroy = noop ;
}
/ * *
* @ template { Extract < keyof Events , string > } K
* @ param { K } type
* @ param { ( ( e : Events [ K ] ) => void ) | null | undefined } callback
* @ returns { ( ) => void }
* /
$on ( type , callback ) {
if ( ! is _function ( callback ) ) {
return noop ;
}
const callbacks = this . $$ . callbacks [ type ] || ( this . $$ . callbacks [ type ] = [ ] ) ;
callbacks . push ( callback ) ;
return ( ) => {
const index = callbacks . indexOf ( callback ) ;
2026-05-06 17:32:44 +08:00
if ( index !== - 1 ) callbacks . splice ( index , 1 ) ;
2025-08-02 12:09:34 +08:00
} ;
}
/ * *
* @ param { Partial < Props > } props
* @ returns { void }
* /
$set ( props ) {
if ( this . $$set && ! is _empty ( props ) ) {
this . $$ . skip _bound = true ;
this . $$set ( props ) ;
this . $$ . skip _bound = false ;
}
}
} ;
2026-05-06 17:32:44 +08:00
// node_modules/.pnpm/svelte@4.2.18/node_modules/svelte/src/shared/version.js
2025-08-02 12:09:34 +08:00
var PUBLIC _VERSION = "4" ;
2026-05-06 17:32:44 +08:00
// node_modules/.pnpm/svelte@4.2.18/node_modules/svelte/src/runtime/internal/disclose-version/index.js
2025-08-02 12:09:34 +08:00
if ( typeof window !== "undefined" )
( window . _ _svelte || ( window . _ _svelte = { v : /* @__PURE__ */ new Set ( ) } ) ) . v . add ( PUBLIC _VERSION ) ;
// src/ui/component/ObsidianButton.svelte
function create _fragment ( ctx ) {
let button ;
let current ;
let mounted ;
let dispose ;
const default _slot _template = (
/*#slots*/
ctx [ 4 ] . default
) ;
const default _slot = create _slot (
default _slot _template ,
ctx ,
/*$$scope*/
ctx [ 3 ] ,
null
) ;
return {
c ( ) {
button = element ( "button" ) ;
2026-05-06 17:32:44 +08:00
if ( default _slot ) default _slot . c ( ) ;
2025-08-02 12:09:34 +08:00
attr (
button ,
"aria-label" ,
/*popup*/
ctx [ 0 ]
) ;
button . disabled = /*disabled*/
ctx [ 1 ] ;
toggle _class ( button , "mod-cta" , ! /*disabled*/
ctx [ 1 ] ) ;
} ,
m ( target , anchor ) {
insert ( target , button , anchor ) ;
if ( default _slot ) {
default _slot . m ( button , null ) ;
}
current = true ;
if ( ! mounted ) {
dispose = listen (
button ,
"click" ,
/*handleClick*/
ctx [ 2 ]
) ;
mounted = true ;
}
} ,
p ( ctx2 , [ dirty ] ) {
if ( default _slot ) {
if ( default _slot . p && ( ! current || dirty & /*$$scope*/
8 ) ) {
update _slot _base (
default _slot ,
default _slot _template ,
ctx2 ,
/*$$scope*/
ctx2 [ 3 ] ,
! current ? get _all _dirty _from _scope (
/*$$scope*/
ctx2 [ 3 ]
) : get _slot _changes (
default _slot _template ,
/*$$scope*/
ctx2 [ 3 ] ,
dirty ,
null
) ,
null
) ;
}
}
if ( ! current || dirty & /*popup*/
1 ) {
attr (
button ,
"aria-label" ,
/*popup*/
ctx2 [ 0 ]
) ;
}
if ( ! current || dirty & /*disabled*/
2 ) {
button . disabled = /*disabled*/
ctx2 [ 1 ] ;
}
if ( ! current || dirty & /*disabled*/
2 ) {
toggle _class ( button , "mod-cta" , ! /*disabled*/
ctx2 [ 1 ] ) ;
}
} ,
i ( local ) {
2026-05-06 17:32:44 +08:00
if ( current ) return ;
2025-08-02 12:09:34 +08:00
transition _in ( default _slot , local ) ;
current = true ;
} ,
o ( local ) {
transition _out ( default _slot , local ) ;
current = false ;
} ,
d ( detaching ) {
if ( detaching ) {
detach ( button ) ;
}
2026-05-06 17:32:44 +08:00
if ( default _slot ) default _slot . d ( detaching ) ;
2025-08-02 12:09:34 +08:00
mounted = false ;
dispose ( ) ;
}
} ;
}
function instance ( $$self , $$props , $$invalidate ) {
let { $$slots : slots = { } , $$scope } = $$props ;
let { popup = "" } = $$props ;
let { disabled = false } = $$props ;
const dispatcher = createEventDispatcher ( ) ;
const handleClick = ( ) => {
dispatcher ( "click" ) ;
} ;
$$self . $$set = ( $$props2 ) => {
2026-05-06 17:32:44 +08:00
if ( "popup" in $$props2 ) $$invalidate ( 0 , popup = $$props2 . popup ) ;
if ( "disabled" in $$props2 ) $$invalidate ( 1 , disabled = $$props2 . disabled ) ;
if ( "$$scope" in $$props2 ) $$invalidate ( 3 , $$scope = $$props2 . $$scope ) ;
2025-08-02 12:09:34 +08:00
} ;
return [ popup , disabled , handleClick , $$scope , slots ] ;
}
var ObsidianButton = class extends SvelteComponent {
constructor ( options ) {
super ( ) ;
init ( this , options , instance , create _fragment , safe _not _equal , { popup : 0 , disabled : 1 } ) ;
}
} ;
var ObsidianButton _default = ObsidianButton ;
2026-05-06 17:32:44 +08:00
// node_modules/.pnpm/svelte-lucide-icons@0.6.0/node_modules/svelte-lucide-icons/icons/File.svelte
2025-08-02 12:09:34 +08:00
function create _fragment2 ( ctx ) {
let svg ;
2026-05-06 17:32:44 +08:00
let path2 ;
2025-08-02 12:09:34 +08:00
let polyline ;
let current ;
const default _slot _template = (
/*#slots*/
ctx [ 3 ] . default
) ;
const default _slot = create _slot (
default _slot _template ,
ctx ,
/*$$scope*/
ctx [ 2 ] ,
null
) ;
let svg _levels = [
{ xmlns : "http://www.w3.org/2000/svg" } ,
{ width : (
/*size*/
ctx [ 0 ]
) } ,
{ height : (
/*size*/
ctx [ 0 ]
) } ,
{ viewBox : "0 0 24 24" } ,
{ fill : "none" } ,
{ stroke : "currentColor" } ,
{ "stroke-width" : "2" } ,
{ "stroke-linecap" : "round" } ,
{ "stroke-linejoin" : "round" } ,
/*$$restProps*/
ctx [ 1 ]
] ;
let svg _data = { } ;
for ( let i = 0 ; i < svg _levels . length ; i += 1 ) {
svg _data = assign ( svg _data , svg _levels [ i ] ) ;
}
return {
c ( ) {
svg = svg _element ( "svg" ) ;
2026-05-06 17:32:44 +08:00
if ( default _slot ) default _slot . c ( ) ;
path2 = svg _element ( "path" ) ;
2025-08-02 12:09:34 +08:00
polyline = svg _element ( "polyline" ) ;
2026-05-06 17:32:44 +08:00
attr ( path2 , "d" , "M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z" ) ;
2025-08-02 12:09:34 +08:00
attr ( polyline , "points" , "14 2 14 8 20 8" ) ;
set _svg _attributes ( svg , svg _data ) ;
} ,
m ( target , anchor ) {
insert ( target , svg , anchor ) ;
if ( default _slot ) {
default _slot . m ( svg , null ) ;
}
2026-05-06 17:32:44 +08:00
append ( svg , path2 ) ;
2025-08-02 12:09:34 +08:00
append ( svg , polyline ) ;
current = true ;
} ,
p ( ctx2 , [ dirty ] ) {
if ( default _slot ) {
if ( default _slot . p && ( ! current || dirty & /*$$scope*/
4 ) ) {
update _slot _base (
default _slot ,
default _slot _template ,
ctx2 ,
/*$$scope*/
ctx2 [ 2 ] ,
! current ? get _all _dirty _from _scope (
/*$$scope*/
ctx2 [ 2 ]
) : get _slot _changes (
default _slot _template ,
/*$$scope*/
ctx2 [ 2 ] ,
dirty ,
null
) ,
null
) ;
}
}
set _svg _attributes ( svg , svg _data = get _spread _update ( svg _levels , [
{ xmlns : "http://www.w3.org/2000/svg" } ,
( ! current || dirty & /*size*/
1 ) && { width : (
/*size*/
ctx2 [ 0 ]
) } ,
( ! current || dirty & /*size*/
1 ) && { height : (
/*size*/
ctx2 [ 0 ]
) } ,
{ viewBox : "0 0 24 24" } ,
{ fill : "none" } ,
{ stroke : "currentColor" } ,
{ "stroke-width" : "2" } ,
{ "stroke-linecap" : "round" } ,
{ "stroke-linejoin" : "round" } ,
dirty & /*$$restProps*/
2 && /*$$restProps*/
ctx2 [ 1 ]
] ) ) ;
} ,
i ( local ) {
2026-05-06 17:32:44 +08:00
if ( current ) return ;
2025-08-02 12:09:34 +08:00
transition _in ( default _slot , local ) ;
current = true ;
} ,
o ( local ) {
transition _out ( default _slot , local ) ;
current = false ;
} ,
d ( detaching ) {
if ( detaching ) {
detach ( svg ) ;
}
2026-05-06 17:32:44 +08:00
if ( default _slot ) default _slot . d ( detaching ) ;
2025-08-02 12:09:34 +08:00
}
} ;
}
function instance2 ( $$self , $$props , $$invalidate ) {
const omit _props _names = [ "size" ] ;
let $$restProps = compute _rest _props ( $$props , omit _props _names ) ;
let { $$slots : slots = { } , $$scope } = $$props ;
let { size = 24 } = $$props ;
$$self . $$set = ( $$new _props ) => {
$$props = assign ( assign ( { } , $$props ) , exclude _internal _props ( $$new _props ) ) ;
$$invalidate ( 1 , $$restProps = compute _rest _props ( $$props , omit _props _names ) ) ;
2026-05-06 17:32:44 +08:00
if ( "size" in $$new _props ) $$invalidate ( 0 , size = $$new _props . size ) ;
if ( "$$scope" in $$new _props ) $$invalidate ( 2 , $$scope = $$new _props . $$scope ) ;
2025-08-02 12:09:34 +08:00
} ;
return [ size , $$restProps , $$scope , slots ] ;
}
var File = class extends SvelteComponent {
constructor ( options ) {
super ( ) ;
init ( this , options , instance2 , create _fragment2 , safe _not _equal , { size : 0 } ) ;
}
} ;
var File _default = File ;
// src/ui/component/ObsidianIconButton.svelte
function add _css ( target ) {
append _styles ( target , "svelte-12yh6aw" , ".wrapper.svelte-12yh6aw{display:flex;justify-content:center;margin:0}.button-enabled.svelte-12yh6aw:hover{color:var(--interactive-accent)}.button-disabled.svelte-12yh6aw{color:var(--text-muted)}" ) ;
}
function create _fragment3 ( ctx ) {
let div ;
let button ;
let button _class _value ;
let current ;
let mounted ;
let dispose ;
const default _slot _template = (
/*#slots*/
ctx [ 4 ] . default
) ;
const default _slot = create _slot (
default _slot _template ,
ctx ,
/*$$scope*/
ctx [ 3 ] ,
null
) ;
return {
c ( ) {
div = element ( "div" ) ;
button = element ( "button" ) ;
2026-05-06 17:32:44 +08:00
if ( default _slot ) default _slot . c ( ) ;
2025-08-02 12:09:34 +08:00
attr (
button ,
"aria-label" ,
/*popup*/
ctx [ 0 ]
) ;
button . disabled = /*disabled*/
ctx [ 1 ] ;
attr ( button , "class" , button _class _value = null _to _empty (
/*disabled*/
ctx [ 1 ] ? "button-disabled" : "button-enabled"
) + " svelte-12yh6aw" ) ;
set _style ( button , "background-color" , "transparent" ) ;
set _style ( button , "padding" , "0" ) ;
attr ( div , "class" , "wrapper svelte-12yh6aw" ) ;
} ,
m ( target , anchor ) {
insert ( target , div , anchor ) ;
append ( div , button ) ;
if ( default _slot ) {
default _slot . m ( button , null ) ;
}
current = true ;
if ( ! mounted ) {
dispose = listen (
button ,
"click" ,
/*handleClick*/
ctx [ 2 ]
) ;
mounted = true ;
}
} ,
p ( ctx2 , [ dirty ] ) {
if ( default _slot ) {
if ( default _slot . p && ( ! current || dirty & /*$$scope*/
8 ) ) {
update _slot _base (
default _slot ,
default _slot _template ,
ctx2 ,
/*$$scope*/
ctx2 [ 3 ] ,
! current ? get _all _dirty _from _scope (
/*$$scope*/
ctx2 [ 3 ]
) : get _slot _changes (
default _slot _template ,
/*$$scope*/
ctx2 [ 3 ] ,
dirty ,
null
) ,
null
) ;
}
}
if ( ! current || dirty & /*popup*/
1 ) {
attr (
button ,
"aria-label" ,
/*popup*/
ctx2 [ 0 ]
) ;
}
if ( ! current || dirty & /*disabled*/
2 ) {
button . disabled = /*disabled*/
ctx2 [ 1 ] ;
}
if ( ! current || dirty & /*disabled*/
2 && button _class _value !== ( button _class _value = null _to _empty (
/*disabled*/
ctx2 [ 1 ] ? "button-disabled" : "button-enabled"
) + " svelte-12yh6aw" ) ) {
attr ( button , "class" , button _class _value ) ;
}
} ,
i ( local ) {
2026-05-06 17:32:44 +08:00
if ( current ) return ;
2025-08-02 12:09:34 +08:00
transition _in ( default _slot , local ) ;
current = true ;
} ,
o ( local ) {
transition _out ( default _slot , local ) ;
current = false ;
} ,
d ( detaching ) {
if ( detaching ) {
detach ( div ) ;
}
2026-05-06 17:32:44 +08:00
if ( default _slot ) default _slot . d ( detaching ) ;
2025-08-02 12:09:34 +08:00
mounted = false ;
dispose ( ) ;
}
} ;
}
function instance3 ( $$self , $$props , $$invalidate ) {
let { $$slots : slots = { } , $$scope } = $$props ;
let { popup } = $$props ;
let { disabled = false } = $$props ;
const dispatcher = createEventDispatcher ( ) ;
const handleClick = ( ) => {
if ( ! disabled ) {
dispatcher ( "click" ) ;
}
} ;
$$self . $$set = ( $$props2 ) => {
2026-05-06 17:32:44 +08:00
if ( "popup" in $$props2 ) $$invalidate ( 0 , popup = $$props2 . popup ) ;
if ( "disabled" in $$props2 ) $$invalidate ( 1 , disabled = $$props2 . disabled ) ;
if ( "$$scope" in $$props2 ) $$invalidate ( 3 , $$scope = $$props2 . $$scope ) ;
2025-08-02 12:09:34 +08:00
} ;
return [ popup , disabled , handleClick , $$scope , slots ] ;
}
var ObsidianIconButton = class extends SvelteComponent {
constructor ( options ) {
super ( ) ;
init ( this , options , instance3 , create _fragment3 , safe _not _equal , { popup : 0 , disabled : 1 } , add _css ) ;
}
} ;
var ObsidianIconButton _default = ObsidianIconButton ;
// src/ui/component/CustomDictionaryWordAdd.svelte
function get _each _context ( ctx , list , i ) {
const child _ctx = ctx . slice ( ) ;
child _ctx [ 26 ] = list [ i ] ;
return child _ctx ;
}
function create _each _block ( ctx ) {
let option ;
let t0 _value = (
/*dictionary*/
ctx [ 26 ] . path + ""
) ;
let t0 ;
let t1 ;
let option _value _value ;
return {
c ( ) {
option = element ( "option" ) ;
t0 = text ( t0 _value ) ;
t1 = space ( ) ;
option . _ _value = option _value _value = /*dictionary*/
ctx [ 26 ] ;
set _input _value ( option , option . _ _value ) ;
} ,
m ( target , anchor ) {
insert ( target , option , anchor ) ;
append ( option , t0 ) ;
append ( option , t1 ) ;
} ,
p ( ctx2 , dirty ) {
if ( dirty & /*dictionaries*/
32 && t0 _value !== ( t0 _value = /*dictionary*/
2026-05-06 17:32:44 +08:00
ctx2 [ 26 ] . path + "" ) ) set _data ( t0 , t0 _value ) ;
2025-08-02 12:09:34 +08:00
if ( dirty & /*dictionaries*/
32 && option _value _value !== ( option _value _value = /*dictionary*/
ctx2 [ 26 ] ) ) {
option . _ _value = option _value _value ;
set _input _value ( option , option . _ _value ) ;
}
} ,
d ( detaching ) {
if ( detaching ) {
detach ( option ) ;
}
}
} ;
}
function create _default _slot _1 ( ctx ) {
let file ;
let current ;
file = new File _default ( { } ) ;
return {
c ( ) {
create _component ( file . $$ . fragment ) ;
} ,
m ( target , anchor ) {
mount _component ( file , target , anchor ) ;
current = true ;
} ,
i ( local ) {
2026-05-06 17:32:44 +08:00
if ( current ) return ;
2025-08-02 12:09:34 +08:00
transition _in ( file . $$ . fragment , local ) ;
current = true ;
} ,
o ( local ) {
transition _out ( file . $$ . fragment , local ) ;
current = false ;
} ,
d ( detaching ) {
destroy _component ( file , detaching ) ;
}
} ;
}
function create _if _block _1 ( ctx ) {
let label ;
let input ;
let t ;
let mounted ;
let dispose ;
return {
c ( ) {
label = element ( "label" ) ;
input = element ( "input" ) ;
t = text ( "\n Distinguish between display and insertion" ) ;
attr ( input , "type" , "checkbox" ) ;
} ,
m ( target , anchor ) {
insert ( target , label , anchor ) ;
append ( label , input ) ;
input . checked = /*useDisplayedWord*/
ctx [ 1 ] ;
append ( label , t ) ;
if ( ! mounted ) {
dispose = listen (
input ,
"change" ,
/*input_change_handler*/
ctx [ 21 ]
) ;
mounted = true ;
}
} ,
p ( ctx2 , dirty ) {
if ( dirty & /*useDisplayedWord*/
2 ) {
input . checked = /*useDisplayedWord*/
ctx2 [ 1 ] ;
}
} ,
d ( detaching ) {
if ( detaching ) {
detach ( label ) ;
}
mounted = false ;
dispose ( ) ;
}
} ;
}
function create _if _block ( ctx ) {
let h3 ;
let t1 ;
let textarea ;
let mounted ;
let dispose ;
return {
c ( ) {
h3 = element ( "h3" ) ;
h3 . textContent = "Displayed Word" ;
t1 = space ( ) ;
textarea = element ( "textarea" ) ;
set _style ( textarea , "width" , "100%" ) ;
attr ( textarea , "rows" , "3" ) ;
} ,
m ( target , anchor ) {
insert ( target , h3 , anchor ) ;
insert ( target , t1 , anchor ) ;
insert ( target , textarea , anchor ) ;
set _input _value (
textarea ,
/*displayedWord*/
ctx [ 3 ]
) ;
ctx [ 23 ] ( textarea ) ;
if ( ! mounted ) {
dispose = listen (
textarea ,
"input" ,
/*textarea_input_handler*/
ctx [ 22 ]
) ;
mounted = true ;
}
} ,
p ( ctx2 , dirty ) {
if ( dirty & /*displayedWord*/
8 ) {
set _input _value (
textarea ,
/*displayedWord*/
ctx2 [ 3 ]
) ;
}
} ,
d ( detaching ) {
if ( detaching ) {
detach ( h3 ) ;
detach ( t1 ) ;
detach ( textarea ) ;
}
ctx [ 23 ] ( null ) ;
mounted = false ;
dispose ( ) ;
}
} ;
}
function create _default _slot ( ctx ) {
let t ;
return {
c ( ) {
t = text ( "Submit" ) ;
} ,
m ( target , anchor ) {
insert ( target , t , anchor ) ;
} ,
d ( detaching ) {
if ( detaching ) {
detach ( t ) ;
}
}
} ;
}
function create _fragment4 ( ctx ) {
let div2 ;
let h2 ;
let t1 ;
let h30 ;
let t3 ;
let div0 ;
let select2 ;
let t4 ;
let obsidianiconbutton ;
let t5 ;
let h31 ;
let t6 ;
let t7 ;
let textarea0 ;
let t8 ;
let t9 ;
let t10 ;
let h32 ;
let t12 ;
let input ;
let t13 ;
let h33 ;
let t15 ;
let textarea1 ;
let t16 ;
let div1 ;
let obsidianbutton ;
let current ;
let mounted ;
let dispose ;
let each _value = ensure _array _like (
/*dictionaries*/
ctx [ 5 ]
) ;
let each _blocks = [ ] ;
for ( let i = 0 ; i < each _value . length ; i += 1 ) {
each _blocks [ i ] = create _each _block ( get _each _context ( ctx , each _value , i ) ) ;
}
obsidianiconbutton = new ObsidianIconButton _default ( {
props : {
popup : "Open the file" ,
$$slots : { default : [ create _default _slot _1 ] } ,
$$scope : { ctx }
}
} ) ;
obsidianiconbutton . $on (
"click" ,
/*click_handler*/
ctx [ 18 ]
) ;
let if _block0 = (
/*enableDisplayedWord*/
ctx [ 11 ] && create _if _block _1 ( ctx )
) ;
let if _block1 = (
/*useDisplayedWord*/
ctx [ 1 ] && create _if _block ( ctx )
) ;
obsidianbutton = new ObsidianButton _default ( {
props : {
disabled : ! /*enableSubmit*/
ctx [ 12 ] ,
$$slots : { default : [ create _default _slot ] } ,
$$scope : { ctx }
}
} ) ;
obsidianbutton . $on (
"click" ,
/*handleSubmit*/
ctx [ 13 ]
) ;
return {
c ( ) {
div2 = element ( "div" ) ;
h2 = element ( "h2" ) ;
h2 . textContent = "Add a word to a custom dictionary" ;
t1 = space ( ) ;
h30 = element ( "h3" ) ;
h30 . textContent = "Dictionary" ;
t3 = space ( ) ;
div0 = element ( "div" ) ;
select2 = element ( "select" ) ;
for ( let i = 0 ; i < each _blocks . length ; i += 1 ) {
each _blocks [ i ] . c ( ) ;
}
t4 = space ( ) ;
create _component ( obsidianiconbutton . $$ . fragment ) ;
t5 = space ( ) ;
h31 = element ( "h3" ) ;
t6 = text (
/*firstWordTitle*/
ctx [ 10 ]
) ;
t7 = space ( ) ;
textarea0 = element ( "textarea" ) ;
t8 = space ( ) ;
2026-05-06 17:32:44 +08:00
if ( if _block0 ) if _block0 . c ( ) ;
2025-08-02 12:09:34 +08:00
t9 = space ( ) ;
2026-05-06 17:32:44 +08:00
if ( if _block1 ) if _block1 . c ( ) ;
2025-08-02 12:09:34 +08:00
t10 = space ( ) ;
h32 = element ( "h3" ) ;
h32 . textContent = "Description" ;
t12 = space ( ) ;
input = element ( "input" ) ;
t13 = space ( ) ;
h33 = element ( "h3" ) ;
h33 . textContent = "Aliases (for each line)" ;
t15 = space ( ) ;
textarea1 = element ( "textarea" ) ;
t16 = space ( ) ;
div1 = element ( "div" ) ;
create _component ( obsidianbutton . $$ . fragment ) ;
attr ( select2 , "class" , "dropdown" ) ;
if (
/*selectedDictionary*/
ctx [ 2 ] === void 0
2026-05-06 17:32:44 +08:00
) add _render _callback ( ( ) => (
/*select_change_handler*/
ctx [ 17 ] . call ( select2 )
) ) ;
2025-08-02 12:09:34 +08:00
set _style ( div0 , "display" , "flex" ) ;
set _style ( div0 , "gap" , "10px" ) ;
set _style ( textarea0 , "width" , "100%" ) ;
attr ( textarea0 , "rows" , "3" ) ;
attr ( input , "type" , "text" ) ;
set _style ( input , "width" , "100%" ) ;
set _style ( textarea1 , "width" , "100%" ) ;
attr ( textarea1 , "rows" , "3" ) ;
set _style ( div1 , "text-align" , "center" ) ;
set _style ( div1 , "width" , "100%" ) ;
set _style ( div1 , "padding-top" , "15px" ) ;
} ,
m ( target , anchor ) {
insert ( target , div2 , anchor ) ;
append ( div2 , h2 ) ;
append ( div2 , t1 ) ;
append ( div2 , h30 ) ;
append ( div2 , t3 ) ;
append ( div2 , div0 ) ;
append ( div0 , select2 ) ;
for ( let i = 0 ; i < each _blocks . length ; i += 1 ) {
if ( each _blocks [ i ] ) {
each _blocks [ i ] . m ( select2 , null ) ;
}
}
select _option (
select2 ,
/*selectedDictionary*/
ctx [ 2 ] ,
true
) ;
append ( div0 , t4 ) ;
mount _component ( obsidianiconbutton , div0 , null ) ;
append ( div2 , t5 ) ;
append ( div2 , h31 ) ;
append ( h31 , t6 ) ;
append ( div2 , t7 ) ;
append ( div2 , textarea0 ) ;
set _input _value (
textarea0 ,
/*inputWord*/
ctx [ 0 ]
) ;
ctx [ 20 ] ( textarea0 ) ;
append ( div2 , t8 ) ;
2026-05-06 17:32:44 +08:00
if ( if _block0 ) if _block0 . m ( div2 , null ) ;
2025-08-02 12:09:34 +08:00
append ( div2 , t9 ) ;
2026-05-06 17:32:44 +08:00
if ( if _block1 ) if _block1 . m ( div2 , null ) ;
2025-08-02 12:09:34 +08:00
append ( div2 , t10 ) ;
append ( div2 , h32 ) ;
append ( div2 , t12 ) ;
append ( div2 , input ) ;
set _input _value (
input ,
/*description*/
ctx [ 4 ]
) ;
append ( div2 , t13 ) ;
append ( div2 , h33 ) ;
append ( div2 , t15 ) ;
append ( div2 , textarea1 ) ;
set _input _value (
textarea1 ,
/*aliasesStr*/
ctx [ 8 ]
) ;
append ( div2 , t16 ) ;
append ( div2 , div1 ) ;
mount _component ( obsidianbutton , div1 , null ) ;
current = true ;
if ( ! mounted ) {
dispose = [
listen (
select2 ,
"change" ,
/*select_change_handler*/
ctx [ 17 ]
) ,
listen (
textarea0 ,
"input" ,
/*textarea0_input_handler*/
ctx [ 19 ]
) ,
listen (
input ,
"input" ,
/*input_input_handler*/
ctx [ 24 ]
) ,
listen (
textarea1 ,
"input" ,
/*textarea1_input_handler*/
ctx [ 25 ]
)
] ;
mounted = true ;
}
} ,
p ( ctx2 , [ dirty ] ) {
if ( dirty & /*dictionaries*/
32 ) {
each _value = ensure _array _like (
/*dictionaries*/
ctx2 [ 5 ]
) ;
let i ;
for ( i = 0 ; i < each _value . length ; i += 1 ) {
const child _ctx = get _each _context ( ctx2 , each _value , i ) ;
if ( each _blocks [ i ] ) {
each _blocks [ i ] . p ( child _ctx , dirty ) ;
} else {
each _blocks [ i ] = create _each _block ( child _ctx ) ;
each _blocks [ i ] . c ( ) ;
each _blocks [ i ] . m ( select2 , null ) ;
}
}
for ( ; i < each _blocks . length ; i += 1 ) {
each _blocks [ i ] . d ( 1 ) ;
}
each _blocks . length = each _value . length ;
}
if ( dirty & /*selectedDictionary, dictionaries*/
36 ) {
select _option (
select2 ,
/*selectedDictionary*/
ctx2 [ 2 ]
) ;
}
const obsidianiconbutton _changes = { } ;
if ( dirty & /*$$scope*/
536870912 ) {
obsidianiconbutton _changes . $$scope = { dirty , ctx : ctx2 } ;
}
obsidianiconbutton . $set ( obsidianiconbutton _changes ) ;
if ( ! current || dirty & /*firstWordTitle*/
2026-05-06 17:32:44 +08:00
1024 ) set _data (
t6 ,
/*firstWordTitle*/
ctx2 [ 10 ]
) ;
2025-08-02 12:09:34 +08:00
if ( dirty & /*inputWord*/
1 ) {
set _input _value (
textarea0 ,
/*inputWord*/
ctx2 [ 0 ]
) ;
}
if (
/*enableDisplayedWord*/
ctx2 [ 11 ]
) {
if ( if _block0 ) {
if _block0 . p ( ctx2 , dirty ) ;
} else {
if _block0 = create _if _block _1 ( ctx2 ) ;
if _block0 . c ( ) ;
if _block0 . m ( div2 , t9 ) ;
}
} else if ( if _block0 ) {
if _block0 . d ( 1 ) ;
if _block0 = null ;
}
if (
/*useDisplayedWord*/
ctx2 [ 1 ]
) {
if ( if _block1 ) {
if _block1 . p ( ctx2 , dirty ) ;
} else {
if _block1 = create _if _block ( ctx2 ) ;
if _block1 . c ( ) ;
if _block1 . m ( div2 , t10 ) ;
}
} else if ( if _block1 ) {
if _block1 . d ( 1 ) ;
if _block1 = null ;
}
if ( dirty & /*description*/
16 && input . value !== /*description*/
ctx2 [ 4 ] ) {
set _input _value (
input ,
/*description*/
ctx2 [ 4 ]
) ;
}
if ( dirty & /*aliasesStr*/
256 ) {
set _input _value (
textarea1 ,
/*aliasesStr*/
ctx2 [ 8 ]
) ;
}
const obsidianbutton _changes = { } ;
if ( dirty & /*enableSubmit*/
2026-05-06 17:32:44 +08:00
4096 ) obsidianbutton _changes . disabled = ! /*enableSubmit*/
ctx2 [ 12 ] ;
2025-08-02 12:09:34 +08:00
if ( dirty & /*$$scope*/
536870912 ) {
obsidianbutton _changes . $$scope = { dirty , ctx : ctx2 } ;
}
obsidianbutton . $set ( obsidianbutton _changes ) ;
} ,
i ( local ) {
2026-05-06 17:32:44 +08:00
if ( current ) return ;
2025-08-02 12:09:34 +08:00
transition _in ( obsidianiconbutton . $$ . fragment , local ) ;
transition _in ( obsidianbutton . $$ . fragment , local ) ;
current = true ;
} ,
o ( local ) {
transition _out ( obsidianiconbutton . $$ . fragment , local ) ;
transition _out ( obsidianbutton . $$ . fragment , local ) ;
current = false ;
} ,
d ( detaching ) {
if ( detaching ) {
detach ( div2 ) ;
}
destroy _each ( each _blocks , detaching ) ;
destroy _component ( obsidianiconbutton ) ;
ctx [ 20 ] ( null ) ;
2026-05-06 17:32:44 +08:00
if ( if _block0 ) if _block0 . d ( ) ;
if ( if _block1 ) if _block1 . d ( ) ;
2025-08-02 12:09:34 +08:00
destroy _component ( obsidianbutton ) ;
mounted = false ;
run _all ( dispose ) ;
}
} ;
}
function instance4 ( $$self , $$props , $$invalidate ) {
let enableSubmit ;
let enableDisplayedWord ;
let firstWordTitle ;
let { dictionaries } = $$props ;
let { selectedDictionary } = $$props ;
let { inputWord = "" } = $$props ;
let { useDisplayedWord = false } = $$props ;
let { displayedWord = "" } = $$props ;
let { description = "" } = $$props ;
let { aliases = [ ] } = $$props ;
let { dividerForDisplay = "" } = $$props ;
let { onSubmit } = $$props ;
let { onClickFileIcon } = $$props ;
let aliasesStr = aliases . join ( "\n" ) ;
let wordRef = null ;
let displayedWordRef = null ;
const handleSubmit = ( ) => {
onSubmit ( selectedDictionary . path , {
value : displayedWord || inputWord ,
description ,
aliases : aliasesStr . split ( "\n" ) ,
type : "customDictionary" ,
createdPath : selectedDictionary . path ,
insertedText : displayedWord ? inputWord : void 0
} ) ;
} ;
onMount ( ( ) => {
setTimeout (
( ) => wordRef === null || wordRef === void 0 ? void 0 : wordRef . focus ( ) ,
50
) ;
} ) ;
function select _change _handler ( ) {
selectedDictionary = select _value ( this ) ;
$$invalidate ( 2 , selectedDictionary ) ;
$$invalidate ( 5 , dictionaries ) ;
}
const click _handler = ( ) => onClickFileIcon ( selectedDictionary . path ) ;
function textarea0 _input _handler ( ) {
inputWord = this . value ;
$$invalidate ( 0 , inputWord ) ;
}
function textarea0 _binding ( $$value ) {
binding _callbacks [ $$value ? "unshift" : "push" ] ( ( ) => {
wordRef = $$value ;
$$invalidate ( 9 , wordRef ) ;
} ) ;
}
function input _change _handler ( ) {
useDisplayedWord = this . checked ;
$$invalidate ( 1 , useDisplayedWord ) ;
}
function textarea _input _handler ( ) {
displayedWord = this . value ;
$$invalidate ( 3 , displayedWord ) ;
}
function textarea _binding ( $$value ) {
binding _callbacks [ $$value ? "unshift" : "push" ] ( ( ) => {
displayedWordRef = $$value ;
$$invalidate ( 7 , displayedWordRef ) ;
} ) ;
}
function input _input _handler ( ) {
description = this . value ;
$$invalidate ( 4 , description ) ;
}
function textarea1 _input _handler ( ) {
aliasesStr = this . value ;
$$invalidate ( 8 , aliasesStr ) ;
}
$$self . $$set = ( $$props2 ) => {
2026-05-06 17:32:44 +08:00
if ( "dictionaries" in $$props2 ) $$invalidate ( 5 , dictionaries = $$props2 . dictionaries ) ;
if ( "selectedDictionary" in $$props2 ) $$invalidate ( 2 , selectedDictionary = $$props2 . selectedDictionary ) ;
if ( "inputWord" in $$props2 ) $$invalidate ( 0 , inputWord = $$props2 . inputWord ) ;
if ( "useDisplayedWord" in $$props2 ) $$invalidate ( 1 , useDisplayedWord = $$props2 . useDisplayedWord ) ;
if ( "displayedWord" in $$props2 ) $$invalidate ( 3 , displayedWord = $$props2 . displayedWord ) ;
if ( "description" in $$props2 ) $$invalidate ( 4 , description = $$props2 . description ) ;
if ( "aliases" in $$props2 ) $$invalidate ( 14 , aliases = $$props2 . aliases ) ;
if ( "dividerForDisplay" in $$props2 ) $$invalidate ( 15 , dividerForDisplay = $$props2 . dividerForDisplay ) ;
if ( "onSubmit" in $$props2 ) $$invalidate ( 16 , onSubmit = $$props2 . onSubmit ) ;
if ( "onClickFileIcon" in $$props2 ) $$invalidate ( 6 , onClickFileIcon = $$props2 . onClickFileIcon ) ;
2025-08-02 12:09:34 +08:00
} ;
$$self . $$ . update = ( ) => {
if ( $$self . $$ . dirty & /*inputWord*/
1 ) {
2026-05-06 17:32:44 +08:00
$ : $$invalidate ( 12 , enableSubmit = inputWord . length > 0 ) ;
2025-08-02 12:09:34 +08:00
}
if ( $$self . $$ . dirty & /*dividerForDisplay*/
32768 ) {
2026-05-06 17:32:44 +08:00
$ : $$invalidate ( 11 , enableDisplayedWord = Boolean ( dividerForDisplay ) ) ;
2025-08-02 12:09:34 +08:00
}
if ( $$self . $$ . dirty & /*useDisplayedWord*/
2 ) {
2026-05-06 17:32:44 +08:00
$ : $$invalidate ( 10 , firstWordTitle = useDisplayedWord ? "Inserted word" : "Word" ) ;
2025-08-02 12:09:34 +08:00
}
if ( $$self . $$ . dirty & /*useDisplayedWord, displayedWordRef*/
130 ) {
$ : {
if ( useDisplayedWord ) {
displayedWordRef === null || displayedWordRef === void 0 ? void 0 : displayedWordRef . focus ( ) ;
}
}
}
} ;
return [
inputWord ,
useDisplayedWord ,
selectedDictionary ,
displayedWord ,
description ,
dictionaries ,
onClickFileIcon ,
displayedWordRef ,
aliasesStr ,
wordRef ,
firstWordTitle ,
enableDisplayedWord ,
enableSubmit ,
handleSubmit ,
aliases ,
dividerForDisplay ,
onSubmit ,
select _change _handler ,
click _handler ,
textarea0 _input _handler ,
textarea0 _binding ,
input _change _handler ,
textarea _input _handler ,
textarea _binding ,
input _input _handler ,
textarea1 _input _handler
] ;
}
var CustomDictionaryWordAdd = class extends SvelteComponent {
constructor ( options ) {
super ( ) ;
init ( this , options , instance4 , create _fragment4 , safe _not _equal , {
dictionaries : 5 ,
selectedDictionary : 2 ,
inputWord : 0 ,
useDisplayedWord : 1 ,
displayedWord : 3 ,
description : 4 ,
aliases : 14 ,
dividerForDisplay : 15 ,
onSubmit : 16 ,
onClickFileIcon : 6
} ) ;
}
} ;
var CustomDictionaryWordAdd _default = CustomDictionaryWordAdd ;
// src/ui/CustomDictionaryWordAddModal.ts
var CustomDictionaryWordAddModal = class extends import _obsidian8 . Modal {
2026-05-06 17:32:44 +08:00
constructor ( app , dictionaryPaths , initialValue = "" , dividerForDisplay = "" , onSubmit ) {
super ( app ) ;
const appHelper = new AppHelper ( app ) ;
2025-08-02 12:09:34 +08:00
const dictionaries = dictionaryPaths . map ( ( x ) => ( { id : x , path : x } ) ) ;
const { contentEl } = this ;
this . component = new CustomDictionaryWordAdd _default ( {
target : contentEl ,
props : {
dictionaries ,
selectedDictionary : dictionaries [ 0 ] ,
inputWord : initialValue ,
dividerForDisplay ,
onSubmit ,
onClickFileIcon : ( dictionaryPath ) => {
const markdownFile = appHelper . getMarkdownFileByPath ( dictionaryPath ) ;
if ( ! markdownFile ) {
new import _obsidian8 . Notice ( ` Can't open ${ dictionaryPath } ` ) ;
return ;
}
this . close ( ) ;
appHelper . openMarkdownFile ( markdownFile , true ) ;
}
}
} ) ;
}
onClose ( ) {
super . onClose ( ) ;
this . component . $destroy ( ) ;
}
} ;
2026-05-06 17:32:44 +08:00
// src/ui/ProviderStatusBar.ts
var ProviderStatusBar = class _ProviderStatusBar {
constructor ( currentFile , currentVault , customDictionary , internalLink , frontMatter , matchStrategy , complementAutomatically ) {
this . currentFile = currentFile ;
this . currentVault = currentVault ;
this . customDictionary = customDictionary ;
this . internalLink = internalLink ;
this . frontMatter = frontMatter ;
this . matchStrategy = matchStrategy ;
this . complementAutomatically = complementAutomatically ;
2025-08-02 12:09:34 +08:00
}
2026-05-06 17:32:44 +08:00
static new ( statusBar , showMatchStrategy , showIndexingStatus , showComplementAutomatically ) {
const currentFile = showIndexingStatus ? statusBar . createEl ( "span" , {
text : "---" ,
cls : "various-complements__footer various-complements__footer__current-file"
} ) : null ;
const currentVault = showIndexingStatus ? statusBar . createEl ( "span" , {
text : "---" ,
cls : "various-complements__footer various-complements__footer__current-vault"
} ) : null ;
const customDictionary = showIndexingStatus ? statusBar . createEl ( "span" , {
text : "---" ,
cls : "various-complements__footer various-complements__footer__custom-dictionary"
} ) : null ;
const internalLink = showIndexingStatus ? statusBar . createEl ( "span" , {
text : "---" ,
cls : "various-complements__footer various-complements__footer__internal-link"
} ) : null ;
const frontMatter = showIndexingStatus ? statusBar . createEl ( "span" , {
text : "---" ,
cls : "various-complements__footer various-complements__footer__front-matter"
} ) : null ;
const matchStrategy = showMatchStrategy ? statusBar . createEl ( "span" , {
text : "---" ,
cls : "various-complements__footer various-complements__footer__match-strategy"
} ) : null ;
const complementAutomatically = showComplementAutomatically ? statusBar . createEl ( "span" , {
text : "---" ,
cls : "various-complements__footer various-complements__footer__complement-automatically"
} ) : null ;
return new _ProviderStatusBar (
currentFile ,
currentVault ,
customDictionary ,
internalLink ,
frontMatter ,
matchStrategy ,
complementAutomatically
) ;
}
setOnClickStrategyListener ( listener ) {
var _a ;
( _a = this . matchStrategy ) == null ? void 0 : _a . addEventListener ( "click" , listener ) ;
}
setOnClickComplementAutomatically ( listener ) {
var _a ;
( _a = this . complementAutomatically ) == null ? void 0 : _a . addEventListener ( "click" , listener ) ;
}
setCurrentFileDisabled ( ) {
var _a ;
( _a = this . currentFile ) == null ? void 0 : _a . setText ( "---" ) ;
}
setCurrentVaultDisabled ( ) {
var _a ;
( _a = this . currentVault ) == null ? void 0 : _a . setText ( "---" ) ;
}
setCustomDictionaryDisabled ( ) {
var _a ;
( _a = this . customDictionary ) == null ? void 0 : _a . setText ( "---" ) ;
}
setInternalLinkDisabled ( ) {
var _a ;
( _a = this . internalLink ) == null ? void 0 : _a . setText ( "---" ) ;
}
setFrontMatterDisabled ( ) {
var _a ;
( _a = this . frontMatter ) == null ? void 0 : _a . setText ( "---" ) ;
}
setCurrentFileIndexing ( ) {
var _a ;
( _a = this . currentFile ) == null ? void 0 : _a . setText ( "indexing..." ) ;
}
setCurrentVaultIndexing ( ) {
var _a ;
( _a = this . currentVault ) == null ? void 0 : _a . setText ( "indexing..." ) ;
}
setCustomDictionaryIndexing ( ) {
var _a ;
( _a = this . customDictionary ) == null ? void 0 : _a . setText ( "indexing..." ) ;
}
setInternalLinkIndexing ( ) {
var _a ;
( _a = this . internalLink ) == null ? void 0 : _a . setText ( "indexing..." ) ;
}
setFrontMatterIndexing ( ) {
var _a ;
( _a = this . frontMatter ) == null ? void 0 : _a . setText ( "indexing..." ) ;
}
setCurrentFileIndexed ( count ) {
var _a ;
( _a = this . currentFile ) == null ? void 0 : _a . setText ( String ( count ) ) ;
}
setCurrentVaultIndexed ( count ) {
var _a ;
( _a = this . currentVault ) == null ? void 0 : _a . setText ( String ( count ) ) ;
}
setCustomDictionaryIndexed ( count ) {
var _a ;
( _a = this . customDictionary ) == null ? void 0 : _a . setText ( String ( count ) ) ;
}
setInternalLinkIndexed ( count ) {
var _a ;
( _a = this . internalLink ) == null ? void 0 : _a . setText ( String ( count ) ) ;
}
setFrontMatterIndexed ( count ) {
var _a ;
( _a = this . frontMatter ) == null ? void 0 : _a . setText ( String ( count ) ) ;
}
setMatchStrategy ( strategy ) {
var _a ;
( _a = this . matchStrategy ) == null ? void 0 : _a . setText ( strategy . name ) ;
}
setComplementAutomatically ( automatically ) {
var _a ;
( _a = this . complementAutomatically ) == null ? void 0 : _a . setText ( automatically ? "auto" : "manual" ) ;
2025-08-02 12:09:34 +08:00
}
} ;
// src/main.ts
var VariousComponents = class extends import _obsidian9 . Plugin {
onunload ( ) {
super . onunload ( ) ;
this . suggester . unregister ( ) ;
}
async onload ( ) {
this . appHelper = new AppHelper ( this . app ) ;
await this . loadSettings ( ) ;
this . settingTab = new VariousComplementsSettingTab ( this . app , this ) ;
this . addSettingTab ( this . settingTab ) ;
if ( this . appHelper . isMobile ( ) && this . settings . disableOnMobile ) {
return ;
}
this . registerEvent (
this . app . workspace . on ( "editor-menu" , ( menu ) => {
if ( ! this . appHelper . getSelection ( ) ) {
return ;
}
menu . addItem (
( item ) => item . setTitle ( "Add to custom dictionary" ) . setIcon ( "stacked-levels" ) . onClick ( ( ) => {
this . addWordToCustomDictionary ( ) ;
} )
) ;
} )
) ;
this . statusBar = ProviderStatusBar . new (
this . addStatusBarItem ( ) ,
this . settings . showMatchStrategy ,
this . settings . showIndexingStatus ,
this . settings . showComplementAutomatically
) ;
this . statusBar . setOnClickStrategyListener ( async ( ) => {
await this . settingTab . toggleMatchStrategy ( ) ;
} ) ;
this . statusBar . setOnClickComplementAutomatically ( async ( ) => {
await this . settingTab . toggleComplementAutomatically ( ) ;
} ) ;
const debouncedSaveData = ( 0 , import _obsidian9 . debounce ) ( async ( ) => {
var _a , _b ;
await this . appHelper . saveJson (
( 0 , import _obsidian9 . normalizePath ) (
this . settings . intelligentSuggestionPrioritization . historyFilePath || DEFAULT _HISTORIES _PATH
) ,
( _b = ( _a = this . suggester . selectionHistoryStorage ) == null ? void 0 : _a . data ) != null ? _b : { }
) ;
} , 5e3 ) ;
this . suggester = await AutoCompleteSuggest . new (
this . app ,
this . settings ,
this . statusBar ,
debouncedSaveData
) ;
this . registerEditorSuggest ( this . suggester ) ;
this . addCommand ( {
id : "reload-custom-dictionaries" ,
name : "Reload custom dictionaries" ,
hotkeys : [ { modifiers : [ "Mod" , "Shift" ] , key : "r" } ] ,
callback : async ( ) => {
await this . suggester . refreshCustomDictionaryTokens ( ) ;
}
} ) ;
this . addCommand ( {
id : "reload-current-vault" ,
name : "Reload current vault" ,
callback : async ( ) => {
await this . suggester . refreshCurrentVaultTokens ( ) ;
}
} ) ;
this . addCommand ( {
id : "toggle-match-strategy" ,
name : "Toggle Match strategy" ,
callback : async ( ) => {
await this . settingTab . toggleMatchStrategy ( ) ;
}
} ) ;
this . addCommand ( {
id : "toggle-complement-automatically" ,
name : "Toggle Complement automatically" ,
callback : async ( ) => {
await this . settingTab . toggleComplementAutomatically ( ) ;
}
} ) ;
this . addCommand ( {
id : "show-suggestions" ,
name : "Show suggestions" ,
hotkeys : [ { modifiers : [ "Mod" ] , key : " " } ] ,
callback : async ( ) => {
this . suggester . triggerComplete ( ) ;
}
} ) ;
this . addCommand ( {
id : "hide-suggestions" ,
name : "Hide suggestions" ,
callback : async ( ) => {
this . suggester . hideCompletion ( ) ;
}
} ) ;
2026-05-06 17:32:44 +08:00
this . addCommand ( {
id : "fallback-linkify" ,
name : "Fallback linkify" ,
callback : async ( ) => {
this . suggester . triggerComplete ( { fallbackLinkify : true } ) ;
}
} ) ;
2025-08-02 12:09:34 +08:00
this . addCommand ( {
id : "add-word-custom-dictionary" ,
name : "Add a word to a custom dictionary" ,
hotkeys : [ { modifiers : [ "Mod" , "Shift" ] , key : " " } ] ,
callback : async ( ) => {
this . addWordToCustomDictionary ( ) ;
}
} ) ;
this . addCommand ( {
id : "predictable-complements" ,
name : "Predictable complement" ,
callback : async ( ) => {
this . suggester . predictableComplete ( ) ;
}
} ) ;
this . addCommand ( {
id : "copy-plugin-settings" ,
name : "Copy plugin settings" ,
callback : async ( ) => {
await navigator . clipboard . writeText (
this . settingTab . getPluginSettingsAsJsonString ( )
) ;
new import _obsidian9 . Notice ( "Copy settings of Various Complements" ) ;
}
} ) ;
}
async loadSettings ( ) {
const currentSettings = await this . loadData ( ) ;
this . settings = merge . withOptions (
{ mergeArrays : false } ,
DEFAULT _SETTINGS ,
currentSettings != null ? currentSettings : { }
) ;
}
async saveSettings ( needUpdateTokens = { } ) {
await this . saveData ( this . settings ) ;
await this . suggester . updateSettings ( this . settings ) ;
if ( needUpdateTokens . currentFile ) {
await this . suggester . refreshCurrentFileTokens ( ) ;
}
if ( needUpdateTokens . currentVault ) {
await this . suggester . refreshCurrentVaultTokens ( ) ;
}
if ( needUpdateTokens . customDictionary ) {
await this . suggester . refreshCustomDictionaryTokens ( ) ;
}
if ( needUpdateTokens . internalLink ) {
this . suggester . refreshInternalLinkTokens ( ) ;
}
if ( needUpdateTokens . frontMatter ) {
this . suggester . refreshFrontMatterTokens ( ) ;
}
if ( needUpdateTokens . intelligentSuggestionPrioritization ) {
await this . suggester . refreshIntelligentSuggestionPrioritization ( ) ;
}
}
addWordToCustomDictionary ( ) {
const selectedWord = this . appHelper . getSelection ( ) ;
const provider = this . suggester . customDictionaryWordProvider ;
const modal = new CustomDictionaryWordAddModal (
this . app ,
provider . editablePaths ,
selectedWord ,
this . settings . delimiterToDivideSuggestionsForDisplayFromInsertion ,
async ( dictionaryPath , _word ) => {
const word = {
... _word ,
caretSymbol : this . settings . caretLocationSymbolAfterComplement
} ;
if ( provider . wordByValue [ word . value ] ) {
new import _obsidian9 . Notice ( ` \u 26A0 ${ word . value } already exists ` , 0 ) ;
return ;
}
await provider . addWordWithDictionary ( word , dictionaryPath , {
emoji : this . settings . matchingWithoutEmoji ,
accentsDiacritics : this . settings . treatAccentDiacriticsAsAlphabeticCharacters
} ) ;
new import _obsidian9 . Notice ( ` Added ${ word . value } ` ) ;
modal . close ( ) ;
}
) ;
modal . open ( ) ;
}
} ;
2026-05-06 17:32:44 +08:00
/* nosourcemap */