5656 lines
737 KiB
JavaScript
5656 lines
737 KiB
JavaScript
|
'use strict';
|
|||
|
|
|||
|
var obsidian = require('obsidian');
|
|||
|
|
|||
|
/******************************************************************************
|
|||
|
Copyright (c) Microsoft Corporation.
|
|||
|
|
|||
|
Permission to use, copy, modify, and/or distribute this software for any
|
|||
|
purpose with or without fee is hereby granted.
|
|||
|
|
|||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|||
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|||
|
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|||
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|||
|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|||
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|||
|
PERFORMANCE OF THIS SOFTWARE.
|
|||
|
***************************************************************************** */
|
|||
|
|
|||
|
function __rest(s, e) {
|
|||
|
var t = {};
|
|||
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|||
|
t[p] = s[p];
|
|||
|
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|||
|
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|||
|
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|||
|
t[p[i]] = s[p[i]];
|
|||
|
}
|
|||
|
return t;
|
|||
|
}
|
|||
|
|
|||
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|||
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|||
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|||
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|||
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|||
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
const regEmoji = new RegExp(/[\u2700-\u27BF]|[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2011-\u26FF]|\uD83E[\uDD10-\uDDFF]|[\uFE0E-\uFE0F]/, "g");
|
|||
|
function allAlphabets(text) {
|
|||
|
return Boolean(text.match(/^[a-zA-Z0-9_-]+$/));
|
|||
|
}
|
|||
|
function excludeEmoji(text) {
|
|||
|
return text.replace(regEmoji, "");
|
|||
|
}
|
|||
|
function lowerIncludes(one, other) {
|
|||
|
return one.toLowerCase().includes(other.toLowerCase());
|
|||
|
}
|
|||
|
function lowerStartsWith(a, b) {
|
|||
|
return a.toLowerCase().startsWith(b.toLowerCase());
|
|||
|
}
|
|||
|
function capitalizeFirstLetter(str) {
|
|||
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|||
|
}
|
|||
|
function* splitRaw(text, regexp) {
|
|||
|
let previousIndex = 0;
|
|||
|
for (let r of text.matchAll(regexp)) {
|
|||
|
if (previousIndex !== r.index) {
|
|||
|
yield text.slice(previousIndex, r.index);
|
|||
|
}
|
|||
|
yield text[r.index];
|
|||
|
previousIndex = r.index + 1;
|
|||
|
}
|
|||
|
if (previousIndex !== text.length) {
|
|||
|
yield text.slice(previousIndex, text.length);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function pickTokens(content, trimPattern) {
|
|||
|
return content.split(trimPattern).filter((x) => x !== "");
|
|||
|
}
|
|||
|
const TRIM_CHAR_PATTERN = /[\n\t\[\]$/:?!=()<>"'.,|;*~ `]/g;
|
|||
|
class DefaultTokenizer {
|
|||
|
tokenize(content, raw) {
|
|||
|
return raw
|
|||
|
? Array.from(splitRaw(content, this.getTrimPattern())).filter((x) => x !== " ")
|
|||
|
: pickTokens(content, this.getTrimPattern());
|
|||
|
}
|
|||
|
recursiveTokenize(content) {
|
|||
|
const trimIndexes = Array.from(content.matchAll(this.getTrimPattern()))
|
|||
|
.sort((a, b) => a.index - b.index)
|
|||
|
.map((x) => x.index);
|
|||
|
return [
|
|||
|
{ word: content, offset: 0 },
|
|||
|
...trimIndexes.map((i) => ({
|
|||
|
word: content.slice(i + 1),
|
|||
|
offset: i + 1,
|
|||
|
})),
|
|||
|
];
|
|||
|
}
|
|||
|
getTrimPattern() {
|
|||
|
return TRIM_CHAR_PATTERN;
|
|||
|
}
|
|||
|
shouldIgnore(str) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
const ARABIC_TRIM_CHAR_PATTERN = /[\n\t\[\]$/:?!=()<>"'.,|;*~ `،؛]/g;
|
|||
|
class ArabicTokenizer extends DefaultTokenizer {
|
|||
|
getTrimPattern() {
|
|||
|
return ARABIC_TRIM_CHAR_PATTERN;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// @ts-nocheck
|
|||
|
// Because this code is originally javascript code.
|
|||
|
// noinspection FunctionTooLongJS,FunctionWithMultipleLoopsJS,EqualityComparisonWithCoercionJS,PointlessBooleanExpressionJS,JSDeclarationsAtScopeStart
|
|||
|
// TinySegmenter 0.1 -- Super compact Japanese tokenizer in Javascript
|
|||
|
// (c) 2008 Taku Kudo <taku@chasen.org>
|
|||
|
// TinySegmenter is freely distributable under the terms of a new BSD licence.
|
|||
|
// For details, see http://chasen.org/~taku/software/TinySegmenter/LICENCE.txt
|
|||
|
function TinySegmenter() {
|
|||
|
var patterns = {
|
|||
|
"[一二三四五六七八九十百千万億兆]": "M",
|
|||
|
"[一-龠々〆ヵヶ]": "H",
|
|||
|
"[ぁ-ん]": "I",
|
|||
|
"[ァ-ヴーア-ン゙ー]": "K",
|
|||
|
"[a-zA-Za-zA-Z]": "A",
|
|||
|
"[0-90-9]": "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__ = {
|
|||
|
",と": 660,
|
|||
|
",同": 727,
|
|||
|
B1あ: 1404,
|
|||
|
B1同: 542,
|
|||
|
"、と": 660,
|
|||
|
"、同": 727,
|
|||
|
"」と": 1682,
|
|||
|
あっ: 1505,
|
|||
|
いう: 1743,
|
|||
|
いっ: -2055,
|
|||
|
いる: 672,
|
|||
|
うし: -4817,
|
|||
|
うん: 665,
|
|||
|
から: 3472,
|
|||
|
がら: 600,
|
|||
|
こう: -790,
|
|||
|
こと: 2083,
|
|||
|
こん: -1262,
|
|||
|
さら: -4143,
|
|||
|
さん: 4573,
|
|||
|
した: 2641,
|
|||
|
して: 1104,
|
|||
|
すで: -3399,
|
|||
|
そこ: 1977,
|
|||
|
それ: -871,
|
|||
|
たち: 1122,
|
|||
|
ため: 601,
|
|||
|
った: 3463,
|
|||
|
つい: -802,
|
|||
|
てい: 805,
|
|||
|
てき: 1249,
|
|||
|
でき: 1127,
|
|||
|
です: 3445,
|
|||
|
では: 844,
|
|||
|
とい: -4915,
|
|||
|
とみ: 1922,
|
|||
|
どこ: 3887,
|
|||
|
ない: 5713,
|
|||
|
なっ: 3015,
|
|||
|
など: 7379,
|
|||
|
なん: -1113,
|
|||
|
にし: 2468,
|
|||
|
には: 1498,
|
|||
|
にも: 1671,
|
|||
|
に対: -912,
|
|||
|
の一: -501,
|
|||
|
の中: 741,
|
|||
|
ませ: 2448,
|
|||
|
まで: 1711,
|
|||
|
まま: 2600,
|
|||
|
まる: -2155,
|
|||
|
やむ: -1947,
|
|||
|
よっ: -2565,
|
|||
|
れた: 2369,
|
|||
|
れで: -913,
|
|||
|
をし: 1860,
|
|||
|
を見: 731,
|
|||
|
亡く: -1886,
|
|||
|
京都: 2558,
|
|||
|
取り: -2784,
|
|||
|
大き: -2604,
|
|||
|
大阪: 1497,
|
|||
|
平方: -2314,
|
|||
|
引き: -1336,
|
|||
|
日本: -195,
|
|||
|
本当: -2423,
|
|||
|
毎日: -2113,
|
|||
|
目指: -724,
|
|||
|
B1あ: 1404,
|
|||
|
B1同: 542,
|
|||
|
"」と": 1682,
|
|||
|
};
|
|||
|
this.BW2__ = {
|
|||
|
"..": -11822,
|
|||
|
11: -669,
|
|||
|
"――": -5730,
|
|||
|
"−−": -13175,
|
|||
|
いう: -1609,
|
|||
|
うか: 2490,
|
|||
|
かし: -1350,
|
|||
|
かも: -602,
|
|||
|
から: -7194,
|
|||
|
かれ: 4612,
|
|||
|
がい: 853,
|
|||
|
がら: -3198,
|
|||
|
きた: 1941,
|
|||
|
くな: -1597,
|
|||
|
こと: -8392,
|
|||
|
この: -4193,
|
|||
|
させ: 4533,
|
|||
|
され: 13168,
|
|||
|
さん: -3977,
|
|||
|
しい: -1819,
|
|||
|
しか: -545,
|
|||
|
した: 5078,
|
|||
|
して: 972,
|
|||
|
しな: 939,
|
|||
|
その: -3744,
|
|||
|
たい: -1253,
|
|||
|
たた: -662,
|
|||
|
ただ: -3857,
|
|||
|
たち: -786,
|
|||
|
たと: 1224,
|
|||
|
たは: -939,
|
|||
|
った: 4589,
|
|||
|
って: 1647,
|
|||
|
っと: -2094,
|
|||
|
てい: 6144,
|
|||
|
てき: 3640,
|
|||
|
てく: 2551,
|
|||
|
ては: -3110,
|
|||
|
ても: -3065,
|
|||
|
でい: 2666,
|
|||
|
でき: -1528,
|
|||
|
でし: -3828,
|
|||
|
です: -4761,
|
|||
|
でも: -4203,
|
|||
|
とい: 1890,
|
|||
|
とこ: -1746,
|
|||
|
とと: -2279,
|
|||
|
との: 720,
|
|||
|
とみ: 5168,
|
|||
|
とも: -3941,
|
|||
|
ない: -2488,
|
|||
|
なが: -1313,
|
|||
|
など: -6509,
|
|||
|
なの: 2614,
|
|||
|
なん: 3099,
|
|||
|
にお: -1615,
|
|||
|
にし: 2748,
|
|||
|
にな: 2454,
|
|||
|
によ: -7236,
|
|||
|
に対: -14943,
|
|||
|
に従: -4688,
|
|||
|
に関: -11388,
|
|||
|
のか: 2093,
|
|||
|
ので: -7059,
|
|||
|
のに: -6041,
|
|||
|
のの: -6125,
|
|||
|
はい: 1073,
|
|||
|
はが: -1033,
|
|||
|
はず: -2532,
|
|||
|
ばれ: 1813,
|
|||
|
まし: -1316,
|
|||
|
まで: -6621,
|
|||
|
まれ: 5409,
|
|||
|
めて: -3153,
|
|||
|
もい: 2230,
|
|||
|
もの: -10713,
|
|||
|
らか: -944,
|
|||
|
らし: -1611,
|
|||
|
らに: -1897,
|
|||
|
りし: 651,
|
|||
|
りま: 1620,
|
|||
|
れた: 4270,
|
|||
|
れて: 849,
|
|||
|
れば: 4114,
|
|||
|
ろう: 6067,
|
|||
|
われ: 7901,
|
|||
|
を通: -11877,
|
|||
|
んだ: 728,
|
|||
|
んな: -4115,
|
|||
|
一人: 602,
|
|||
|
一方: -1375,
|
|||
|
一日: 970,
|
|||
|
一部: -1051,
|
|||
|
上が: -4479,
|
|||
|
会社: -1116,
|
|||
|
出て: 2163,
|
|||
|
分の: -7758,
|
|||
|
同党: 970,
|
|||
|
同日: -913,
|
|||
|
大阪: -2471,
|
|||
|
委員: -1250,
|
|||
|
少な: -1050,
|
|||
|
年度: -8669,
|
|||
|
年間: -1626,
|
|||
|
府県: -2363,
|
|||
|
手権: -1982,
|
|||
|
新聞: -4066,
|
|||
|
日新: -722,
|
|||
|
日本: -7068,
|
|||
|
日米: 3372,
|
|||
|
曜日: -601,
|
|||
|
朝鮮: -2355,
|
|||
|
本人: -2697,
|
|||
|
東京: -1543,
|
|||
|
然と: -1384,
|
|||
|
社会: -1276,
|
|||
|
立て: -990,
|
|||
|
第に: -1612,
|
|||
|
米国: -4268,
|
|||
|
"11": -669,
|
|||
|
};
|
|||
|
this.BW3__ = {
|
|||
|
あた: -2194,
|
|||
|
あり: 719,
|
|||
|
ある: 3846,
|
|||
|
"い.": -1185,
|
|||
|
"い。": -1185,
|
|||
|
いい: 5308,
|
|||
|
いえ: 2079,
|
|||
|
いく: 3029,
|
|||
|
いた: 2056,
|
|||
|
いっ: 1883,
|
|||
|
いる: 5600,
|
|||
|
いわ: 1527,
|
|||
|
うち: 1117,
|
|||
|
うと: 4798,
|
|||
|
えと: 1454,
|
|||
|
"か.": 2857,
|
|||
|
"か。": 2857,
|
|||
|
かけ: -743,
|
|||
|
かっ: -4098,
|
|||
|
かに: -669,
|
|||
|
から: 6520,
|
|||
|
かり: -2670,
|
|||
|
"が,": 1816,
|
|||
|
"が、": 1816,
|
|||
|
がき: -4855,
|
|||
|
がけ: -1127,
|
|||
|
がっ: -913,
|
|||
|
がら: -4977,
|
|||
|
がり: -2064,
|
|||
|
きた: 1645,
|
|||
|
けど: 1374,
|
|||
|
こと: 7397,
|
|||
|
この: 1542,
|
|||
|
ころ: -2757,
|
|||
|
さい: -714,
|
|||
|
さを: 976,
|
|||
|
"し,": 1557,
|
|||
|
"し、": 1557,
|
|||
|
しい: -3714,
|
|||
|
した: 3562,
|
|||
|
して: 1449,
|
|||
|
しな: 2608,
|
|||
|
しま: 1200,
|
|||
|
"す.": -1310,
|
|||
|
"す。": -1310,
|
|||
|
する: 6521,
|
|||
|
"ず,": 3426,
|
|||
|
"ず、": 3426,
|
|||
|
ずに: 841,
|
|||
|
そう: 428,
|
|||
|
"た.": 8875,
|
|||
|
"た。": 8875,
|
|||
|
たい: -594,
|
|||
|
たの: 812,
|
|||
|
たり: -1183,
|
|||
|
たる: -853,
|
|||
|
"だ.": 4098,
|
|||
|
"だ。": 4098,
|
|||
|
だっ: 1004,
|
|||
|
った: -4748,
|
|||
|
って: 300,
|
|||
|
てい: 6240,
|
|||
|
てお: 855,
|
|||
|
ても: 302,
|
|||
|
です: 1437,
|
|||
|
でに: -1482,
|
|||
|
では: 2295,
|
|||
|
とう: -1387,
|
|||
|
とし: 2266,
|
|||
|
との: 541,
|
|||
|
とも: -3543,
|
|||
|
どう: 4664,
|
|||
|
ない: 1796,
|
|||
|
なく: -903,
|
|||
|
など: 2135,
|
|||
|
"に,": -1021,
|
|||
|
"に、": -1021,
|
|||
|
にし: 1771,
|
|||
|
にな: 1906,
|
|||
|
には: 2644,
|
|||
|
"の,": -724,
|
|||
|
"の、": -724,
|
|||
|
の子: -1000,
|
|||
|
"は,": 1337,
|
|||
|
"は、": 1337,
|
|||
|
べき: 2181,
|
|||
|
まし: 1113,
|
|||
|
ます: 6943,
|
|||
|
まっ: -1549,
|
|||
|
まで: 6154,
|
|||
|
まれ: -793,
|
|||
|
らし: 1479,
|
|||
|
られ: 6820,
|
|||
|
るる: 3818,
|
|||
|
"れ,": 854,
|
|||
|
"れ、": 854,
|
|||
|
れた: 1850,
|
|||
|
れて: 1375,
|
|||
|
れば: -3246,
|
|||
|
れる: 1091,
|
|||
|
われ: -605,
|
|||
|
んだ: 606,
|
|||
|
んで: 798,
|
|||
|
カ月: 990,
|
|||
|
会議: 860,
|
|||
|
入り: 1232,
|
|||
|
大会: 2217,
|
|||
|
始め: 1681,
|
|||
|
市: 965,
|
|||
|
新聞: -5055,
|
|||
|
"日,": 974,
|
|||
|
"日、": 974,
|
|||
|
社会: 2024,
|
|||
|
カ月: 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__ = { につい: -4681, 東京都: 2026 };
|
|||
|
this.TW2__ = {
|
|||
|
ある程: -2049,
|
|||
|
いった: -1256,
|
|||
|
ころが: -2434,
|
|||
|
しょう: 3873,
|
|||
|
その後: -4430,
|
|||
|
だって: -1049,
|
|||
|
ていた: 1833,
|
|||
|
として: -4657,
|
|||
|
ともに: -4517,
|
|||
|
もので: 1882,
|
|||
|
一気に: -792,
|
|||
|
初めて: -1512,
|
|||
|
同時に: -8097,
|
|||
|
大きな: -1255,
|
|||
|
対して: -2721,
|
|||
|
社会党: -3216,
|
|||
|
};
|
|||
|
this.TW3__ = {
|
|||
|
いただ: -1734,
|
|||
|
してい: 1314,
|
|||
|
として: -4314,
|
|||
|
につい: -5483,
|
|||
|
にとっ: -5989,
|
|||
|
に当た: -6247,
|
|||
|
"ので,": -727,
|
|||
|
"ので、": -727,
|
|||
|
のもの: -600,
|
|||
|
れから: -3752,
|
|||
|
十二月: -2287,
|
|||
|
};
|
|||
|
this.TW4__ = {
|
|||
|
"いう.": 8576,
|
|||
|
"いう。": 8576,
|
|||
|
からな: -2348,
|
|||
|
してい: 2958,
|
|||
|
"たが,": 1516,
|
|||
|
"たが、": 1516,
|
|||
|
ている: 1538,
|
|||
|
という: 1349,
|
|||
|
ました: 5543,
|
|||
|
ません: 1097,
|
|||
|
ようと: -4258,
|
|||
|
よると: 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,
|
|||
|
"、": 156,
|
|||
|
"「": -463,
|
|||
|
あ: -941,
|
|||
|
う: -127,
|
|||
|
が: -553,
|
|||
|
き: 121,
|
|||
|
こ: 505,
|
|||
|
で: -201,
|
|||
|
と: -547,
|
|||
|
ど: -123,
|
|||
|
に: -789,
|
|||
|
の: -185,
|
|||
|
は: -847,
|
|||
|
も: -466,
|
|||
|
や: -470,
|
|||
|
よ: 182,
|
|||
|
ら: -292,
|
|||
|
り: 208,
|
|||
|
れ: 169,
|
|||
|
を: -446,
|
|||
|
ん: -137,
|
|||
|
"・": -135,
|
|||
|
主: -402,
|
|||
|
京: -268,
|
|||
|
区: -912,
|
|||
|
午: 871,
|
|||
|
国: -460,
|
|||
|
大: 561,
|
|||
|
委: 729,
|
|||
|
市: -411,
|
|||
|
日: -141,
|
|||
|
理: 361,
|
|||
|
生: -408,
|
|||
|
県: -386,
|
|||
|
都: -718,
|
|||
|
"「": -463,
|
|||
|
"・": -135,
|
|||
|
};
|
|||
|
this.UW2__ = {
|
|||
|
",": -829,
|
|||
|
"、": -829,
|
|||
|
〇: 892,
|
|||
|
"「": -645,
|
|||
|
"」": 3145,
|
|||
|
あ: -538,
|
|||
|
い: 505,
|
|||
|
う: 134,
|
|||
|
お: -502,
|
|||
|
か: 1454,
|
|||
|
が: -856,
|
|||
|
く: -412,
|
|||
|
こ: 1141,
|
|||
|
さ: 878,
|
|||
|
ざ: 540,
|
|||
|
し: 1529,
|
|||
|
す: -675,
|
|||
|
せ: 300,
|
|||
|
そ: -1011,
|
|||
|
た: 188,
|
|||
|
だ: 1837,
|
|||
|
つ: -949,
|
|||
|
て: -291,
|
|||
|
で: -268,
|
|||
|
と: -981,
|
|||
|
ど: 1273,
|
|||
|
な: 1063,
|
|||
|
に: -1764,
|
|||
|
の: 130,
|
|||
|
は: -409,
|
|||
|
ひ: -1273,
|
|||
|
べ: 1261,
|
|||
|
ま: 600,
|
|||
|
も: -1263,
|
|||
|
や: -402,
|
|||
|
よ: 1639,
|
|||
|
り: -579,
|
|||
|
る: -694,
|
|||
|
れ: 571,
|
|||
|
を: -2516,
|
|||
|
ん: 2095,
|
|||
|
ア: -587,
|
|||
|
カ: 306,
|
|||
|
キ: 568,
|
|||
|
ッ: 831,
|
|||
|
三: -758,
|
|||
|
不: -2150,
|
|||
|
世: -302,
|
|||
|
中: -968,
|
|||
|
主: -861,
|
|||
|
事: 492,
|
|||
|
人: -123,
|
|||
|
会: 978,
|
|||
|
保: 362,
|
|||
|
入: 548,
|
|||
|
初: -3025,
|
|||
|
副: -1566,
|
|||
|
北: -3414,
|
|||
|
区: -422,
|
|||
|
大: -1769,
|
|||
|
天: -865,
|
|||
|
太: -483,
|
|||
|
子: -1519,
|
|||
|
学: 760,
|
|||
|
実: 1023,
|
|||
|
小: -2009,
|
|||
|
市: -813,
|
|||
|
年: -1060,
|
|||
|
強: 1067,
|
|||
|
手: -1519,
|
|||
|
揺: -1033,
|
|||
|
政: 1522,
|
|||
|
文: -1355,
|
|||
|
新: -1682,
|
|||
|
日: -1815,
|
|||
|
明: -1462,
|
|||
|
最: -630,
|
|||
|
朝: -1843,
|
|||
|
本: -1650,
|
|||
|
東: -931,
|
|||
|
果: -665,
|
|||
|
次: -2378,
|
|||
|
民: -180,
|
|||
|
気: -1740,
|
|||
|
理: 752,
|
|||
|
発: 529,
|
|||
|
目: -1584,
|
|||
|
相: -242,
|
|||
|
県: -1165,
|
|||
|
立: -763,
|
|||
|
第: 810,
|
|||
|
米: 509,
|
|||
|
自: -1353,
|
|||
|
行: 838,
|
|||
|
西: -744,
|
|||
|
見: -3874,
|
|||
|
調: 1010,
|
|||
|
議: 1198,
|
|||
|
込: 3041,
|
|||
|
開: 1758,
|
|||
|
間: -1257,
|
|||
|
"「": -645,
|
|||
|
"」": 3145,
|
|||
|
ッ: 831,
|
|||
|
ア: -587,
|
|||
|
カ: 306,
|
|||
|
キ: 568,
|
|||
|
};
|
|||
|
this.UW3__ = {
|
|||
|
",": 4889,
|
|||
|
1: -800,
|
|||
|
"−": -1723,
|
|||
|
"、": 4889,
|
|||
|
々: -2311,
|
|||
|
〇: 5827,
|
|||
|
"」": 2670,
|
|||
|
"〓": -3573,
|
|||
|
あ: -2696,
|
|||
|
い: 1006,
|
|||
|
う: 2342,
|
|||
|
え: 1983,
|
|||
|
お: -4864,
|
|||
|
か: -1163,
|
|||
|
が: 3271,
|
|||
|
く: 1004,
|
|||
|
け: 388,
|
|||
|
げ: 401,
|
|||
|
こ: -3552,
|
|||
|
ご: -3116,
|
|||
|
さ: -1058,
|
|||
|
し: -395,
|
|||
|
す: 584,
|
|||
|
せ: 3685,
|
|||
|
そ: -5228,
|
|||
|
た: 842,
|
|||
|
ち: -521,
|
|||
|
っ: -1444,
|
|||
|
つ: -1081,
|
|||
|
て: 6167,
|
|||
|
で: 2318,
|
|||
|
と: 1691,
|
|||
|
ど: -899,
|
|||
|
な: -2788,
|
|||
|
に: 2745,
|
|||
|
の: 4056,
|
|||
|
は: 4555,
|
|||
|
ひ: -2171,
|
|||
|
ふ: -1798,
|
|||
|
へ: 1199,
|
|||
|
ほ: -5516,
|
|||
|
ま: -4384,
|
|||
|
み: -120,
|
|||
|
め: 1205,
|
|||
|
も: 2323,
|
|||
|
や: -788,
|
|||
|
よ: -202,
|
|||
|
ら: 727,
|
|||
|
り: 649,
|
|||
|
る: 5905,
|
|||
|
れ: 2773,
|
|||
|
わ: -1207,
|
|||
|
を: 6620,
|
|||
|
ん: -518,
|
|||
|
ア: 551,
|
|||
|
グ: 1319,
|
|||
|
ス: 874,
|
|||
|
ッ: -1350,
|
|||
|
ト: 521,
|
|||
|
ム: 1109,
|
|||
|
ル: 1591,
|
|||
|
ロ: 2201,
|
|||
|
ン: 278,
|
|||
|
"・": -3794,
|
|||
|
一: -1619,
|
|||
|
下: -1759,
|
|||
|
世: -2087,
|
|||
|
両: 3815,
|
|||
|
中: 653,
|
|||
|
主: -758,
|
|||
|
予: -1193,
|
|||
|
二: 974,
|
|||
|
人: 2742,
|
|||
|
今: 792,
|
|||
|
他: 1889,
|
|||
|
以: -1368,
|
|||
|
低: 811,
|
|||
|
何: 4265,
|
|||
|
作: -361,
|
|||
|
保: -2439,
|
|||
|
元: 4858,
|
|||
|
党: 3593,
|
|||
|
全: 1574,
|
|||
|
公: -3030,
|
|||
|
六: 755,
|
|||
|
共: -1880,
|
|||
|
円: 5807,
|
|||
|
再: 3095,
|
|||
|
分: 457,
|
|||
|
初: 2475,
|
|||
|
別: 1129,
|
|||
|
前: 2286,
|
|||
|
副: 4437,
|
|||
|
力: 365,
|
|||
|
動: -949,
|
|||
|
務: -1872,
|
|||
|
化: 1327,
|
|||
|
北: -1038,
|
|||
|
区: 4646,
|
|||
|
千: -2309,
|
|||
|
午: -783,
|
|||
|
協: -1006,
|
|||
|
口: 483,
|
|||
|
右: 1233,
|
|||
|
各: 3588,
|
|||
|
合: -241,
|
|||
|
同: 3906,
|
|||
|
和: -837,
|
|||
|
員: 4513,
|
|||
|
国: 642,
|
|||
|
型: 1389,
|
|||
|
場: 1219,
|
|||
|
外: -241,
|
|||
|
妻: 2016,
|
|||
|
学: -1356,
|
|||
|
安: -423,
|
|||
|
実: -1008,
|
|||
|
家: 1078,
|
|||
|
小: -513,
|
|||
|
少: -3102,
|
|||
|
州: 1155,
|
|||
|
市: 3197,
|
|||
|
平: -1804,
|
|||
|
年: 2416,
|
|||
|
広: -1030,
|
|||
|
府: 1605,
|
|||
|
度: 1452,
|
|||
|
建: -2352,
|
|||
|
当: -3885,
|
|||
|
得: 1905,
|
|||
|
思: -1291,
|
|||
|
性: 1822,
|
|||
|
戸: -488,
|
|||
|
指: -3973,
|
|||
|
政: -2013,
|
|||
|
教: -1479,
|
|||
|
数: 3222,
|
|||
|
文: -1489,
|
|||
|
新: 1764,
|
|||
|
日: 2099,
|
|||
|
旧: 5792,
|
|||
|
昨: -661,
|
|||
|
時: -1248,
|
|||
|
曜: -951,
|
|||
|
最: -937,
|
|||
|
月: 4125,
|
|||
|
期: 360,
|
|||
|
李: 3094,
|
|||
|
村: 364,
|
|||
|
東: -805,
|
|||
|
核: 5156,
|
|||
|
森: 2438,
|
|||
|
業: 484,
|
|||
|
氏: 2613,
|
|||
|
民: -1694,
|
|||
|
決: -1073,
|
|||
|
法: 1868,
|
|||
|
海: -495,
|
|||
|
無: 979,
|
|||
|
物: 461,
|
|||
|
特: -3850,
|
|||
|
生: -273,
|
|||
|
用: 914,
|
|||
|
町: 1215,
|
|||
|
的: 7313,
|
|||
|
直: -1835,
|
|||
|
省: 792,
|
|||
|
県: 6293,
|
|||
|
知: -1528,
|
|||
|
私: 4231,
|
|||
|
税: 401,
|
|||
|
立: -960,
|
|||
|
第: 1201,
|
|||
|
米: 7767,
|
|||
|
系: 3066,
|
|||
|
約: 3663,
|
|||
|
級: 1384,
|
|||
|
統: -4229,
|
|||
|
総: 1163,
|
|||
|
線: 1255,
|
|||
|
者: 6457,
|
|||
|
能: 725,
|
|||
|
自: -2869,
|
|||
|
英: 785,
|
|||
|
見: 1044,
|
|||
|
調: -562,
|
|||
|
財: -733,
|
|||
|
費: 1777,
|
|||
|
車: 1835,
|
|||
|
軍: 1375,
|
|||
|
込: -1504,
|
|||
|
通: -1136,
|
|||
|
選: -681,
|
|||
|
郎: 1026,
|
|||
|
郡: 4404,
|
|||
|
部: 1200,
|
|||
|
金: 2163,
|
|||
|
長: 421,
|
|||
|
開: -1432,
|
|||
|
間: 1302,
|
|||
|
関: -1282,
|
|||
|
雨: 2009,
|
|||
|
電: -1045,
|
|||
|
非: 2066,
|
|||
|
駅: 1620,
|
|||
|
"1": -800,
|
|||
|
"」": 2670,
|
|||
|
"・": -3794,
|
|||
|
ッ: -1350,
|
|||
|
ア: 551,
|
|||
|
グ: 1319,
|
|||
|
ス: 874,
|
|||
|
ト: 521,
|
|||
|
ム: 1109,
|
|||
|
ル: 1591,
|
|||
|
ロ: 2201,
|
|||
|
ン: 278,
|
|||
|
};
|
|||
|
this.UW4__ = {
|
|||
|
",": 3930,
|
|||
|
".": 3508,
|
|||
|
"―": -4841,
|
|||
|
"、": 3930,
|
|||
|
"。": 3508,
|
|||
|
〇: 4999,
|
|||
|
"「": 1895,
|
|||
|
"」": 3798,
|
|||
|
"〓": -5156,
|
|||
|
あ: 4752,
|
|||
|
い: -3435,
|
|||
|
う: -640,
|
|||
|
え: -2514,
|
|||
|
お: 2405,
|
|||
|
か: 530,
|
|||
|
が: 6006,
|
|||
|
き: -4482,
|
|||
|
ぎ: -3821,
|
|||
|
く: -3788,
|
|||
|
け: -4376,
|
|||
|
げ: -4734,
|
|||
|
こ: 2255,
|
|||
|
ご: 1979,
|
|||
|
さ: 2864,
|
|||
|
し: -843,
|
|||
|
じ: -2506,
|
|||
|
す: -731,
|
|||
|
ず: 1251,
|
|||
|
せ: 181,
|
|||
|
そ: 4091,
|
|||
|
た: 5034,
|
|||
|
だ: 5408,
|
|||
|
ち: -3654,
|
|||
|
っ: -5882,
|
|||
|
つ: -1659,
|
|||
|
て: 3994,
|
|||
|
で: 7410,
|
|||
|
と: 4547,
|
|||
|
な: 5433,
|
|||
|
に: 6499,
|
|||
|
ぬ: 1853,
|
|||
|
ね: 1413,
|
|||
|
の: 7396,
|
|||
|
は: 8578,
|
|||
|
ば: 1940,
|
|||
|
ひ: 4249,
|
|||
|
び: -4134,
|
|||
|
ふ: 1345,
|
|||
|
へ: 6665,
|
|||
|
べ: -744,
|
|||
|
ほ: 1464,
|
|||
|
ま: 1051,
|
|||
|
み: -2082,
|
|||
|
む: -882,
|
|||
|
め: -5046,
|
|||
|
も: 4169,
|
|||
|
ゃ: -2666,
|
|||
|
や: 2795,
|
|||
|
ょ: -1544,
|
|||
|
よ: 3351,
|
|||
|
ら: -2922,
|
|||
|
り: -9726,
|
|||
|
る: -14896,
|
|||
|
れ: -2613,
|
|||
|
ろ: -4570,
|
|||
|
わ: -1783,
|
|||
|
を: 13150,
|
|||
|
ん: -2352,
|
|||
|
カ: 2145,
|
|||
|
コ: 1789,
|
|||
|
セ: 1287,
|
|||
|
ッ: -724,
|
|||
|
ト: -403,
|
|||
|
メ: -1635,
|
|||
|
ラ: -881,
|
|||
|
リ: -541,
|
|||
|
ル: -856,
|
|||
|
ン: -3637,
|
|||
|
"・": -4371,
|
|||
|
ー: -11870,
|
|||
|
一: -2069,
|
|||
|
中: 2210,
|
|||
|
予: 782,
|
|||
|
事: -190,
|
|||
|
井: -1768,
|
|||
|
人: 1036,
|
|||
|
以: 544,
|
|||
|
会: 950,
|
|||
|
体: -1286,
|
|||
|
作: 530,
|
|||
|
側: 4292,
|
|||
|
先: 601,
|
|||
|
党: -2006,
|
|||
|
共: -1212,
|
|||
|
内: 584,
|
|||
|
円: 788,
|
|||
|
初: 1347,
|
|||
|
前: 1623,
|
|||
|
副: 3879,
|
|||
|
力: -302,
|
|||
|
動: -740,
|
|||
|
務: -2715,
|
|||
|
化: 776,
|
|||
|
区: 4517,
|
|||
|
協: 1013,
|
|||
|
参: 1555,
|
|||
|
合: -1834,
|
|||
|
和: -681,
|
|||
|
員: -910,
|
|||
|
器: -851,
|
|||
|
回: 1500,
|
|||
|
国: -619,
|
|||
|
園: -1200,
|
|||
|
地: 866,
|
|||
|
場: -1410,
|
|||
|
塁: -2094,
|
|||
|
士: -1413,
|
|||
|
多: 1067,
|
|||
|
大: 571,
|
|||
|
子: -4802,
|
|||
|
学: -1397,
|
|||
|
定: -1057,
|
|||
|
寺: -809,
|
|||
|
小: 1910,
|
|||
|
屋: -1328,
|
|||
|
山: -1500,
|
|||
|
島: -2056,
|
|||
|
川: -2667,
|
|||
|
市: 2771,
|
|||
|
年: 374,
|
|||
|
庁: -4556,
|
|||
|
後: 456,
|
|||
|
性: 553,
|
|||
|
感: 916,
|
|||
|
所: -1566,
|
|||
|
支: 856,
|
|||
|
改: 787,
|
|||
|
政: 2182,
|
|||
|
教: 704,
|
|||
|
文: 522,
|
|||
|
方: -856,
|
|||
|
日: 1798,
|
|||
|
時: 1829,
|
|||
|
最: 845,
|
|||
|
月: -9066,
|
|||
|
木: -485,
|
|||
|
来: -442,
|
|||
|
校: -360,
|
|||
|
業: -1043,
|
|||
|
氏: 5388,
|
|||
|
民: -2716,
|
|||
|
気: -910,
|
|||
|
沢: -939,
|
|||
|
済: -543,
|
|||
|
物: -735,
|
|||
|
率: 672,
|
|||
|
球: -1267,
|
|||
|
生: -1286,
|
|||
|
産: -1101,
|
|||
|
田: -2900,
|
|||
|
町: 1826,
|
|||
|
的: 2586,
|
|||
|
目: 922,
|
|||
|
省: -3485,
|
|||
|
県: 2997,
|
|||
|
空: -867,
|
|||
|
立: -2112,
|
|||
|
第: 788,
|
|||
|
米: 2937,
|
|||
|
系: 786,
|
|||
|
約: 2171,
|
|||
|
経: 1146,
|
|||
|
統: -1169,
|
|||
|
総: 940,
|
|||
|
線: -994,
|
|||
|
署: 749,
|
|||
|
者: 2145,
|
|||
|
能: -730,
|
|||
|
般: -852,
|
|||
|
行: -792,
|
|||
|
規: 792,
|
|||
|
警: -1184,
|
|||
|
議: -244,
|
|||
|
谷: -1000,
|
|||
|
賞: 730,
|
|||
|
車: -1481,
|
|||
|
軍: 1158,
|
|||
|
輪: -1433,
|
|||
|
込: -3370,
|
|||
|
近: 929,
|
|||
|
道: -1291,
|
|||
|
選: 2596,
|
|||
|
郎: -4866,
|
|||
|
都: 1192,
|
|||
|
野: -1100,
|
|||
|
銀: -2213,
|
|||
|
長: 357,
|
|||
|
間: -2344,
|
|||
|
院: -2297,
|
|||
|
際: -2604,
|
|||
|
電: -878,
|
|||
|
領: -1659,
|
|||
|
題: -792,
|
|||
|
館: -1984,
|
|||
|
首: 1749,
|
|||
|
高: 2120,
|
|||
|
"「": 1895,
|
|||
|
"」": 3798,
|
|||
|
"・": -4371,
|
|||
|
ッ: -724,
|
|||
|
ー: -11870,
|
|||
|
カ: 2145,
|
|||
|
コ: 1789,
|
|||
|
セ: 1287,
|
|||
|
ト: -403,
|
|||
|
メ: -1635,
|
|||
|
ラ: -881,
|
|||
|
リ: -541,
|
|||
|
ル: -856,
|
|||
|
ン: -3637,
|
|||
|
};
|
|||
|
this.UW5__ = {
|
|||
|
",": 465,
|
|||
|
".": -299,
|
|||
|
1: -514,
|
|||
|
E2: -32768,
|
|||
|
"]": -2762,
|
|||
|
"、": 465,
|
|||
|
"。": -299,
|
|||
|
"「": 363,
|
|||
|
あ: 1655,
|
|||
|
い: 331,
|
|||
|
う: -503,
|
|||
|
え: 1199,
|
|||
|
お: 527,
|
|||
|
か: 647,
|
|||
|
が: -421,
|
|||
|
き: 1624,
|
|||
|
ぎ: 1971,
|
|||
|
く: 312,
|
|||
|
げ: -983,
|
|||
|
さ: -1537,
|
|||
|
し: -1371,
|
|||
|
す: -852,
|
|||
|
だ: -1186,
|
|||
|
ち: 1093,
|
|||
|
っ: 52,
|
|||
|
つ: 921,
|
|||
|
て: -18,
|
|||
|
で: -850,
|
|||
|
と: -127,
|
|||
|
ど: 1682,
|
|||
|
な: -787,
|
|||
|
に: -1224,
|
|||
|
の: -635,
|
|||
|
は: -578,
|
|||
|
べ: 1001,
|
|||
|
み: 502,
|
|||
|
め: 865,
|
|||
|
ゃ: 3350,
|
|||
|
ょ: 854,
|
|||
|
り: -208,
|
|||
|
る: 429,
|
|||
|
れ: 504,
|
|||
|
わ: 419,
|
|||
|
を: -1264,
|
|||
|
ん: 327,
|
|||
|
イ: 241,
|
|||
|
ル: 451,
|
|||
|
ン: -343,
|
|||
|
中: -871,
|
|||
|
京: 722,
|
|||
|
会: -1153,
|
|||
|
党: -654,
|
|||
|
務: 3519,
|
|||
|
区: -901,
|
|||
|
告: 848,
|
|||
|
員: 2104,
|
|||
|
大: -1296,
|
|||
|
学: -548,
|
|||
|
定: 1785,
|
|||
|
嵐: -1304,
|
|||
|
市: -2991,
|
|||
|
席: 921,
|
|||
|
年: 1763,
|
|||
|
思: 872,
|
|||
|
所: -814,
|
|||
|
挙: 1618,
|
|||
|
新: -1682,
|
|||
|
日: 218,
|
|||
|
月: -4353,
|
|||
|
査: 932,
|
|||
|
格: 1356,
|
|||
|
機: -1508,
|
|||
|
氏: -1347,
|
|||
|
田: 240,
|
|||
|
町: -3912,
|
|||
|
的: -3149,
|
|||
|
相: 1319,
|
|||
|
省: -1052,
|
|||
|
県: -4003,
|
|||
|
研: -997,
|
|||
|
社: -278,
|
|||
|
空: -813,
|
|||
|
統: 1955,
|
|||
|
者: -2233,
|
|||
|
表: 663,
|
|||
|
語: -1073,
|
|||
|
議: 1219,
|
|||
|
選: -1018,
|
|||
|
郎: -368,
|
|||
|
長: 786,
|
|||
|
間: 1191,
|
|||
|
題: 2368,
|
|||
|
館: -689,
|
|||
|
"1": -514,
|
|||
|
E2: -32768,
|
|||
|
"「": 363,
|
|||
|
イ: 241,
|
|||
|
ル: 451,
|
|||
|
ン: -343,
|
|||
|
};
|
|||
|
this.UW6__ = {
|
|||
|
",": 227,
|
|||
|
".": 808,
|
|||
|
1: -270,
|
|||
|
E1: 306,
|
|||
|
"、": 227,
|
|||
|
"。": 808,
|
|||
|
あ: -307,
|
|||
|
う: 189,
|
|||
|
か: 241,
|
|||
|
が: -73,
|
|||
|
く: -121,
|
|||
|
こ: -200,
|
|||
|
じ: 1782,
|
|||
|
す: 383,
|
|||
|
た: -428,
|
|||
|
っ: 573,
|
|||
|
て: -1014,
|
|||
|
で: 101,
|
|||
|
と: -105,
|
|||
|
な: -253,
|
|||
|
に: -149,
|
|||
|
の: -417,
|
|||
|
は: -236,
|
|||
|
も: -206,
|
|||
|
り: 187,
|
|||
|
る: -135,
|
|||
|
を: 195,
|
|||
|
ル: -673,
|
|||
|
ン: -496,
|
|||
|
一: -277,
|
|||
|
中: 201,
|
|||
|
件: -800,
|
|||
|
会: 624,
|
|||
|
前: 302,
|
|||
|
区: 1792,
|
|||
|
員: -1212,
|
|||
|
委: 798,
|
|||
|
学: -960,
|
|||
|
市: 887,
|
|||
|
広: -695,
|
|||
|
後: 535,
|
|||
|
業: -697,
|
|||
|
相: 753,
|
|||
|
社: -507,
|
|||
|
福: 974,
|
|||
|
空: -822,
|
|||
|
者: 1811,
|
|||
|
連: 463,
|
|||
|
郎: 1082,
|
|||
|
"1": -270,
|
|||
|
E1: 306,
|
|||
|
ル: -673,
|
|||
|
ン: -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];
|
|||
|
}
|
|||
|
}
|
|||
|
return "O";
|
|||
|
};
|
|||
|
TinySegmenter.prototype.ts_ = function (v) {
|
|||
|
if (v) {
|
|||
|
return v;
|
|||
|
}
|
|||
|
return 0;
|
|||
|
};
|
|||
|
TinySegmenter.prototype.segment = function (input) {
|
|||
|
if (input == null || input == undefined || input == "") {
|
|||
|
return [];
|
|||
|
}
|
|||
|
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]));
|
|||
|
}
|
|||
|
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.TC5__[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";
|
|||
|
}
|
|||
|
p1 = p2;
|
|||
|
p2 = p3;
|
|||
|
p3 = p;
|
|||
|
word += seg[i];
|
|||
|
}
|
|||
|
result.push(word);
|
|||
|
return result;
|
|||
|
};
|
|||
|
|
|||
|
// @ts-ignore
|
|||
|
const segmenter = new TinySegmenter();
|
|||
|
function pickTokensAsJapanese(content, trimPattern) {
|
|||
|
return content
|
|||
|
.split(trimPattern)
|
|||
|
.filter((x) => x !== "")
|
|||
|
.flatMap((x) => segmenter.segment(x));
|
|||
|
}
|
|||
|
/**
|
|||
|
* Japanese needs original logic.
|
|||
|
*/
|
|||
|
class JapaneseTokenizer {
|
|||
|
tokenize(content, raw) {
|
|||
|
return pickTokensAsJapanese(content, raw ? / /g : this.getTrimPattern());
|
|||
|
}
|
|||
|
recursiveTokenize(content) {
|
|||
|
const tokens = segmenter
|
|||
|
.segment(content)
|
|||
|
// https://github.com/tadashi-aikawa/obsidian-various-complements-plugin/issues/77
|
|||
|
.flatMap((x) => x === " " ? x : x.split(" ").map((t) => (t === "" ? " " : t)));
|
|||
|
const ret = [];
|
|||
|
for (let i = 0; i < tokens.length; i++) {
|
|||
|
if (i === 0 ||
|
|||
|
tokens[i].length !== 1 ||
|
|||
|
!Boolean(tokens[i].match(this.getTrimPattern()))) {
|
|||
|
ret.push({
|
|||
|
word: tokens.slice(i).join(""),
|
|||
|
offset: tokens.slice(0, i).join("").length,
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
return ret;
|
|||
|
}
|
|||
|
getTrimPattern() {
|
|||
|
return TRIM_CHAR_PATTERN;
|
|||
|
}
|
|||
|
shouldIgnore(str) {
|
|||
|
return Boolean(str.match(/^[ぁ-んa-zA-Z。、ー ]*$/));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
const ENGLISH_PATTERN = /[a-zA-Z0-9_\-\\]/;
|
|||
|
class EnglishOnlyTokenizer extends DefaultTokenizer {
|
|||
|
tokenize(content, raw) {
|
|||
|
const tokenized = Array.from(this._tokenize(content)).filter((x) => x.word.match(ENGLISH_PATTERN));
|
|||
|
return raw
|
|||
|
? tokenized.map((x) => x.word)
|
|||
|
: tokenized
|
|||
|
.map((x) => x.word)
|
|||
|
.filter((x) => !x.match(this.getTrimPattern()));
|
|||
|
}
|
|||
|
recursiveTokenize(content) {
|
|||
|
const offsets = Array.from(this._tokenize(content))
|
|||
|
.filter((x) => !x.word.match(this.getTrimPattern()))
|
|||
|
.map((x) => x.offset);
|
|||
|
return [
|
|||
|
...offsets.map((i) => ({
|
|||
|
word: content.slice(i),
|
|||
|
offset: i,
|
|||
|
})),
|
|||
|
];
|
|||
|
}
|
|||
|
*_tokenize(content) {
|
|||
|
let startIndex = 0;
|
|||
|
let previousType = "none";
|
|||
|
for (let i = 0; i < content.length; i++) {
|
|||
|
if (content[i].match(super.getTrimPattern())) {
|
|||
|
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,
|
|||
|
};
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function createTokenizer(strategy) {
|
|||
|
switch (strategy.name) {
|
|||
|
case "default":
|
|||
|
return new DefaultTokenizer();
|
|||
|
case "english-only":
|
|||
|
return new EnglishOnlyTokenizer();
|
|||
|
case "arabic":
|
|||
|
return new ArabicTokenizer();
|
|||
|
case "japanese":
|
|||
|
return new JapaneseTokenizer();
|
|||
|
default:
|
|||
|
throw new Error(`Unexpected strategy name: ${strategy}`);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
class TokenizeStrategy {
|
|||
|
constructor(name, triggerThreshold) {
|
|||
|
this.name = name;
|
|||
|
this.triggerThreshold = triggerThreshold;
|
|||
|
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);
|
|||
|
TokenizeStrategy.ENGLISH_ONLY = new TokenizeStrategy("english-only", 3);
|
|||
|
TokenizeStrategy.JAPANESE = new TokenizeStrategy("japanese", 2);
|
|||
|
TokenizeStrategy.ARABIC = new TokenizeStrategy("arabic", 3);
|
|||
|
|
|||
|
class AppHelper {
|
|||
|
constructor(app) {
|
|||
|
this.unsafeApp = app;
|
|||
|
}
|
|||
|
equalsAsEditorPostion(one, other) {
|
|||
|
return one.line === other.line && one.ch === other.ch;
|
|||
|
}
|
|||
|
getAliases(file) {
|
|||
|
var _a, _b;
|
|||
|
return ((_b = obsidian.parseFrontMatterAliases((_a = this.unsafeApp.metadataCache.getFileCache(file)) === null || _a === void 0 ? void 0 : _a.frontmatter)) !== null && _b !== void 0 ? _b : []);
|
|||
|
}
|
|||
|
getFrontMatter(file) {
|
|||
|
var _a, _b, _c, _d;
|
|||
|
const frontMatter = (_a = this.unsafeApp.metadataCache.getFileCache(file)) === null || _a === void 0 ? void 0 : _a.frontmatter;
|
|||
|
if (!frontMatter) {
|
|||
|
return undefined;
|
|||
|
}
|
|||
|
// remove #
|
|||
|
const tags = (_c = (_b = obsidian.parseFrontMatterTags(frontMatter)) === null || _b === void 0 ? void 0 : _b.map((x) => x.slice(1))) !== null && _c !== void 0 ? _c : [];
|
|||
|
const aliases = (_d = obsidian.parseFrontMatterAliases(frontMatter)) !== null && _d !== void 0 ? _d : [];
|
|||
|
const rest = __rest(frontMatter, ["position"]);
|
|||
|
return Object.assign(Object.assign({}, Object.fromEntries(Object.entries(rest).map(([k, _v]) => [
|
|||
|
k,
|
|||
|
obsidian.parseFrontMatterStringArray(frontMatter, k),
|
|||
|
]))), { tags, tag: tags, aliases, alias: aliases });
|
|||
|
}
|
|||
|
getMarkdownViewInActiveLeaf() {
|
|||
|
if (!this.unsafeApp.workspace.getActiveViewOfType(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 || _a === void 0 ? void 0 : _a.path) === file.path;
|
|||
|
}
|
|||
|
getPreviousFile() {
|
|||
|
var _a;
|
|||
|
const fName = (_a = this.unsafeApp.workspace.getLastOpenFiles()) === null || _a === void 0 ? void 0 : _a[1];
|
|||
|
if (!fName) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
return this.getMarkdownFileByPath(fName);
|
|||
|
}
|
|||
|
getCurrentDirname() {
|
|||
|
var _a, _b;
|
|||
|
return (_b = (_a = this.getActiveFile()) === null || _a === void 0 ? void 0 : _a.parent.path) !== null && _b !== void 0 ? _b : null;
|
|||
|
}
|
|||
|
getCurrentEditor() {
|
|||
|
var _a, _b;
|
|||
|
return (_b = (_a = this.getMarkdownViewInActiveLeaf()) === null || _a === void 0 ? void 0 : _a.editor) !== null && _b !== void 0 ? _b : null;
|
|||
|
}
|
|||
|
getSelection() {
|
|||
|
var _a;
|
|||
|
return (_a = this.getCurrentEditor()) === null || _a === void 0 ? void 0 : _a.getSelection();
|
|||
|
}
|
|||
|
getCurrentOffset(editor) {
|
|||
|
return editor.posToOffset(editor.getCursor());
|
|||
|
}
|
|||
|
getCurrentLine(editor) {
|
|||
|
return editor.getLine(editor.getCursor().line);
|
|||
|
}
|
|||
|
getCurrentLineUntilCursor(editor) {
|
|||
|
return this.getCurrentLine(editor).slice(0, editor.getCursor().ch);
|
|||
|
}
|
|||
|
searchPhantomLinks() {
|
|||
|
return Object.entries(this.unsafeApp.metadataCache.unresolvedLinks).flatMap(([path, obj]) => Object.keys(obj).map((link) => ({ path, link })));
|
|||
|
}
|
|||
|
getMarkdownFileByPath(path) {
|
|||
|
if (!path.endsWith(".md")) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
const abstractFile = this.unsafeApp.vault.getAbstractFileByPath(path);
|
|||
|
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 || _a === void 0 ? void 0 : _a.getViewState())
|
|||
|
.then(() => {
|
|||
|
this.unsafeApp.workspace.setActiveLeaf(leaf, true, true);
|
|||
|
const viewOfType = this.unsafeApp.workspace.getActiveViewOfType(obsidian.MarkdownView);
|
|||
|
if (viewOfType) {
|
|||
|
const editor = viewOfType.editor;
|
|||
|
const pos = editor.offsetToPos(offset);
|
|||
|
editor.setCursor(pos);
|
|||
|
editor.scrollIntoView({ from: pos, to: pos }, true);
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
getCurrentFrontMatter() {
|
|||
|
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(/.+:/g));
|
|||
|
if (keyLocations.length === 0) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
const currentKeyLocation = keyLocations
|
|||
|
.filter((x) => x.index < currentOffset)
|
|||
|
.last();
|
|||
|
if (!currentKeyLocation) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
return currentKeyLocation[0].split(":")[0];
|
|||
|
}
|
|||
|
/**
|
|||
|
* Unsafe method
|
|||
|
*/
|
|||
|
isIMEOn() {
|
|||
|
var _a, _b, _c;
|
|||
|
if (!this.unsafeApp.workspace.getActiveViewOfType(obsidian.MarkdownView)) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
const markdownView = this.unsafeApp.workspace.activeLeaf
|
|||
|
.view;
|
|||
|
const cm5or6 = markdownView.editor.cm;
|
|||
|
// cm6
|
|||
|
if (((_a = cm5or6 === null || cm5or6 === void 0 ? void 0 : cm5or6.inputState) === null || _a === void 0 ? void 0 : _a.composing) > 0) {
|
|||
|
return true;
|
|||
|
}
|
|||
|
// cm5
|
|||
|
return !!((_c = (_b = cm5or6 === null || cm5or6 === void 0 ? void 0 : cm5or6.display) === null || _b === void 0 ? void 0 : _b.input) === null || _c === void 0 ? void 0 : _c.composing);
|
|||
|
}
|
|||
|
writeLog(log) {
|
|||
|
return __awaiter(this, void 0, void 0, function* () {
|
|||
|
yield this.unsafeApp.vault.adapter.append(obsidian.normalizePath("log.md"), log);
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
const 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 = 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((element, index) => arr.findIndex((step) => fn(element, step)) === index);
|
|||
|
}
|
|||
|
function mirrorMap(collection, toValue) {
|
|||
|
return collection.reduce((p, c) => (Object.assign(Object.assign({}, p), { [toValue(c)]: toValue(c) })), {});
|
|||
|
}
|
|||
|
|
|||
|
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");
|
|||
|
|
|||
|
function pushWord(wordsByFirstLetter, key, word) {
|
|||
|
if (wordsByFirstLetter[key] === undefined) {
|
|||
|
wordsByFirstLetter[key] = [word];
|
|||
|
return;
|
|||
|
}
|
|||
|
wordsByFirstLetter[key].push(word);
|
|||
|
}
|
|||
|
// Public for tests
|
|||
|
function judge(word, query, queryStartWithUpper) {
|
|||
|
var _a;
|
|||
|
if (query === "") {
|
|||
|
return {
|
|||
|
word: Object.assign(Object.assign({}, word), { hit: word.value }),
|
|||
|
value: word.value,
|
|||
|
alias: false,
|
|||
|
};
|
|||
|
}
|
|||
|
if (lowerStartsWith(word.value, query)) {
|
|||
|
if (queryStartWithUpper &&
|
|||
|
word.type !== "internalLink" &&
|
|||
|
word.type !== "frontMatter") {
|
|||
|
const c = capitalizeFirstLetter(word.value);
|
|||
|
return {
|
|||
|
word: Object.assign(Object.assign({}, word), { value: c, hit: c }),
|
|||
|
value: c,
|
|||
|
alias: false,
|
|||
|
};
|
|||
|
}
|
|||
|
else {
|
|||
|
return {
|
|||
|
word: Object.assign(Object.assign({}, word), { hit: word.value }),
|
|||
|
value: word.value,
|
|||
|
alias: false,
|
|||
|
};
|
|||
|
}
|
|||
|
}
|
|||
|
const matchedAlias = (_a = word.aliases) === null || _a === void 0 ? void 0 : _a.find((a) => lowerStartsWith(a, query));
|
|||
|
if (matchedAlias) {
|
|||
|
return {
|
|||
|
word: Object.assign(Object.assign({}, word), { hit: matchedAlias }),
|
|||
|
value: matchedAlias,
|
|||
|
alias: true,
|
|||
|
};
|
|||
|
}
|
|||
|
return {
|
|||
|
word,
|
|||
|
alias: false,
|
|||
|
};
|
|||
|
}
|
|||
|
function suggestWords(indexedWords, query, max, frontMatter, selectionHistoryStorage) {
|
|||
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|||
|
const queryStartWithUpper = capitalizeFirstLetter(query) === query;
|
|||
|
const flattenFrontMatterWords = () => {
|
|||
|
var _a, _b;
|
|||
|
if (frontMatter === "alias" || frontMatter === "aliases") {
|
|||
|
return [];
|
|||
|
}
|
|||
|
if (frontMatter && ((_a = indexedWords.frontMatter) === null || _a === void 0 ? void 0 : _a[frontMatter])) {
|
|||
|
return Object.values((_b = indexedWords.frontMatter) === null || _b === void 0 ? void 0 : _b[frontMatter]).flat();
|
|||
|
}
|
|||
|
return [];
|
|||
|
};
|
|||
|
const words = queryStartWithUpper
|
|||
|
? frontMatter
|
|||
|
? flattenFrontMatterWords()
|
|||
|
: [
|
|||
|
...((_a = indexedWords.currentFile[query.charAt(0)]) !== null && _a !== void 0 ? _a : []),
|
|||
|
...((_b = indexedWords.currentFile[query.charAt(0).toLowerCase()]) !== null && _b !== void 0 ? _b : []),
|
|||
|
...((_c = indexedWords.currentVault[query.charAt(0)]) !== null && _c !== void 0 ? _c : []),
|
|||
|
...((_d = indexedWords.currentVault[query.charAt(0).toLowerCase()]) !== null && _d !== void 0 ? _d : []),
|
|||
|
...((_e = indexedWords.customDictionary[query.charAt(0)]) !== null && _e !== void 0 ? _e : []),
|
|||
|
...((_f = indexedWords.customDictionary[query.charAt(0).toLowerCase()]) !== null && _f !== void 0 ? _f : []),
|
|||
|
...((_g = indexedWords.internalLink[query.charAt(0)]) !== null && _g !== void 0 ? _g : []),
|
|||
|
...((_h = indexedWords.internalLink[query.charAt(0).toLowerCase()]) !== null && _h !== void 0 ? _h : []),
|
|||
|
]
|
|||
|
: frontMatter
|
|||
|
? flattenFrontMatterWords()
|
|||
|
: [
|
|||
|
...((_j = indexedWords.currentFile[query.charAt(0)]) !== null && _j !== void 0 ? _j : []),
|
|||
|
...((_k = indexedWords.currentVault[query.charAt(0)]) !== null && _k !== void 0 ? _k : []),
|
|||
|
...((_l = indexedWords.customDictionary[query.charAt(0)]) !== null && _l !== void 0 ? _l : []),
|
|||
|
...((_m = indexedWords.internalLink[query.charAt(0)]) !== null && _m !== void 0 ? _m : []),
|
|||
|
...((_o = indexedWords.internalLink[query.charAt(0).toUpperCase()]) !== null && _o !== void 0 ? _o : []),
|
|||
|
];
|
|||
|
const candidate = Array.from(words)
|
|||
|
.map((x) => judge(x, query, queryStartWithUpper))
|
|||
|
.filter((x) => x.value !== undefined)
|
|||
|
.sort((a, b) => {
|
|||
|
const aWord = a.word;
|
|||
|
const bWord = b.word;
|
|||
|
const notSameWordType = aWord.type !== bWord.type;
|
|||
|
if (frontMatter && notSameWordType) {
|
|||
|
return bWord.type === "frontMatter" ? 1 : -1;
|
|||
|
}
|
|||
|
if (selectionHistoryStorage) {
|
|||
|
const ret = selectionHistoryStorage.compare(aWord, bWord);
|
|||
|
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, max);
|
|||
|
// XXX: There is no guarantee that equals with max, but it is important for performance
|
|||
|
return uniqWith(candidate, (a, b) => a.value === b.value &&
|
|||
|
WordTypeMeta.of(a.type).group === WordTypeMeta.of(b.type).group);
|
|||
|
}
|
|||
|
// TODO: refactoring
|
|||
|
// Public for tests
|
|||
|
function judgeByPartialMatch(word, query, queryStartWithUpper) {
|
|||
|
var _a, _b;
|
|||
|
if (query === "") {
|
|||
|
return {
|
|||
|
word: Object.assign(Object.assign({}, word), { hit: word.value }),
|
|||
|
value: word.value,
|
|||
|
alias: false,
|
|||
|
};
|
|||
|
}
|
|||
|
if (lowerStartsWith(word.value, query)) {
|
|||
|
if (queryStartWithUpper &&
|
|||
|
word.type !== "internalLink" &&
|
|||
|
word.type !== "frontMatter") {
|
|||
|
const c = capitalizeFirstLetter(word.value);
|
|||
|
return { word: Object.assign(Object.assign({}, word), { value: c, hit: c }), value: c, alias: false };
|
|||
|
}
|
|||
|
else {
|
|||
|
return {
|
|||
|
word: Object.assign(Object.assign({}, word), { hit: word.value }),
|
|||
|
value: word.value,
|
|||
|
alias: false,
|
|||
|
};
|
|||
|
}
|
|||
|
}
|
|||
|
const matchedAliasStarts = (_a = word.aliases) === null || _a === void 0 ? void 0 : _a.find((a) => lowerStartsWith(a, query));
|
|||
|
if (matchedAliasStarts) {
|
|||
|
return {
|
|||
|
word: Object.assign(Object.assign({}, word), { hit: matchedAliasStarts }),
|
|||
|
value: matchedAliasStarts,
|
|||
|
alias: true,
|
|||
|
};
|
|||
|
}
|
|||
|
if (lowerIncludes(word.value, query)) {
|
|||
|
return {
|
|||
|
word: Object.assign(Object.assign({}, word), { hit: word.value }),
|
|||
|
value: word.value,
|
|||
|
alias: false,
|
|||
|
};
|
|||
|
}
|
|||
|
const matchedAliasIncluded = (_b = word.aliases) === null || _b === void 0 ? void 0 : _b.find((a) => lowerIncludes(a, query));
|
|||
|
if (matchedAliasIncluded) {
|
|||
|
return {
|
|||
|
word: Object.assign(Object.assign({}, word), { hit: matchedAliasIncluded }),
|
|||
|
value: matchedAliasIncluded,
|
|||
|
alias: true,
|
|||
|
};
|
|||
|
}
|
|||
|
return { word: word, alias: false };
|
|||
|
}
|
|||
|
function suggestWordsByPartialMatch(indexedWords, query, max, frontMatter, selectionHistoryStorage) {
|
|||
|
const queryStartWithUpper = capitalizeFirstLetter(query) === query;
|
|||
|
const flatObjectValues = (object) => Object.values(object).flat();
|
|||
|
const flattenFrontMatterWords = () => {
|
|||
|
var _a, _b;
|
|||
|
if (frontMatter === "alias" || frontMatter === "aliases") {
|
|||
|
return [];
|
|||
|
}
|
|||
|
if (frontMatter && ((_a = indexedWords.frontMatter) === null || _a === void 0 ? void 0 : _a[frontMatter])) {
|
|||
|
return Object.values((_b = indexedWords.frontMatter) === null || _b === void 0 ? void 0 : _b[frontMatter]).flat();
|
|||
|
}
|
|||
|
return [];
|
|||
|
};
|
|||
|
const words = frontMatter
|
|||
|
? flattenFrontMatterWords()
|
|||
|
: [
|
|||
|
...flatObjectValues(indexedWords.currentFile),
|
|||
|
...flatObjectValues(indexedWords.currentVault),
|
|||
|
...flatObjectValues(indexedWords.customDictionary),
|
|||
|
...flatObjectValues(indexedWords.internalLink),
|
|||
|
];
|
|||
|
const candidate = Array.from(words)
|
|||
|
.map((x) => judgeByPartialMatch(x, query, queryStartWithUpper))
|
|||
|
.filter((x) => x.value !== undefined)
|
|||
|
.sort((a, b) => {
|
|||
|
const aWord = a.word;
|
|||
|
const bWord = b.word;
|
|||
|
const notSameWordType = aWord.type !== bWord.type;
|
|||
|
if (frontMatter && notSameWordType) {
|
|||
|
return bWord.type === "frontMatter" ? 1 : -1;
|
|||
|
}
|
|||
|
if (selectionHistoryStorage) {
|
|||
|
const ret = selectionHistoryStorage.compare(aWord, bWord);
|
|||
|
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;
|
|||
|
}
|
|||
|
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, max);
|
|||
|
// XXX: There is no guarantee that equals with max, but it is important for performance
|
|||
|
return uniqWith(candidate, (a, b) => a.value === b.value &&
|
|||
|
WordTypeMeta.of(a.type).group === WordTypeMeta.of(b.type).group);
|
|||
|
}
|
|||
|
|
|||
|
function basename(path, ext) {
|
|||
|
var _a, _b;
|
|||
|
const name = (_b = (_a = path.match(/.+[\\/]([^\\/]+)[\\/]?$/)) === null || _a === void 0 ? void 0 : _a[1]) !== null && _b !== void 0 ? _b : path;
|
|||
|
return ext && name.endsWith(ext) ? name.replace(ext, "") : name;
|
|||
|
}
|
|||
|
function dirname(path) {
|
|||
|
var _a, _b;
|
|||
|
return (_b = (_a = path.match(/(.+)[\\/].+$/)) === null || _a === void 0 ? void 0 : _a[1]) !== null && _b !== void 0 ? _b : ".";
|
|||
|
}
|
|||
|
function isURL(path) {
|
|||
|
return Boolean(path.match(new RegExp("^https?://")));
|
|||
|
}
|
|||
|
|
|||
|
function escape(value) {
|
|||
|
// This tricky logics for Safari
|
|||
|
// https://github.com/tadashi-aikawa/obsidian-various-complements-plugin/issues/56
|
|||
|
return value
|
|||
|
.replace(/\\/g, "__VariousComplementsEscape__")
|
|||
|
.replace(/\n/g, "\\n")
|
|||
|
.replace(/\t/g, "\\t")
|
|||
|
.replace(/__VariousComplementsEscape__/g, "\\\\");
|
|||
|
}
|
|||
|
function unescape(value) {
|
|||
|
// This tricky logics for Safari
|
|||
|
// https://github.com/tadashi-aikawa/obsidian-various-complements-plugin/issues/56
|
|||
|
return value
|
|||
|
.replace(/\\\\/g, "__VariousComplementsEscape__")
|
|||
|
.replace(/\\n/g, "\n")
|
|||
|
.replace(/\\t/g, "\t")
|
|||
|
.replace(/__VariousComplementsEscape__/g, "\\");
|
|||
|
}
|
|||
|
function jsonToWords(json, path, systemCaretSymbol) {
|
|||
|
return json.words.map((x) => {
|
|||
|
var _a;
|
|||
|
return ({
|
|||
|
value: x.displayed || x.value,
|
|||
|
description: x.description,
|
|||
|
aliases: x.aliases,
|
|||
|
type: "customDictionary",
|
|||
|
createdPath: path,
|
|||
|
insertedText: x.displayed ? x.value : undefined,
|
|||
|
caretSymbol: (_a = json.caretSymbol) !== null && _a !== void 0 ? _a : systemCaretSymbol,
|
|||
|
ignoreSpaceAfterCompletion: json.ignoreSpaceAfterCompletion,
|
|||
|
});
|
|||
|
});
|
|||
|
}
|
|||
|
function lineToWord(line, delimiter, path, delimiterForDisplay, delimiterForHide, systemCaretSymbol) {
|
|||
|
const [v, description, ...aliases] = line.split(delimiter.value);
|
|||
|
let value = unescape(v);
|
|||
|
let insertedText;
|
|||
|
let displayedText = value;
|
|||
|
if (delimiterForDisplay && value.includes(delimiterForDisplay)) {
|
|||
|
[displayedText, insertedText] = value.split(delimiterForDisplay);
|
|||
|
}
|
|||
|
if (delimiterForHide && value.includes(delimiterForHide)) {
|
|||
|
insertedText = value.replace(delimiterForHide, "");
|
|||
|
displayedText = `${value.split(delimiterForHide)[0]} ...`;
|
|||
|
}
|
|||
|
return {
|
|||
|
value: displayedText,
|
|||
|
description,
|
|||
|
aliases,
|
|||
|
type: "customDictionary",
|
|||
|
createdPath: path,
|
|||
|
insertedText,
|
|||
|
caretSymbol: systemCaretSymbol,
|
|||
|
};
|
|||
|
}
|
|||
|
function wordToLine(word, delimiter, dividerForDisplay) {
|
|||
|
const value = word.insertedText && dividerForDisplay
|
|||
|
? `${word.value}${dividerForDisplay}${word.insertedText}`
|
|||
|
: word.value;
|
|||
|
const escapedValue = escape(value);
|
|||
|
if (!word.description && !word.aliases) {
|
|||
|
return escapedValue;
|
|||
|
}
|
|||
|
if (!word.aliases) {
|
|||
|
return [escapedValue, word.description].join(delimiter.value);
|
|||
|
}
|
|||
|
return [escapedValue, word.description, ...word.aliases].join(delimiter.value);
|
|||
|
}
|
|||
|
function synonymAliases$1(name) {
|
|||
|
const lessEmojiValue = excludeEmoji(name);
|
|||
|
return name === lessEmojiValue ? [] : [lessEmojiValue];
|
|||
|
}
|
|||
|
class CustomDictionaryWordProvider {
|
|||
|
constructor(app, appHelper) {
|
|||
|
this.words = [];
|
|||
|
this.wordByValue = {};
|
|||
|
this.wordsByFirstLetter = {};
|
|||
|
this.appHelper = appHelper;
|
|||
|
this.fileSystemAdapter = app.vault.adapter;
|
|||
|
}
|
|||
|
get editablePaths() {
|
|||
|
return this.paths.filter((x) => !isURL(x) && !x.endsWith(".json"));
|
|||
|
}
|
|||
|
loadWords(path, option) {
|
|||
|
return __awaiter(this, void 0, void 0, function* () {
|
|||
|
const contents = isURL(path)
|
|||
|
? yield obsidian.request({ url: path })
|
|||
|
: yield this.fileSystemAdapter.read(path);
|
|||
|
const words = path.endsWith(".json")
|
|||
|
? jsonToWords(JSON.parse(contents), path, option.caretSymbol)
|
|||
|
: contents
|
|||
|
.split(/\r\n|\n/)
|
|||
|
.map((x) => x.replace(/%%.*%%/g, ""))
|
|||
|
.filter((x) => x)
|
|||
|
.map((x) => lineToWord(x, this.delimiter, path, option.delimiterForDisplay, option.delimiterForHide, option.caretSymbol));
|
|||
|
return words.filter((x) => !option.regexp || x.value.match(new RegExp(option.regexp)));
|
|||
|
});
|
|||
|
}
|
|||
|
refreshCustomWords(option) {
|
|||
|
return __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.clearWords();
|
|||
|
for (const path of this.paths) {
|
|||
|
try {
|
|||
|
const words = yield this.loadWords(path, option);
|
|||
|
words.forEach((x) => this.words.push(x));
|
|||
|
}
|
|||
|
catch (e) {
|
|||
|
// noinspection ObjectAllocationIgnored
|
|||
|
new obsidian.Notice(`⚠ Fail to load ${path} -- Various Complements Plugin -- \n ${e}`, 0);
|
|||
|
}
|
|||
|
}
|
|||
|
this.words.forEach((x) => this.addWord(x));
|
|||
|
});
|
|||
|
}
|
|||
|
addWordWithDictionary(word, dictionaryPath) {
|
|||
|
return __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.addWord(word);
|
|||
|
yield this.fileSystemAdapter.append(dictionaryPath, "\n" + wordToLine(word, this.delimiter, this.dividerForDisplay));
|
|||
|
});
|
|||
|
}
|
|||
|
addWord(word) {
|
|||
|
var _a, _b;
|
|||
|
// Add aliases as a synonym
|
|||
|
const wordWithSynonym = Object.assign(Object.assign({}, word), { aliases: [...((_a = word.aliases) !== null && _a !== void 0 ? _a : []), ...synonymAliases$1(word.value)] });
|
|||
|
this.wordByValue[wordWithSynonym.value] = wordWithSynonym;
|
|||
|
pushWord(this.wordsByFirstLetter, wordWithSynonym.value.charAt(0), wordWithSynonym);
|
|||
|
(_b = wordWithSynonym.aliases) === null || _b === void 0 ? void 0 : _b.forEach((a) => pushWord(this.wordsByFirstLetter, a.charAt(0), wordWithSynonym));
|
|||
|
}
|
|||
|
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;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
class CurrentFileWordProvider {
|
|||
|
constructor(app, appHelper) {
|
|||
|
this.app = app;
|
|||
|
this.appHelper = appHelper;
|
|||
|
this.wordsByFirstLetter = {};
|
|||
|
this.words = [];
|
|||
|
}
|
|||
|
refreshWords(onlyEnglish) {
|
|||
|
return __awaiter(this, void 0, void 0, function* () {
|
|||
|
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();
|
|||
|
const content = yield this.app.vault.cachedRead(file);
|
|||
|
const tokens = onlyEnglish
|
|||
|
? this.tokenizer.tokenize(content).filter(allAlphabets)
|
|||
|
: this.tokenizer.tokenize(content);
|
|||
|
this.words = uniq(tokens)
|
|||
|
.filter((x) => x !== currentToken)
|
|||
|
.map((x) => ({
|
|||
|
value: x,
|
|||
|
type: "currentFile",
|
|||
|
createdPath: file.path,
|
|||
|
}));
|
|||
|
this.wordsByFirstLetter = groupBy(this.words, (x) => x.value.charAt(0));
|
|||
|
});
|
|||
|
}
|
|||
|
clearWords() {
|
|||
|
this.words = [];
|
|||
|
this.wordsByFirstLetter = {};
|
|||
|
}
|
|||
|
get wordCount() {
|
|||
|
return this.words.length;
|
|||
|
}
|
|||
|
setSettings(tokenizer) {
|
|||
|
this.tokenizer = tokenizer;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
class InternalLinkWordProvider {
|
|||
|
constructor(app, appHelper) {
|
|||
|
this.app = app;
|
|||
|
this.appHelper = appHelper;
|
|||
|
this.words = [];
|
|||
|
this.wordsByFirstLetter = {};
|
|||
|
}
|
|||
|
refreshWords(wordAsInternalLinkAlias, excludePathPrefixPatterns) {
|
|||
|
var _a;
|
|||
|
this.clearWords();
|
|||
|
const synonymAliases = (name) => {
|
|||
|
const lessEmojiValue = excludeEmoji(name);
|
|||
|
return name === lessEmojiValue ? [] : [lessEmojiValue];
|
|||
|
};
|
|||
|
const resolvedInternalLinkWords = this.app.vault
|
|||
|
.getMarkdownFiles()
|
|||
|
.filter((f) => excludePathPrefixPatterns.every((x) => !f.path.startsWith(x)))
|
|||
|
.flatMap((x) => {
|
|||
|
const aliases = this.appHelper.getAliases(x);
|
|||
|
if (wordAsInternalLinkAlias) {
|
|||
|
return [
|
|||
|
{
|
|||
|
value: x.basename,
|
|||
|
type: "internalLink",
|
|||
|
createdPath: x.path,
|
|||
|
aliases: synonymAliases(x.basename),
|
|||
|
description: x.path,
|
|||
|
},
|
|||
|
...aliases.map((a) => ({
|
|||
|
value: a,
|
|||
|
type: "internalLink",
|
|||
|
createdPath: x.path,
|
|||
|
aliases: synonymAliases(a),
|
|||
|
description: x.path,
|
|||
|
aliasMeta: {
|
|||
|
origin: x.basename,
|
|||
|
},
|
|||
|
})),
|
|||
|
];
|
|||
|
}
|
|||
|
else {
|
|||
|
return [
|
|||
|
{
|
|||
|
value: x.basename,
|
|||
|
type: "internalLink",
|
|||
|
createdPath: x.path,
|
|||
|
aliases: [
|
|||
|
...synonymAliases(x.basename),
|
|||
|
...aliases,
|
|||
|
...aliases.flatMap(synonymAliases),
|
|||
|
],
|
|||
|
description: x.path,
|
|||
|
},
|
|||
|
];
|
|||
|
}
|
|||
|
});
|
|||
|
const unresolvedInternalLinkWords = this.appHelper
|
|||
|
.searchPhantomLinks()
|
|||
|
.map(({ path, link }) => {
|
|||
|
return {
|
|||
|
value: link,
|
|||
|
type: "internalLink",
|
|||
|
createdPath: path,
|
|||
|
aliases: synonymAliases(link),
|
|||
|
description: `Appeared in -> ${path}`,
|
|||
|
phantom: true,
|
|||
|
};
|
|||
|
});
|
|||
|
this.words = [...resolvedInternalLinkWords, ...unresolvedInternalLinkWords];
|
|||
|
for (const word of this.words) {
|
|||
|
pushWord(this.wordsByFirstLetter, word.value.charAt(0), word);
|
|||
|
(_a = word.aliases) === null || _a === void 0 ? void 0 : _a.forEach((a) => pushWord(this.wordsByFirstLetter, a.charAt(0), word));
|
|||
|
}
|
|||
|
}
|
|||
|
clearWords() {
|
|||
|
this.words = [];
|
|||
|
this.wordsByFirstLetter = {};
|
|||
|
}
|
|||
|
get wordCount() {
|
|||
|
return this.words.length;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
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);
|
|||
|
|
|||
|
class CycleThroughSuggestionsKeys {
|
|||
|
constructor(name, nextKey, previousKey) {
|
|||
|
this.name = name;
|
|||
|
this.nextKey = nextKey;
|
|||
|
this.previousKey = previousKey;
|
|||
|
CycleThroughSuggestionsKeys._values.push(this);
|
|||
|
}
|
|||
|
static fromName(name) {
|
|||
|
return CycleThroughSuggestionsKeys._values.find((x) => x.name === name);
|
|||
|
}
|
|||
|
static values() {
|
|||
|
return CycleThroughSuggestionsKeys._values;
|
|||
|
}
|
|||
|
}
|
|||
|
CycleThroughSuggestionsKeys._values = [];
|
|||
|
CycleThroughSuggestionsKeys.NONE = new CycleThroughSuggestionsKeys("None", { modifiers: [], key: null }, { modifiers: [], key: null });
|
|||
|
CycleThroughSuggestionsKeys.TAB = new CycleThroughSuggestionsKeys("Tab, Shift+Tab", { modifiers: [], key: "Tab" }, { modifiers: ["Shift"], key: "Tab" });
|
|||
|
CycleThroughSuggestionsKeys.EMACS = new CycleThroughSuggestionsKeys("Ctrl/Cmd+N, Ctrl/Cmd+P", { modifiers: ["Mod"], key: "N" }, { modifiers: ["Mod"], key: "P" });
|
|||
|
CycleThroughSuggestionsKeys.VIM = new CycleThroughSuggestionsKeys("Ctrl/Cmd+J, Ctrl/Cmd+K", { modifiers: ["Mod"], key: "J" }, { modifiers: ["Mod"], key: "K" });
|
|||
|
|
|||
|
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", "\t");
|
|||
|
ColumnDelimiter.COMMA = new ColumnDelimiter("Comma", ",");
|
|||
|
ColumnDelimiter.PIPE = new ColumnDelimiter("Pipe", "|");
|
|||
|
|
|||
|
class SelectSuggestionKey {
|
|||
|
constructor(name, keyBind) {
|
|||
|
this.name = name;
|
|||
|
this.keyBind = keyBind;
|
|||
|
SelectSuggestionKey._values.push(this);
|
|||
|
}
|
|||
|
static fromName(name) {
|
|||
|
return SelectSuggestionKey._values.find((x) => x.name === name);
|
|||
|
}
|
|||
|
static values() {
|
|||
|
return SelectSuggestionKey._values;
|
|||
|
}
|
|||
|
}
|
|||
|
SelectSuggestionKey._values = [];
|
|||
|
SelectSuggestionKey.ENTER = new SelectSuggestionKey("Enter", {
|
|||
|
modifiers: [],
|
|||
|
key: "Enter",
|
|||
|
});
|
|||
|
SelectSuggestionKey.TAB = new SelectSuggestionKey("Tab", {
|
|||
|
modifiers: [],
|
|||
|
key: "Tab",
|
|||
|
});
|
|||
|
SelectSuggestionKey.MOD_ENTER = new SelectSuggestionKey("Ctrl/Cmd+Enter", {
|
|||
|
modifiers: ["Mod"],
|
|||
|
key: "Enter",
|
|||
|
});
|
|||
|
SelectSuggestionKey.ALT_ENTER = new SelectSuggestionKey("Alt+Enter", {
|
|||
|
modifiers: ["Alt"],
|
|||
|
key: "Enter",
|
|||
|
});
|
|||
|
SelectSuggestionKey.SHIFT_ENTER = new SelectSuggestionKey("Shift+Enter", {
|
|||
|
modifiers: ["Shift"],
|
|||
|
key: "Enter",
|
|||
|
});
|
|||
|
SelectSuggestionKey.SPACE = new SelectSuggestionKey("Space", {
|
|||
|
modifiers: [],
|
|||
|
key: " ",
|
|||
|
});
|
|||
|
|
|||
|
class CurrentVaultWordProvider {
|
|||
|
constructor(app, appHelper) {
|
|||
|
this.app = app;
|
|||
|
this.appHelper = appHelper;
|
|||
|
this.wordsByFirstLetter = {};
|
|||
|
this.words = [];
|
|||
|
}
|
|||
|
refreshWords() {
|
|||
|
return __awaiter(this, void 0, void 0, function* () {
|
|||
|
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) => !this.onlyUnderCurrentDirectory || dirname(p) === currentDirname);
|
|||
|
let wordByValue = {};
|
|||
|
for (const path of markdownFilePaths) {
|
|||
|
const content = yield this.app.vault.adapter.read(path);
|
|||
|
for (const token of this.tokenizer.tokenize(content)) {
|
|||
|
wordByValue[token] = {
|
|||
|
value: token,
|
|||
|
type: "currentVault",
|
|||
|
createdPath: path,
|
|||
|
description: path,
|
|||
|
};
|
|||
|
}
|
|||
|
}
|
|||
|
this.words = Object.values(wordByValue);
|
|||
|
this.wordsByFirstLetter = groupBy(this.words, (x) => x.value.charAt(0));
|
|||
|
});
|
|||
|
}
|
|||
|
clearWords() {
|
|||
|
this.words = [];
|
|||
|
this.wordsByFirstLetter = {};
|
|||
|
}
|
|||
|
get wordCount() {
|
|||
|
return this.words.length;
|
|||
|
}
|
|||
|
setSettings(tokenizer, includePrefixPatterns, excludePrefixPatterns, onlyUnderCurrentDirectory) {
|
|||
|
this.tokenizer = tokenizer;
|
|||
|
this.includePrefixPatterns = includePrefixPatterns;
|
|||
|
this.excludePrefixPatterns = excludePrefixPatterns;
|
|||
|
this.onlyUnderCurrentDirectory = onlyUnderCurrentDirectory;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
class OpenSourceFileKeys {
|
|||
|
constructor(name, keyBind) {
|
|||
|
this.name = name;
|
|||
|
this.keyBind = keyBind;
|
|||
|
OpenSourceFileKeys._values.push(this);
|
|||
|
}
|
|||
|
static fromName(name) {
|
|||
|
return OpenSourceFileKeys._values.find((x) => x.name === name);
|
|||
|
}
|
|||
|
static values() {
|
|||
|
return OpenSourceFileKeys._values;
|
|||
|
}
|
|||
|
}
|
|||
|
OpenSourceFileKeys._values = [];
|
|||
|
OpenSourceFileKeys.NONE = new OpenSourceFileKeys("None", {
|
|||
|
modifiers: [],
|
|||
|
key: null,
|
|||
|
});
|
|||
|
OpenSourceFileKeys.MOD_ENTER = new OpenSourceFileKeys("Ctrl/Cmd+Enter", {
|
|||
|
modifiers: ["Mod"],
|
|||
|
key: "Enter",
|
|||
|
});
|
|||
|
OpenSourceFileKeys.ALT_ENTER = new OpenSourceFileKeys("Alt+Enter", {
|
|||
|
modifiers: ["Alt"],
|
|||
|
key: "Enter",
|
|||
|
});
|
|||
|
OpenSourceFileKeys.SHIFT_ENTER = new OpenSourceFileKeys("Shift+Enter", {
|
|||
|
modifiers: ["Shift"],
|
|||
|
key: "Enter",
|
|||
|
});
|
|||
|
|
|||
|
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 !== void 0 ? _a : null; });
|
|||
|
|
|||
|
function synonymAliases(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: synonymAliases(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));
|
|||
|
}
|
|||
|
// noinspection FunctionWithMultipleLoopsJS
|
|||
|
function extractAndUniqWords(wordsByCreatedPath) {
|
|||
|
return uniqBy(Object.values(wordsByCreatedPath).flat(), (w) => w.key + w.value.toLowerCase());
|
|||
|
}
|
|||
|
function indexingWords(words) {
|
|||
|
const wordsByKey = groupBy(words, (x) => x.key);
|
|||
|
return Object.fromEntries(Object.entries(wordsByKey).map(([key, words]) => [
|
|||
|
key,
|
|||
|
groupBy(words, (w) => w.value.charAt(0)),
|
|||
|
]));
|
|||
|
}
|
|||
|
class FrontMatterWordProvider {
|
|||
|
constructor(app, appHelper) {
|
|||
|
this.app = app;
|
|||
|
this.appHelper = appHelper;
|
|||
|
this.wordsByCreatedPath = {};
|
|||
|
}
|
|||
|
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) {
|
|||
|
return;
|
|||
|
}
|
|||
|
this.wordsByCreatedPath[file.path] = pickWords(file, fm);
|
|||
|
}
|
|||
|
updateWords() {
|
|||
|
this.words = extractAndUniqWords(this.wordsByCreatedPath);
|
|||
|
this.wordsByFirstLetterByKey = indexingWords(this.words);
|
|||
|
}
|
|||
|
clearWords() {
|
|||
|
this.wordsByCreatedPath = {};
|
|||
|
this.words = [];
|
|||
|
this.wordsByFirstLetterByKey = {};
|
|||
|
}
|
|||
|
get wordCount() {
|
|||
|
return this.words.length;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
const neverUsedHandler = (..._args) => [];
|
|||
|
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);
|
|||
|
|
|||
|
const SEC = 1000;
|
|||
|
const MIN = SEC * 60;
|
|||
|
const HOUR = MIN * 60;
|
|||
|
const DAY = HOUR * 24;
|
|||
|
const WEEK = DAY * 7;
|
|||
|
function calcScore(history) {
|
|||
|
if (!history) {
|
|||
|
return 0;
|
|||
|
}
|
|||
|
const behind = Date.now() - history.lastUpdated;
|
|||
|
// noinspection IfStatementWithTooManyBranchesJS
|
|||
|
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;
|
|||
|
}
|
|||
|
}
|
|||
|
class SelectionHistoryStorage {
|
|||
|
constructor(data = {}) {
|
|||
|
this.data = data;
|
|||
|
const now = Date.now();
|
|||
|
this.version = now;
|
|||
|
this.persistedVersion = now;
|
|||
|
}
|
|||
|
// noinspection FunctionWithMultipleLoopsJS
|
|||
|
purge() {
|
|||
|
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 (Date.now() - this.data[hit][value][kind].lastUpdated > 4 * WEEK) {
|
|||
|
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];
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
getSelectionHistory(word) {
|
|||
|
var _a, _b;
|
|||
|
return (_b = (_a = this.data[word.hit]) === null || _a === void 0 ? void 0 : _a[word.value]) === null || _b === void 0 ? void 0 : _b[word.type];
|
|||
|
}
|
|||
|
increment(word) {
|
|||
|
if (!this.data[word.hit]) {
|
|||
|
this.data[word.hit] = {};
|
|||
|
}
|
|||
|
if (!this.data[word.hit][word.value]) {
|
|||
|
this.data[word.hit][word.value] = {};
|
|||
|
}
|
|||
|
if (this.data[word.hit][word.value][word.type]) {
|
|||
|
this.data[word.hit][word.value][word.type] = {
|
|||
|
count: this.data[word.hit][word.value][word.type].count + 1,
|
|||
|
lastUpdated: Date.now(),
|
|||
|
};
|
|||
|
}
|
|||
|
else {
|
|||
|
this.data[word.hit][word.value][word.type] = {
|
|||
|
count: 1,
|
|||
|
lastUpdated: Date.now(),
|
|||
|
};
|
|||
|
}
|
|||
|
this.version = Date.now();
|
|||
|
}
|
|||
|
compare(w1, w2) {
|
|||
|
const score1 = calcScore(this.getSelectionHistory(w1));
|
|||
|
const score2 = calcScore(this.getSelectionHistory(w2));
|
|||
|
if (score1 === score2) {
|
|||
|
return 0;
|
|||
|
}
|
|||
|
return score1 > score2 ? -1 : 1;
|
|||
|
}
|
|||
|
get shouldPersist() {
|
|||
|
return this.version > this.persistedVersion;
|
|||
|
}
|
|||
|
syncPersistVersion() {
|
|||
|
this.persistedVersion = this.version;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function buildLogMessage(message, msec) {
|
|||
|
return `${message}: ${Math.round(msec)}[ms]`;
|
|||
|
}
|
|||
|
class AutoCompleteSuggest extends obsidian.EditorSuggest {
|
|||
|
constructor(app, statusBar) {
|
|||
|
super(app);
|
|||
|
this.previousCurrentLine = "";
|
|||
|
this.keymapEventHandler = [];
|
|||
|
this.appHelper = new AppHelper(app);
|
|||
|
this.statusBar = statusBar;
|
|||
|
}
|
|||
|
triggerComplete() {
|
|||
|
const editor = this.appHelper.getCurrentEditor();
|
|||
|
const activeFile = this.app.workspace.getActiveFile();
|
|||
|
if (!editor || !activeFile) {
|
|||
|
return;
|
|||
|
}
|
|||
|
// XXX: Unsafe
|
|||
|
this.runManually = true;
|
|||
|
this.trigger(editor, activeFile, true);
|
|||
|
}
|
|||
|
static new(app, settings, statusBar, onPersistSelectionHistory) {
|
|||
|
return __awaiter(this, void 0, void 0, function* () {
|
|||
|
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);
|
|||
|
ins.selectionHistoryStorage = new SelectionHistoryStorage(settings.selectionHistoryTree);
|
|||
|
ins.selectionHistoryStorage.purge();
|
|||
|
yield ins.updateSettings(settings);
|
|||
|
ins.modifyEventRef = app.vault.on("modify", (_) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
var _a;
|
|||
|
yield ins.refreshCurrentFileTokens();
|
|||
|
if ((_a = ins.selectionHistoryStorage) === null || _a === void 0 ? void 0 : _a.shouldPersist) {
|
|||
|
ins.settings.selectionHistoryTree = ins.selectionHistoryStorage.data;
|
|||
|
ins.selectionHistoryStorage.syncPersistVersion();
|
|||
|
onPersistSelectionHistory();
|
|||
|
}
|
|||
|
}));
|
|||
|
ins.activeLeafChangeRef = app.workspace.on("active-leaf-change", (_) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
yield ins.refreshCurrentFileTokens();
|
|||
|
ins.refreshInternalLinkTokens();
|
|||
|
ins.updateFrontMatterToken();
|
|||
|
}));
|
|||
|
ins.metadataCacheChangeRef = app.metadataCache.on("changed", (f) => {
|
|||
|
ins.updateFrontMatterTokenIndex(f);
|
|||
|
if (!ins.appHelper.isActiveFile(f)) {
|
|||
|
ins.updateFrontMatterToken();
|
|||
|
}
|
|||
|
});
|
|||
|
// Avoid referring to incorrect cache
|
|||
|
const cacheResolvedRef = app.metadataCache.on("resolved", () => __awaiter(this, void 0, void 0, function* () {
|
|||
|
ins.refreshInternalLinkTokens();
|
|||
|
ins.refreshFrontMatterTokens();
|
|||
|
// noinspection ES6MissingAwait
|
|||
|
ins.refreshCustomDictionaryTokens();
|
|||
|
// noinspection ES6MissingAwait
|
|||
|
ins.refreshCurrentVaultTokens();
|
|||
|
ins.app.metadataCache.offref(cacheResolvedRef);
|
|||
|
}));
|
|||
|
return ins;
|
|||
|
});
|
|||
|
}
|
|||
|
predictableComplete() {
|
|||
|
const editor = this.appHelper.getCurrentEditor();
|
|||
|
if (!editor) {
|
|||
|
return;
|
|||
|
}
|
|||
|
const cursor = editor.getCursor();
|
|||
|
const currentToken = this.tokenizer
|
|||
|
.tokenize(editor.getLine(cursor.line).slice(0, cursor.ch))
|
|||
|
.last();
|
|||
|
if (!currentToken) {
|
|||
|
return;
|
|||
|
}
|
|||
|
let suggestion = this.tokenizer
|
|||
|
.tokenize(editor.getRange({ line: Math.max(cursor.line - 50, 0), ch: 0 }, cursor))
|
|||
|
.reverse()
|
|||
|
.slice(1)
|
|||
|
.find((x) => x.startsWith(currentToken));
|
|||
|
if (!suggestion) {
|
|||
|
suggestion = this.tokenizer
|
|||
|
.tokenize(editor.getRange(cursor, {
|
|||
|
line: Math.min(cursor.line + 50, editor.lineCount() - 1),
|
|||
|
ch: 0,
|
|||
|
}))
|
|||
|
.find((x) => x.startsWith(currentToken));
|
|||
|
}
|
|||
|
if (!suggestion) {
|
|||
|
return;
|
|||
|
}
|
|||
|
editor.replaceRange(suggestion, { line: cursor.line, ch: cursor.ch - currentToken.length }, { line: cursor.line, ch: cursor.ch });
|
|||
|
this.close();
|
|||
|
this.debounceClose();
|
|||
|
}
|
|||
|
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);
|
|||
|
}
|
|||
|
get minNumberTriggered() {
|
|||
|
return (this.settings.minNumberOfCharactersTriggered ||
|
|||
|
this.tokenizerStrategy.triggerThreshold);
|
|||
|
}
|
|||
|
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,
|
|||
|
};
|
|||
|
}
|
|||
|
updateSettings(settings) {
|
|||
|
return __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.settings = settings;
|
|||
|
this.statusBar.setMatchStrategy(this.matchStrategy);
|
|||
|
this.tokenizer = createTokenizer(this.tokenizerStrategy);
|
|||
|
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.includeCurrentVaultOnlyFilesUnderCurrentDirectory);
|
|||
|
this.customDictionaryWordProvider.setSettings(settings.customDictionaryPaths.split("\n").filter((x) => x), ColumnDelimiter.fromName(settings.columnDelimiter), settings.delimiterToDivideSuggestionsForDisplayFromInsertion || null);
|
|||
|
this.debounceGetSuggestions = obsidian.debounce((context, cb) => {
|
|||
|
const start = performance.now();
|
|||
|
this.showDebugLog(() => `[context.query]: ${context.query}`);
|
|||
|
const parsedQuery = JSON.parse(context.query);
|
|||
|
const words = parsedQuery.queries
|
|||
|
.filter((x, i, xs) => parsedQuery.currentFrontMatter ||
|
|||
|
(this.settings.minNumberOfWordsTriggeredPhrase + i - 1 <
|
|||
|
xs.length &&
|
|||
|
x.word.length >= this.minNumberTriggered &&
|
|||
|
!this.tokenizer.shouldIgnore(x.word) &&
|
|||
|
!x.word.endsWith(" ")))
|
|||
|
.map((q) => {
|
|||
|
const handler = parsedQuery.currentFrontMatter &&
|
|||
|
this.frontMatterComplementStrategy !==
|
|||
|
SpecificMatchStrategy.INHERIT
|
|||
|
? this.frontMatterComplementStrategy.handler
|
|||
|
: this.matchStrategy.handler;
|
|||
|
return handler(this.indexedWords, q.word, this.settings.maxNumberOfSuggestions, parsedQuery.currentFrontMatter, this.selectionHistoryStorage).map((word) => (Object.assign(Object.assign({}, word), { offset: q.offset })));
|
|||
|
})
|
|||
|
.flat();
|
|||
|
cb(uniqWith(words, (a, b) => a.value === b.value && a.type === b.type).slice(0, this.settings.maxNumberOfSuggestions));
|
|||
|
this.showDebugLog(() => buildLogMessage("Get suggestions", performance.now() - start));
|
|||
|
}, this.settings.delayMilliSeconds, true);
|
|||
|
this.debounceClose = obsidian.debounce(() => {
|
|||
|
this.close();
|
|||
|
}, this.settings.delayMilliSeconds + 50);
|
|||
|
this.registerKeymaps();
|
|||
|
});
|
|||
|
}
|
|||
|
registerKeymaps() {
|
|||
|
// Clear
|
|||
|
this.keymapEventHandler.forEach((x) => this.scope.unregister(x));
|
|||
|
this.keymapEventHandler = [];
|
|||
|
this.scope.unregister(this.scope.keys.find((x) => x.key === "Enter"));
|
|||
|
const selectSuggestionKey = SelectSuggestionKey.fromName(this.settings.selectSuggestionKeys);
|
|||
|
if (selectSuggestionKey !== SelectSuggestionKey.ENTER) {
|
|||
|
this.keymapEventHandler.push(this.scope.register(SelectSuggestionKey.ENTER.keyBind.modifiers, SelectSuggestionKey.ENTER.keyBind.key, () => {
|
|||
|
this.close();
|
|||
|
return true;
|
|||
|
}));
|
|||
|
}
|
|||
|
if (selectSuggestionKey !== SelectSuggestionKey.TAB) {
|
|||
|
this.keymapEventHandler.push(this.scope.register(SelectSuggestionKey.TAB.keyBind.modifiers, SelectSuggestionKey.TAB.keyBind.key, () => {
|
|||
|
this.close();
|
|||
|
return true;
|
|||
|
}));
|
|||
|
}
|
|||
|
this.keymapEventHandler.push(this.scope.register(selectSuggestionKey.keyBind.modifiers, selectSuggestionKey.keyBind.key, () => {
|
|||
|
this.suggestions.useSelectedItem({});
|
|||
|
return false;
|
|||
|
}));
|
|||
|
this.scope.keys.find((x) => x.key === "Escape").func = () => {
|
|||
|
this.close();
|
|||
|
return this.settings.propagateEsc;
|
|||
|
};
|
|||
|
const cycleThroughSuggestionsKeys = CycleThroughSuggestionsKeys.fromName(this.settings.additionalCycleThroughSuggestionsKeys);
|
|||
|
if (cycleThroughSuggestionsKeys !== CycleThroughSuggestionsKeys.NONE) {
|
|||
|
if (cycleThroughSuggestionsKeys === CycleThroughSuggestionsKeys.TAB) {
|
|||
|
this.scope.unregister(this.scope.keys.find((x) => x.modifiers === "" && x.key === "Tab"));
|
|||
|
}
|
|||
|
this.keymapEventHandler.push(this.scope.register(cycleThroughSuggestionsKeys.nextKey.modifiers, cycleThroughSuggestionsKeys.nextKey.key, () => {
|
|||
|
this.suggestions.setSelectedItem(this.suggestions.selectedItem + 1, true);
|
|||
|
return false;
|
|||
|
}), this.scope.register(cycleThroughSuggestionsKeys.previousKey.modifiers, cycleThroughSuggestionsKeys.previousKey.key, () => {
|
|||
|
this.suggestions.setSelectedItem(this.suggestions.selectedItem - 1, true);
|
|||
|
return false;
|
|||
|
}));
|
|||
|
}
|
|||
|
const openSourceFileKey = OpenSourceFileKeys.fromName(this.settings.openSourceFileKey);
|
|||
|
if (openSourceFileKey !== OpenSourceFileKeys.NONE) {
|
|||
|
this.keymapEventHandler.push(this.scope.register(openSourceFileKey.keyBind.modifiers, openSourceFileKey.keyBind.key, () => {
|
|||
|
const item = this.suggestions.values[this.suggestions.selectedItem];
|
|||
|
if (item.type !== "currentVault" &&
|
|||
|
item.type !== "internalLink" &&
|
|||
|
item.type !== "frontMatter") {
|
|||
|
return false;
|
|||
|
}
|
|||
|
const markdownFile = this.appHelper.getMarkdownFileByPath(item.createdPath);
|
|||
|
if (!markdownFile) {
|
|||
|
// noinspection ObjectAllocationIgnored
|
|||
|
new obsidian.Notice(`Can't open ${item.createdPath}`);
|
|||
|
return false;
|
|||
|
}
|
|||
|
this.appHelper.openMarkdownFile(markdownFile, true);
|
|||
|
return false;
|
|||
|
}));
|
|||
|
}
|
|||
|
}
|
|||
|
refreshCurrentFileTokens() {
|
|||
|
return __awaiter(this, void 0, void 0, function* () {
|
|||
|
const start = performance.now();
|
|||
|
this.statusBar.setCurrentFileIndexing();
|
|||
|
if (!this.settings.enableCurrentFileComplement) {
|
|||
|
this.statusBar.setCurrentFileDisabled();
|
|||
|
this.currentFileWordProvider.clearWords();
|
|||
|
this.showDebugLog(() => buildLogMessage("👢 Skip: Index current file tokens", performance.now() - start));
|
|||
|
return;
|
|||
|
}
|
|||
|
yield this.currentFileWordProvider.refreshWords(this.settings.onlyComplementEnglishOnCurrentFileComplement);
|
|||
|
this.statusBar.setCurrentFileIndexed(this.currentFileWordProvider.wordCount);
|
|||
|
this.showDebugLog(() => buildLogMessage("Index current file tokens", performance.now() - start));
|
|||
|
});
|
|||
|
}
|
|||
|
refreshCurrentVaultTokens() {
|
|||
|
return __awaiter(this, void 0, void 0, function* () {
|
|||
|
const start = performance.now();
|
|||
|
this.statusBar.setCurrentVaultIndexing();
|
|||
|
if (!this.settings.enableCurrentVaultComplement) {
|
|||
|
this.statusBar.setCurrentVaultDisabled();
|
|||
|
this.currentVaultWordProvider.clearWords();
|
|||
|
this.showDebugLog(() => buildLogMessage("👢 Skip: Index current vault tokens", performance.now() - start));
|
|||
|
return;
|
|||
|
}
|
|||
|
yield this.currentVaultWordProvider.refreshWords();
|
|||
|
this.statusBar.setCurrentVaultIndexed(this.currentVaultWordProvider.wordCount);
|
|||
|
this.showDebugLog(() => buildLogMessage("Index current vault tokens", performance.now() - start));
|
|||
|
});
|
|||
|
}
|
|||
|
refreshCustomDictionaryTokens() {
|
|||
|
return __awaiter(this, void 0, void 0, function* () {
|
|||
|
const start = performance.now();
|
|||
|
this.statusBar.setCustomDictionaryIndexing();
|
|||
|
if (!this.settings.enableCustomDictionaryComplement) {
|
|||
|
this.statusBar.setCustomDictionaryDisabled();
|
|||
|
this.customDictionaryWordProvider.clearWords();
|
|||
|
this.showDebugLog(() => buildLogMessage("👢Skip: Index custom dictionary tokens", performance.now() - start));
|
|||
|
return;
|
|||
|
}
|
|||
|
yield this.customDictionaryWordProvider.refreshCustomWords({
|
|||
|
regexp: this.settings.customDictionaryWordRegexPattern,
|
|||
|
delimiterForHide: this.settings.delimiterToHideSuggestion || undefined,
|
|||
|
delimiterForDisplay: this.settings.delimiterToDivideSuggestionsForDisplayFromInsertion ||
|
|||
|
undefined,
|
|||
|
caretSymbol: this.settings.caretLocationSymbolAfterComplement || undefined,
|
|||
|
});
|
|||
|
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("👢Skip: Index internal link tokens", performance.now() - start));
|
|||
|
return;
|
|||
|
}
|
|||
|
this.internalLinkWordProvider.refreshWords(this.settings.suggestInternalLinkWithAlias, this.excludeInternalLinkPrefixPathPatterns);
|
|||
|
this.statusBar.setInternalLinkIndexed(this.internalLinkWordProvider.wordCount);
|
|||
|
this.showDebugLog(() => buildLogMessage("Index internal link tokens", performance.now() - start));
|
|||
|
}
|
|||
|
refreshFrontMatterTokens() {
|
|||
|
const start = performance.now();
|
|||
|
this.statusBar.setFrontMatterIndexing();
|
|||
|
if (!this.settings.enableFrontMatterComplement) {
|
|||
|
this.statusBar.setFrontMatterDisabled();
|
|||
|
this.frontMatterWordProvider.clearWords();
|
|||
|
this.showDebugLog(() => buildLogMessage("👢Skip: Index front matter tokens", performance.now() - start));
|
|||
|
return;
|
|||
|
}
|
|||
|
this.frontMatterWordProvider.refreshWords();
|
|||
|
this.statusBar.setFrontMatterIndexed(this.frontMatterWordProvider.wordCount);
|
|||
|
this.showDebugLog(() => buildLogMessage("Index front matter tokens", performance.now() - start));
|
|||
|
}
|
|||
|
updateFrontMatterTokenIndex(file) {
|
|||
|
const start = performance.now();
|
|||
|
if (!this.settings.enableFrontMatterComplement) {
|
|||
|
this.showDebugLog(() => buildLogMessage("👢Skip: Update front matter token index", performance.now() - start));
|
|||
|
return;
|
|||
|
}
|
|||
|
this.frontMatterWordProvider.updateWordIndex(file);
|
|||
|
this.showDebugLog(() => buildLogMessage("Update front matter token index", performance.now() - start));
|
|||
|
}
|
|||
|
updateFrontMatterToken() {
|
|||
|
const start = performance.now();
|
|||
|
if (!this.settings.enableFrontMatterComplement) {
|
|||
|
this.showDebugLog(() => buildLogMessage("👢Skip: Update front matter token", performance.now() - start));
|
|||
|
return;
|
|||
|
}
|
|||
|
this.frontMatterWordProvider.updateWords();
|
|||
|
this.statusBar.setFrontMatterIndexed(this.frontMatterWordProvider.wordCount);
|
|||
|
this.showDebugLog(() => buildLogMessage("Update front matter token", performance.now() - start));
|
|||
|
}
|
|||
|
onTrigger(cursor, editor, file) {
|
|||
|
var _a, _b, _c, _d, _e, _f;
|
|||
|
const start = performance.now();
|
|||
|
if (!this.settings.complementAutomatically &&
|
|||
|
!this.isOpen &&
|
|||
|
!this.runManually) {
|
|||
|
this.showDebugLog(() => "Don't show suggestions");
|
|||
|
return null;
|
|||
|
}
|
|||
|
if (this.settings.disableSuggestionsDuringImeOn &&
|
|||
|
this.appHelper.isIMEOn() &&
|
|||
|
!this.runManually) {
|
|||
|
this.showDebugLog(() => "Don't show suggestions for IME");
|
|||
|
return null;
|
|||
|
}
|
|||
|
const cl = this.appHelper.getCurrentLine(editor);
|
|||
|
if (this.previousCurrentLine === cl && !this.runManually) {
|
|||
|
this.previousCurrentLine = cl;
|
|||
|
this.showDebugLog(() => "Don't show suggestions because there are no changes");
|
|||
|
return null;
|
|||
|
}
|
|||
|
this.previousCurrentLine = cl;
|
|||
|
const currentLineUntilCursor = this.appHelper.getCurrentLineUntilCursor(editor);
|
|||
|
if (currentLineUntilCursor.startsWith("---")) {
|
|||
|
this.showDebugLog(() => "Don't show suggestions because it supposes front matter or horizontal line");
|
|||
|
return null;
|
|||
|
}
|
|||
|
if (currentLineUntilCursor.startsWith("~~~") ||
|
|||
|
currentLineUntilCursor.startsWith("```")) {
|
|||
|
this.showDebugLog(() => "Don't show suggestions because it supposes front code block");
|
|||
|
return null;
|
|||
|
}
|
|||
|
const tokens = this.tokenizer.tokenize(currentLineUntilCursor, true);
|
|||
|
this.showDebugLog(() => `[onTrigger] tokens is ${tokens}`);
|
|||
|
const tokenized = this.tokenizer.recursiveTokenize(currentLineUntilCursor);
|
|||
|
const currentTokens = tokenized.slice(tokenized.length > this.settings.maxNumberOfWordsAsPhrase
|
|||
|
? tokenized.length - this.settings.maxNumberOfWordsAsPhrase
|
|||
|
: 0);
|
|||
|
this.showDebugLog(() => `[onTrigger] currentTokens is ${JSON.stringify(currentTokens)}`);
|
|||
|
const currentToken = (_a = currentTokens[0]) === null || _a === void 0 ? void 0 : _a.word;
|
|||
|
this.showDebugLog(() => `[onTrigger] currentToken is ${currentToken}`);
|
|||
|
if (!currentToken) {
|
|||
|
this.runManually = false;
|
|||
|
this.showDebugLog(() => `Don't show suggestions because currentToken is empty`);
|
|||
|
return null;
|
|||
|
}
|
|||
|
const currentTokenSeparatedWhiteSpace = (_b = currentLineUntilCursor.split(" ").last()) !== null && _b !== void 0 ? _b : "";
|
|||
|
if (new RegExp(`^[${this.settings.firstCharactersDisableSuggestions}]`).test(currentTokenSeparatedWhiteSpace)) {
|
|||
|
this.runManually = false;
|
|||
|
this.showDebugLog(() => `Don't show suggestions for avoiding to conflict with the other commands.`);
|
|||
|
return null;
|
|||
|
}
|
|||
|
if (currentToken.length === 1 &&
|
|||
|
Boolean(currentToken.match(this.tokenizer.getTrimPattern()))) {
|
|||
|
this.runManually = false;
|
|||
|
this.showDebugLog(() => `Don't show suggestions because currentToken is TRIM_PATTERN`);
|
|||
|
return null;
|
|||
|
}
|
|||
|
const currentFrontMatter = this.settings.enableFrontMatterComplement
|
|||
|
? this.appHelper.getCurrentFrontMatter()
|
|||
|
: null;
|
|||
|
this.showDebugLog(() => `Current front matter is ${currentFrontMatter}`);
|
|||
|
if (!this.runManually && !currentFrontMatter) {
|
|||
|
if (currentToken.length < this.minNumberTriggered) {
|
|||
|
this.showDebugLog(() => "Don't show suggestions because currentToken is less than minNumberTriggered option");
|
|||
|
return null;
|
|||
|
}
|
|||
|
if (this.tokenizer.shouldIgnore(currentToken)) {
|
|||
|
this.showDebugLog(() => "Don't show suggestions because currentToken should ignored");
|
|||
|
return null;
|
|||
|
}
|
|||
|
}
|
|||
|
this.showDebugLog(() => buildLogMessage("onTrigger", performance.now() - start));
|
|||
|
this.runManually = false;
|
|||
|
// Hack implementation for Front matter complement
|
|||
|
if (currentFrontMatter && ((_c = currentTokens.last()) === null || _c === void 0 ? void 0 : _c.word.match(/[^ ] $/))) {
|
|||
|
currentTokens.push({ word: "", offset: currentLineUntilCursor.length });
|
|||
|
}
|
|||
|
// For multi-word completion
|
|||
|
this.contextStartCh = cursor.ch - currentToken.length;
|
|||
|
return {
|
|||
|
start: {
|
|||
|
ch: cursor.ch - ((_f = (_e = (_d = currentTokens.last()) === null || _d === void 0 ? void 0 : _d.word) === null || _e === void 0 ? void 0 : _e.length) !== null && _f !== void 0 ? _f : 0),
|
|||
|
line: cursor.line,
|
|||
|
},
|
|||
|
end: cursor,
|
|||
|
query: JSON.stringify({
|
|||
|
currentFrontMatter,
|
|||
|
queries: currentTokens.map((x) => (Object.assign(Object.assign({}, x), { offset: x.offset - currentTokens[0].offset }))),
|
|||
|
}),
|
|||
|
};
|
|||
|
}
|
|||
|
getSuggestions(context) {
|
|||
|
return new Promise((resolve) => {
|
|||
|
this.debounceGetSuggestions(context, (words) => {
|
|||
|
resolve(words);
|
|||
|
});
|
|||
|
});
|
|||
|
}
|
|||
|
renderSuggestion(word, el) {
|
|||
|
const base = createDiv();
|
|||
|
let text = word.value;
|
|||
|
if (word.type === "customDictionary" &&
|
|||
|
word.insertedText &&
|
|||
|
this.settings.displayedTextSuffix) {
|
|||
|
text += this.settings.displayedTextSuffix;
|
|||
|
}
|
|||
|
base.createDiv({
|
|||
|
text,
|
|||
|
cls: word.type === "internalLink" && word.aliasMeta
|
|||
|
? "various-complements__suggestion-item__content__alias"
|
|||
|
: undefined,
|
|||
|
});
|
|||
|
const description = this.descriptionOnSuggestion.toDisplay(word);
|
|||
|
if (description) {
|
|||
|
base.createDiv({
|
|||
|
cls: "various-complements__suggestion-item__description",
|
|||
|
text: `${description}`,
|
|||
|
});
|
|||
|
}
|
|||
|
el.appendChild(base);
|
|||
|
el.addClass("various-complements__suggestion-item");
|
|||
|
switch (word.type) {
|
|||
|
case "currentFile":
|
|||
|
el.addClass("various-complements__suggestion-item__current-file");
|
|||
|
break;
|
|||
|
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");
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
selectSuggestion(word, evt) {
|
|||
|
var _a, _b;
|
|||
|
if (!this.context) {
|
|||
|
return;
|
|||
|
}
|
|||
|
let insertedText = word.value;
|
|||
|
if (word.type === "internalLink") {
|
|||
|
insertedText =
|
|||
|
this.settings.suggestInternalLinkWithAlias && word.aliasMeta
|
|||
|
? `[[${word.aliasMeta.origin}|${word.value}]]`
|
|||
|
: `[[${word.value}]]`;
|
|||
|
}
|
|||
|
if (word.type === "frontMatter" &&
|
|||
|
this.settings.insertCommaAfterFrontMatterCompletion) {
|
|||
|
insertedText = `${insertedText}, `;
|
|||
|
}
|
|||
|
else {
|
|||
|
if (this.settings.insertAfterCompletion &&
|
|||
|
!(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 = this.context.editor;
|
|||
|
editor.replaceRange(insertedText, Object.assign(Object.assign({}, this.context.start), { ch: this.contextStartCh + word.offset }), this.context.end);
|
|||
|
if (positionToMove !== -1) {
|
|||
|
editor.setCursor(editor.offsetToPos(editor.posToOffset(editor.getCursor()) -
|
|||
|
insertedText.length +
|
|||
|
positionToMove));
|
|||
|
}
|
|||
|
// The workaround of strange behavior for that cursor doesn't move after completion only if it doesn't input any word.
|
|||
|
if (this.appHelper.equalsAsEditorPostion(this.context.start, this.context.end)) {
|
|||
|
editor.setCursor(editor.offsetToPos(editor.posToOffset(editor.getCursor()) + insertedText.length));
|
|||
|
}
|
|||
|
(_a = this.selectionHistoryStorage) === null || _a === void 0 ? void 0 : _a.increment(word);
|
|||
|
if (this.settings.showLogAboutPerformanceInConsole) {
|
|||
|
console.log("--- history ---");
|
|||
|
console.log((_b = this.selectionHistoryStorage) === null || _b === void 0 ? void 0 : _b.data);
|
|||
|
}
|
|||
|
this.close();
|
|||
|
this.debounceClose();
|
|||
|
}
|
|||
|
showDebugLog(toMessage) {
|
|||
|
if (this.settings.showLogAboutPerformanceInConsole) {
|
|||
|
console.log(toMessage());
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
const DEFAULT_SETTINGS = {
|
|||
|
// general
|
|||
|
strategy: "default",
|
|||
|
matchStrategy: "prefix",
|
|||
|
maxNumberOfSuggestions: 5,
|
|||
|
maxNumberOfWordsAsPhrase: 3,
|
|||
|
minNumberOfCharactersTriggered: 0,
|
|||
|
minNumberOfWordsTriggeredPhrase: 1,
|
|||
|
complementAutomatically: true,
|
|||
|
delayMilliSeconds: 0,
|
|||
|
disableSuggestionsDuringImeOn: false,
|
|||
|
insertAfterCompletion: true,
|
|||
|
firstCharactersDisableSuggestions: ":/^",
|
|||
|
// appearance
|
|||
|
showMatchStrategy: true,
|
|||
|
showIndexingStatus: true,
|
|||
|
descriptionOnSuggestion: "Short",
|
|||
|
// key customization
|
|||
|
selectSuggestionKeys: "Enter",
|
|||
|
additionalCycleThroughSuggestionsKeys: "None",
|
|||
|
openSourceFileKey: "None",
|
|||
|
propagateEsc: false,
|
|||
|
// current file complement
|
|||
|
enableCurrentFileComplement: true,
|
|||
|
onlyComplementEnglishOnCurrentFileComplement: false,
|
|||
|
// current vault complement
|
|||
|
enableCurrentVaultComplement: false,
|
|||
|
includeCurrentVaultPathPrefixPatterns: "",
|
|||
|
excludeCurrentVaultPathPrefixPatterns: "",
|
|||
|
includeCurrentVaultOnlyFilesUnderCurrentDirectory: false,
|
|||
|
// 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,
|
|||
|
excludeInternalLinkPathPrefixPatterns: "",
|
|||
|
// front matter complement
|
|||
|
enableFrontMatterComplement: true,
|
|||
|
frontMatterComplementMatchStrategy: "inherit",
|
|||
|
insertCommaAfterFrontMatterCompletion: false,
|
|||
|
// debug
|
|||
|
showLogAboutPerformanceInConsole: false,
|
|||
|
// others
|
|||
|
selectionHistoryTree: {},
|
|||
|
};
|
|||
|
class VariousComplementsSettingTab extends obsidian.PluginSettingTab {
|
|||
|
constructor(app, plugin) {
|
|||
|
super(app, plugin);
|
|||
|
this.plugin = plugin;
|
|||
|
}
|
|||
|
display() {
|
|||
|
let { containerEl } = this;
|
|||
|
containerEl.empty();
|
|||
|
containerEl.createEl("h2", { text: "Various Complements - Settings" });
|
|||
|
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.addDebugSettings(containerEl);
|
|||
|
}
|
|||
|
addMainSettings(containerEl) {
|
|||
|
containerEl.createEl("h3", { text: "Main" });
|
|||
|
new obsidian.Setting(containerEl).setName("Strategy").addDropdown((tc) => tc
|
|||
|
.addOptions(mirrorMap(TokenizeStrategy.values(), (x) => x.name))
|
|||
|
.setValue(this.plugin.settings.strategy)
|
|||
|
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.strategy = value;
|
|||
|
yield this.plugin.saveSettings({
|
|||
|
currentFile: true,
|
|||
|
currentVault: true,
|
|||
|
});
|
|||
|
})));
|
|||
|
new obsidian.Setting(containerEl).setName("Match strategy").addDropdown((tc) => tc
|
|||
|
.addOptions(mirrorMap(MatchStrategy.values(), (x) => x.name))
|
|||
|
.setValue(this.plugin.settings.matchStrategy)
|
|||
|
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.matchStrategy = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
this.display();
|
|||
|
})));
|
|||
|
if (this.plugin.settings.matchStrategy === MatchStrategy.PARTIAL.name) {
|
|||
|
containerEl.createEl("div", {
|
|||
|
text: "⚠ `partial` is more than 10 times slower than `prefix`",
|
|||
|
cls: "various-complements__settings__warning",
|
|||
|
});
|
|||
|
}
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Max number of suggestions")
|
|||
|
.addSlider((sc) => sc
|
|||
|
.setLimits(1, 255, 1)
|
|||
|
.setValue(this.plugin.settings.maxNumberOfSuggestions)
|
|||
|
.setDynamicTooltip()
|
|||
|
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.maxNumberOfSuggestions = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
})));
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Max number of words as a phrase")
|
|||
|
.setDesc(`[⚠Warning] It makes slower more than N times (N is set value)`)
|
|||
|
.addSlider((sc) => sc
|
|||
|
.setLimits(1, 10, 1)
|
|||
|
.setValue(this.plugin.settings.maxNumberOfWordsAsPhrase)
|
|||
|
.setDynamicTooltip()
|
|||
|
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.maxNumberOfWordsAsPhrase = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
})));
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Min number of characters for trigger")
|
|||
|
.setDesc("It uses a default value of Strategy if set 0.")
|
|||
|
.addSlider((sc) => sc
|
|||
|
.setLimits(0, 10, 1)
|
|||
|
.setValue(this.plugin.settings.minNumberOfCharactersTriggered)
|
|||
|
.setDynamicTooltip()
|
|||
|
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.minNumberOfCharactersTriggered = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
})));
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Min number of words for trigger")
|
|||
|
.addSlider((sc) => sc
|
|||
|
.setLimits(1, 10, 1)
|
|||
|
.setValue(this.plugin.settings.minNumberOfWordsTriggeredPhrase)
|
|||
|
.setDynamicTooltip()
|
|||
|
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.minNumberOfWordsTriggeredPhrase = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
})));
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Complement automatically")
|
|||
|
.addToggle((tc) => {
|
|||
|
tc.setValue(this.plugin.settings.complementAutomatically).onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.complementAutomatically = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
}));
|
|||
|
});
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Delay milli-seconds for trigger")
|
|||
|
.addSlider((sc) => sc
|
|||
|
.setLimits(0, 1000, 10)
|
|||
|
.setValue(this.plugin.settings.delayMilliSeconds)
|
|||
|
.setDynamicTooltip()
|
|||
|
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.delayMilliSeconds = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
})));
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Disable suggestions during IME on")
|
|||
|
.addToggle((tc) => {
|
|||
|
tc.setValue(this.plugin.settings.disableSuggestionsDuringImeOn).onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.disableSuggestionsDuringImeOn = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
}));
|
|||
|
});
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Insert space after completion")
|
|||
|
.addToggle((tc) => {
|
|||
|
tc.setValue(this.plugin.settings.insertAfterCompletion).onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.insertAfterCompletion = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
}));
|
|||
|
});
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("First characters to disable suggestions")
|
|||
|
.addText((cb) => {
|
|||
|
cb.setValue(this.plugin.settings.firstCharactersDisableSuggestions).onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.firstCharactersDisableSuggestions = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
}));
|
|||
|
});
|
|||
|
}
|
|||
|
addAppearanceSettings(containerEl) {
|
|||
|
containerEl.createEl("h3", { text: "Appearance" });
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Show Match strategy")
|
|||
|
.setDesc("Show Match strategy at the status bar. Changing this option requires a restart to take effect.")
|
|||
|
.addToggle((tc) => {
|
|||
|
tc.setValue(this.plugin.settings.showMatchStrategy).onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.showMatchStrategy = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
}));
|
|||
|
});
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Show Indexing status")
|
|||
|
.setDesc("Show indexing status at the status bar. Changing this option requires a restart to take effect.")
|
|||
|
.addToggle((tc) => {
|
|||
|
tc.setValue(this.plugin.settings.showIndexingStatus).onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.showIndexingStatus = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
}));
|
|||
|
});
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Description on a suggestion")
|
|||
|
.addDropdown((tc) => tc
|
|||
|
.addOptions(mirrorMap(DescriptionOnSuggestion.values(), (x) => x.name))
|
|||
|
.setValue(this.plugin.settings.descriptionOnSuggestion)
|
|||
|
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.descriptionOnSuggestion = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
})));
|
|||
|
}
|
|||
|
addKeyCustomizationSettings(containerEl) {
|
|||
|
containerEl.createEl("h3", { text: "Key customization" });
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Select a suggestion key")
|
|||
|
.addDropdown((tc) => tc
|
|||
|
.addOptions(mirrorMap(SelectSuggestionKey.values(), (x) => x.name))
|
|||
|
.setValue(this.plugin.settings.selectSuggestionKeys)
|
|||
|
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.selectSuggestionKeys = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
})));
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Additional cycle through suggestions keys")
|
|||
|
.addDropdown((tc) => tc
|
|||
|
.addOptions(mirrorMap(CycleThroughSuggestionsKeys.values(), (x) => x.name))
|
|||
|
.setValue(this.plugin.settings.additionalCycleThroughSuggestionsKeys)
|
|||
|
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.additionalCycleThroughSuggestionsKeys = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
})));
|
|||
|
new obsidian.Setting(containerEl).setName("Open source file key").addDropdown((tc) => tc
|
|||
|
.addOptions(mirrorMap(OpenSourceFileKeys.values(), (x) => x.name))
|
|||
|
.setValue(this.plugin.settings.openSourceFileKey)
|
|||
|
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.openSourceFileKey = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
})));
|
|||
|
new obsidian.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((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.propagateEsc = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
}));
|
|||
|
});
|
|||
|
}
|
|||
|
addCurrentFileComplementSettings(containerEl) {
|
|||
|
containerEl.createEl("h3", {
|
|||
|
text: "Current file complement",
|
|||
|
cls: "various-complements__settings__header various-complements__settings__header__current-file",
|
|||
|
});
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Enable Current file complement")
|
|||
|
.addToggle((tc) => {
|
|||
|
tc.setValue(this.plugin.settings.enableCurrentFileComplement).onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.enableCurrentFileComplement = value;
|
|||
|
yield this.plugin.saveSettings({ currentFile: true });
|
|||
|
this.display();
|
|||
|
}));
|
|||
|
});
|
|||
|
if (this.plugin.settings.enableCurrentFileComplement) {
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Only complement English on current file complement")
|
|||
|
.addToggle((tc) => {
|
|||
|
tc.setValue(this.plugin.settings.onlyComplementEnglishOnCurrentFileComplement).onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.onlyComplementEnglishOnCurrentFileComplement =
|
|||
|
value;
|
|||
|
yield this.plugin.saveSettings({ currentFile: true });
|
|||
|
}));
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
addCurrentVaultComplementSettings(containerEl) {
|
|||
|
containerEl.createEl("h3", {
|
|||
|
text: "Current vault complement",
|
|||
|
cls: "various-complements__settings__header various-complements__settings__header__current-vault",
|
|||
|
});
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Enable Current vault complement")
|
|||
|
.addToggle((tc) => {
|
|||
|
tc.setValue(this.plugin.settings.enableCurrentVaultComplement).onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.enableCurrentVaultComplement = value;
|
|||
|
yield this.plugin.saveSettings({ currentVault: true });
|
|||
|
this.display();
|
|||
|
}));
|
|||
|
});
|
|||
|
if (this.plugin.settings.enableCurrentVaultComplement) {
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Include prefix path patterns")
|
|||
|
.setDesc("Prefix match path patterns to include files.")
|
|||
|
.addTextArea((tac) => {
|
|||
|
const el = tac
|
|||
|
.setValue(this.plugin.settings.includeCurrentVaultPathPrefixPatterns)
|
|||
|
.setPlaceholder("Private/")
|
|||
|
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.includeCurrentVaultPathPrefixPatterns =
|
|||
|
value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
}));
|
|||
|
el.inputEl.className =
|
|||
|
"various-complements__settings__text-area-path";
|
|||
|
return el;
|
|||
|
});
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Exclude prefix path patterns")
|
|||
|
.setDesc("Prefix match path patterns to exclude files.")
|
|||
|
.addTextArea((tac) => {
|
|||
|
const el = tac
|
|||
|
.setValue(this.plugin.settings.excludeCurrentVaultPathPrefixPatterns)
|
|||
|
.setPlaceholder("Private/")
|
|||
|
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.excludeCurrentVaultPathPrefixPatterns =
|
|||
|
value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
}));
|
|||
|
el.inputEl.className =
|
|||
|
"various-complements__settings__text-area-path";
|
|||
|
return el;
|
|||
|
});
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Include only files under current directory")
|
|||
|
.addToggle((tc) => {
|
|||
|
tc.setValue(this.plugin.settings
|
|||
|
.includeCurrentVaultOnlyFilesUnderCurrentDirectory).onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.includeCurrentVaultOnlyFilesUnderCurrentDirectory =
|
|||
|
value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
}));
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
addCustomDictionaryComplementSettings(containerEl) {
|
|||
|
containerEl.createEl("h3", {
|
|||
|
text: "Custom dictionary complement",
|
|||
|
cls: "various-complements__settings__header various-complements__settings__header__custom-dictionary",
|
|||
|
});
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Enable Custom dictionary complement")
|
|||
|
.addToggle((tc) => {
|
|||
|
tc.setValue(this.plugin.settings.enableCustomDictionaryComplement).onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.enableCustomDictionaryComplement = value;
|
|||
|
yield this.plugin.saveSettings({ customDictionary: true });
|
|||
|
this.display();
|
|||
|
}));
|
|||
|
});
|
|||
|
if (this.plugin.settings.enableCustomDictionaryComplement) {
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Custom dictionary paths")
|
|||
|
.setDesc("Specify either a relative path from Vault root or URL for each line.")
|
|||
|
.addTextArea((tac) => {
|
|||
|
const el = tac
|
|||
|
.setValue(this.plugin.settings.customDictionaryPaths)
|
|||
|
.setPlaceholder("dictionary.md")
|
|||
|
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.customDictionaryPaths = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
}));
|
|||
|
el.inputEl.className =
|
|||
|
"various-complements__settings__text-area-path";
|
|||
|
return el;
|
|||
|
});
|
|||
|
new obsidian.Setting(containerEl).setName("Column delimiter").addDropdown((tc) => tc
|
|||
|
.addOptions(mirrorMap(ColumnDelimiter.values(), (x) => x.name))
|
|||
|
.setValue(this.plugin.settings.columnDelimiter)
|
|||
|
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.columnDelimiter = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
})));
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Word regex pattern")
|
|||
|
.setDesc("Only load words that match the regular expression pattern.")
|
|||
|
.addText((cb) => {
|
|||
|
cb.setValue(this.plugin.settings.customDictionaryWordRegexPattern).onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.customDictionaryWordRegexPattern = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
}));
|
|||
|
});
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Delimiter to hide a suggestion")
|
|||
|
.setDesc("If set ';;;', 'abcd;;;efg' is shown as 'abcd' on suggestions, but completes to 'abcdefg'.")
|
|||
|
.addText((cb) => {
|
|||
|
cb.setValue(this.plugin.settings.delimiterToHideSuggestion).onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.delimiterToHideSuggestion = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
}));
|
|||
|
});
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Delimiter to divide suggestions for display from ones for insertion")
|
|||
|
.setDesc("If set ' >>> ', 'displayed >>> inserted' is shown as 'displayed' on suggestions, but completes to 'inserted'.")
|
|||
|
.addText((cb) => {
|
|||
|
cb.setValue(this.plugin.settings
|
|||
|
.delimiterToDivideSuggestionsForDisplayFromInsertion).onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.delimiterToDivideSuggestionsForDisplayFromInsertion =
|
|||
|
value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
}));
|
|||
|
});
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Caret location symbol after complement")
|
|||
|
.setDesc("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>`.")
|
|||
|
.addText((cb) => {
|
|||
|
cb.setValue(this.plugin.settings.caretLocationSymbolAfterComplement).onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.caretLocationSymbolAfterComplement = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
}));
|
|||
|
});
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Displayed text suffix")
|
|||
|
.setDesc("It shows as a suffix of displayed text if there is a difference between displayed and inserted")
|
|||
|
.addText((cb) => {
|
|||
|
cb.setValue(this.plugin.settings.displayedTextSuffix).onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.displayedTextSuffix = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
}));
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
addInternalLinkComplementSettings(containerEl) {
|
|||
|
containerEl.createEl("h3", {
|
|||
|
text: "Internal link complement",
|
|||
|
cls: "various-complements__settings__header various-complements__settings__header__internal-link",
|
|||
|
});
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Enable Internal link complement")
|
|||
|
.addToggle((tc) => {
|
|||
|
tc.setValue(this.plugin.settings.enableInternalLinkComplement).onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.enableInternalLinkComplement = value;
|
|||
|
yield this.plugin.saveSettings({ internalLink: true });
|
|||
|
this.display();
|
|||
|
}));
|
|||
|
});
|
|||
|
if (this.plugin.settings.enableInternalLinkComplement) {
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Suggest with an alias")
|
|||
|
.addToggle((tc) => {
|
|||
|
tc.setValue(this.plugin.settings.suggestInternalLinkWithAlias).onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.suggestInternalLinkWithAlias = value;
|
|||
|
yield this.plugin.saveSettings({ internalLink: true });
|
|||
|
}));
|
|||
|
});
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Exclude prefix path patterns")
|
|||
|
.setDesc("Prefix match path patterns to exclude files.")
|
|||
|
.addTextArea((tac) => {
|
|||
|
const el = tac
|
|||
|
.setValue(this.plugin.settings.excludeInternalLinkPathPrefixPatterns)
|
|||
|
.setPlaceholder("Private/")
|
|||
|
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.excludeInternalLinkPathPrefixPatterns =
|
|||
|
value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
}));
|
|||
|
el.inputEl.className =
|
|||
|
"various-complements__settings__text-area-path";
|
|||
|
return el;
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
addFrontMatterComplementSettings(containerEl) {
|
|||
|
containerEl.createEl("h3", {
|
|||
|
text: "Front matter complement",
|
|||
|
cls: "various-complements__settings__header various-complements__settings__header__front-matter",
|
|||
|
});
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Enable Front matter complement")
|
|||
|
.addToggle((tc) => {
|
|||
|
tc.setValue(this.plugin.settings.enableFrontMatterComplement).onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.enableFrontMatterComplement = value;
|
|||
|
yield this.plugin.saveSettings({ frontMatter: true });
|
|||
|
this.display();
|
|||
|
}));
|
|||
|
});
|
|||
|
if (this.plugin.settings.enableFrontMatterComplement) {
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Match strategy in the front matter")
|
|||
|
.addDropdown((tc) => tc
|
|||
|
.addOptions(mirrorMap(SpecificMatchStrategy.values(), (x) => x.name))
|
|||
|
.setValue(this.plugin.settings.frontMatterComplementMatchStrategy)
|
|||
|
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.frontMatterComplementMatchStrategy = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
})));
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Insert comma after completion")
|
|||
|
.addToggle((tc) => {
|
|||
|
tc.setValue(this.plugin.settings.insertCommaAfterFrontMatterCompletion).onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.insertCommaAfterFrontMatterCompletion = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
}));
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
addDebugSettings(containerEl) {
|
|||
|
containerEl.createEl("h3", { text: "Debug" });
|
|||
|
new obsidian.Setting(containerEl)
|
|||
|
.setName("Show log about performance in a console")
|
|||
|
.addToggle((tc) => {
|
|||
|
tc.setValue(this.plugin.settings.showLogAboutPerformanceInConsole).onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.showLogAboutPerformanceInConsole = value;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
}));
|
|||
|
});
|
|||
|
}
|
|||
|
toggleMatchStrategy() {
|
|||
|
return __awaiter(this, void 0, void 0, function* () {
|
|||
|
switch (this.plugin.settings.matchStrategy) {
|
|||
|
case "prefix":
|
|||
|
this.plugin.settings.matchStrategy = "partial";
|
|||
|
break;
|
|||
|
case "partial":
|
|||
|
this.plugin.settings.matchStrategy = "prefix";
|
|||
|
break;
|
|||
|
default:
|
|||
|
// noinspection ObjectAllocationIgnored
|
|||
|
new obsidian.Notice("⚠Unexpected error");
|
|||
|
}
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
});
|
|||
|
}
|
|||
|
toggleComplementAutomatically() {
|
|||
|
return __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.plugin.settings.complementAutomatically =
|
|||
|
!this.plugin.settings.complementAutomatically;
|
|||
|
yield this.plugin.saveSettings();
|
|||
|
});
|
|||
|
}
|
|||
|
ensureCustomDictionaryPath(path, state) {
|
|||
|
return __awaiter(this, void 0, void 0, function* () {
|
|||
|
const paths = this.plugin.settings.customDictionaryPaths.split("\n");
|
|||
|
const exists = paths.some((x) => x === path);
|
|||
|
if ((exists && state === "present") || (!exists && state === "absent")) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
const newPaths = state === "present" ? [...paths, path] : paths.filter((x) => x !== path);
|
|||
|
this.plugin.settings.customDictionaryPaths = newPaths.join("\n");
|
|||
|
yield this.plugin.saveSettings({ customDictionary: true });
|
|||
|
return true;
|
|||
|
});
|
|||
|
}
|
|||
|
getPluginSettingsAsJsonString() {
|
|||
|
return JSON.stringify({
|
|||
|
version: this.plugin.manifest.version,
|
|||
|
mobile: this.app.isMobile,
|
|||
|
settings: Object.assign(Object.assign({}, this.plugin.settings), { selectionHistoryTree: null }),
|
|||
|
}, null, 4);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
class ProviderStatusBar {
|
|||
|
constructor(currentFile, currentVault, customDictionary, internalLink, frontMatter, matchStrategy) {
|
|||
|
this.currentFile = currentFile;
|
|||
|
this.currentVault = currentVault;
|
|||
|
this.customDictionary = customDictionary;
|
|||
|
this.internalLink = internalLink;
|
|||
|
this.frontMatter = frontMatter;
|
|||
|
this.matchStrategy = matchStrategy;
|
|||
|
}
|
|||
|
static new(statusBar, showMatchStrategy, showIndexingStatus) {
|
|||
|
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;
|
|||
|
return new ProviderStatusBar(currentFile, currentVault, customDictionary, internalLink, frontMatter, matchStrategy);
|
|||
|
}
|
|||
|
setOnClickStrategyListener(listener) {
|
|||
|
var _a;
|
|||
|
(_a = this.matchStrategy) === null || _a === void 0 ? void 0 : _a.addEventListener("click", listener);
|
|||
|
}
|
|||
|
setCurrentFileDisabled() {
|
|||
|
var _a;
|
|||
|
(_a = this.currentFile) === null || _a === void 0 ? void 0 : _a.setText("---");
|
|||
|
}
|
|||
|
setCurrentVaultDisabled() {
|
|||
|
var _a;
|
|||
|
(_a = this.currentVault) === null || _a === void 0 ? void 0 : _a.setText("---");
|
|||
|
}
|
|||
|
setCustomDictionaryDisabled() {
|
|||
|
var _a;
|
|||
|
(_a = this.customDictionary) === null || _a === void 0 ? void 0 : _a.setText("---");
|
|||
|
}
|
|||
|
setInternalLinkDisabled() {
|
|||
|
var _a;
|
|||
|
(_a = this.internalLink) === null || _a === void 0 ? void 0 : _a.setText("---");
|
|||
|
}
|
|||
|
setFrontMatterDisabled() {
|
|||
|
var _a;
|
|||
|
(_a = this.frontMatter) === null || _a === void 0 ? void 0 : _a.setText("---");
|
|||
|
}
|
|||
|
setCurrentFileIndexing() {
|
|||
|
var _a;
|
|||
|
(_a = this.currentFile) === null || _a === void 0 ? void 0 : _a.setText("indexing...");
|
|||
|
}
|
|||
|
setCurrentVaultIndexing() {
|
|||
|
var _a;
|
|||
|
(_a = this.currentVault) === null || _a === void 0 ? void 0 : _a.setText("indexing...");
|
|||
|
}
|
|||
|
setCustomDictionaryIndexing() {
|
|||
|
var _a;
|
|||
|
(_a = this.customDictionary) === null || _a === void 0 ? void 0 : _a.setText("indexing...");
|
|||
|
}
|
|||
|
setInternalLinkIndexing() {
|
|||
|
var _a;
|
|||
|
(_a = this.internalLink) === null || _a === void 0 ? void 0 : _a.setText("indexing...");
|
|||
|
}
|
|||
|
setFrontMatterIndexing() {
|
|||
|
var _a;
|
|||
|
(_a = this.frontMatter) === null || _a === void 0 ? void 0 : _a.setText("indexing...");
|
|||
|
}
|
|||
|
setCurrentFileIndexed(count) {
|
|||
|
var _a;
|
|||
|
(_a = this.currentFile) === null || _a === void 0 ? void 0 : _a.setText(String(count));
|
|||
|
}
|
|||
|
setCurrentVaultIndexed(count) {
|
|||
|
var _a;
|
|||
|
(_a = this.currentVault) === null || _a === void 0 ? void 0 : _a.setText(String(count));
|
|||
|
}
|
|||
|
setCustomDictionaryIndexed(count) {
|
|||
|
var _a;
|
|||
|
(_a = this.customDictionary) === null || _a === void 0 ? void 0 : _a.setText(String(count));
|
|||
|
}
|
|||
|
setInternalLinkIndexed(count) {
|
|||
|
var _a;
|
|||
|
(_a = this.internalLink) === null || _a === void 0 ? void 0 : _a.setText(String(count));
|
|||
|
}
|
|||
|
setFrontMatterIndexed(count) {
|
|||
|
var _a;
|
|||
|
(_a = this.frontMatter) === null || _a === void 0 ? void 0 : _a.setText(String(count));
|
|||
|
}
|
|||
|
setMatchStrategy(strategy) {
|
|||
|
var _a;
|
|||
|
(_a = this.matchStrategy) === null || _a === void 0 ? void 0 : _a.setText(strategy.name);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function noop() { }
|
|||
|
function assign(tar, src) {
|
|||
|
// @ts-ignore
|
|||
|
for (const k in src)
|
|||
|
tar[k] = src[k];
|
|||
|
return tar;
|
|||
|
}
|
|||
|
function run(fn) {
|
|||
|
return fn();
|
|||
|
}
|
|||
|
function blank_object() {
|
|||
|
return 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 === undefined) {
|
|||
|
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 = {};
|
|||
|
for (const k in props)
|
|||
|
if (k[0] !== '$')
|
|||
|
result[k] = props[k];
|
|||
|
return result;
|
|||
|
}
|
|||
|
function compute_rest_props(props, keys) {
|
|||
|
const rest = {};
|
|||
|
keys = new Set(keys);
|
|||
|
for (const k in props)
|
|||
|
if (!keys.has(k) && k[0] !== '$')
|
|||
|
rest[k] = props[k];
|
|||
|
return rest;
|
|||
|
}
|
|||
|
function null_to_empty(value) {
|
|||
|
return value == null ? '' : value;
|
|||
|
}
|
|||
|
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) {
|
|||
|
if (!node)
|
|||
|
return document;
|
|||
|
const root = node.getRootNode ? node.getRootNode() : node.ownerDocument;
|
|||
|
if (root && root.host) {
|
|||
|
return root;
|
|||
|
}
|
|||
|
return node.ownerDocument;
|
|||
|
}
|
|||
|
function append_stylesheet(node, style) {
|
|||
|
append(node.head || node, style);
|
|||
|
}
|
|||
|
function insert(target, node, anchor) {
|
|||
|
target.insertBefore(node, anchor || null);
|
|||
|
}
|
|||
|
function detach(node) {
|
|||
|
node.parentNode.removeChild(node);
|
|||
|
}
|
|||
|
function destroy_each(iterations, detaching) {
|
|||
|
for (let i = 0; i < iterations.length; i += 1) {
|
|||
|
if (iterations[i])
|
|||
|
iterations[i].d(detaching);
|
|||
|
}
|
|||
|
}
|
|||
|
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) {
|
|||
|
if (value == null)
|
|||
|
node.removeAttribute(attribute);
|
|||
|
else if (node.getAttribute(attribute) !== value)
|
|||
|
node.setAttribute(attribute, value);
|
|||
|
}
|
|||
|
function set_svg_attributes(node, attributes) {
|
|||
|
for (const key in attributes) {
|
|||
|
attr(node, key, attributes[key]);
|
|||
|
}
|
|||
|
}
|
|||
|
function children(element) {
|
|||
|
return Array.from(element.childNodes);
|
|||
|
}
|
|||
|
function set_data(text, data) {
|
|||
|
data = '' + data;
|
|||
|
if (text.wholeText !== data)
|
|||
|
text.data = 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(select, value) {
|
|||
|
for (let i = 0; i < select.options.length; i += 1) {
|
|||
|
const option = select.options[i];
|
|||
|
if (option.__value === value) {
|
|||
|
option.selected = true;
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
select.selectedIndex = -1; // no option should be selected
|
|||
|
}
|
|||
|
function select_value(select) {
|
|||
|
const selected_option = select.querySelector(':checked') || select.options[0];
|
|||
|
return selected_option && selected_option.__value;
|
|||
|
}
|
|||
|
function toggle_class(element, name, toggle) {
|
|||
|
element.classList[toggle ? 'add' : 'remove'](name);
|
|||
|
}
|
|||
|
function custom_event(type, detail, { bubbles = false, cancelable = false } = {}) {
|
|||
|
const e = document.createEvent('CustomEvent');
|
|||
|
e.initCustomEvent(type, bubbles, cancelable, detail);
|
|||
|
return e;
|
|||
|
}
|
|||
|
|
|||
|
let current_component;
|
|||
|
function set_current_component(component) {
|
|||
|
current_component = component;
|
|||
|
}
|
|||
|
function get_current_component() {
|
|||
|
if (!current_component)
|
|||
|
throw new Error('Function called outside component initialization');
|
|||
|
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) {
|
|||
|
// TODO are there situations where events could be dispatched
|
|||
|
// in a server (non-DOM) environment?
|
|||
|
const event = custom_event(type, detail, { cancelable });
|
|||
|
callbacks.slice().forEach(fn => {
|
|||
|
fn.call(component, event);
|
|||
|
});
|
|||
|
return !event.defaultPrevented;
|
|||
|
}
|
|||
|
return true;
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
const dirty_components = [];
|
|||
|
const binding_callbacks = [];
|
|||
|
const render_callbacks = [];
|
|||
|
const flush_callbacks = [];
|
|||
|
const resolved_promise = Promise.resolve();
|
|||
|
let 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);
|
|||
|
}
|
|||
|
// flush() calls callbacks in this order:
|
|||
|
// 1. All beforeUpdate callbacks, in order: parents before children
|
|||
|
// 2. All bind:this callbacks, in reverse order: children before parents.
|
|||
|
// 3. All afterUpdate callbacks, in order: parents before children. EXCEPT
|
|||
|
// for afterUpdates called during the initial onMount, which are called in
|
|||
|
// reverse order: children before parents.
|
|||
|
// Since callbacks might update component values, which could trigger another
|
|||
|
// call to flush(), the following steps guard against this:
|
|||
|
// 1. During beforeUpdate, any updated components will be added to the
|
|||
|
// dirty_components array and will cause a reentrant call to flush(). Because
|
|||
|
// the flush index is kept outside the function, the reentrant call will pick
|
|||
|
// up where the earlier call left off and go through all dirty components. The
|
|||
|
// current_component value is saved and restored so that the reentrant call will
|
|||
|
// not interfere with the "parent" flush() call.
|
|||
|
// 2. bind:this callbacks cannot trigger new flush() calls.
|
|||
|
// 3. During afterUpdate, any updated components will NOT have their afterUpdate
|
|||
|
// callback called a second time; the seen_callbacks set, outside the flush()
|
|||
|
// function, guarantees this behavior.
|
|||
|
const seen_callbacks = new Set();
|
|||
|
let flushidx = 0; // Do *not* move this inside the flush() function
|
|||
|
function flush() {
|
|||
|
const saved_component = current_component;
|
|||
|
do {
|
|||
|
// first, call beforeUpdate functions
|
|||
|
// and update components
|
|||
|
while (flushidx < dirty_components.length) {
|
|||
|
const component = dirty_components[flushidx];
|
|||
|
flushidx++;
|
|||
|
set_current_component(component);
|
|||
|
update(component.$$);
|
|||
|
}
|
|||
|
set_current_component(null);
|
|||
|
dirty_components.length = 0;
|
|||
|
flushidx = 0;
|
|||
|
while (binding_callbacks.length)
|
|||
|
binding_callbacks.pop()();
|
|||
|
// then, once components are updated, call
|
|||
|
// afterUpdate functions. This may cause
|
|||
|
// subsequent updates...
|
|||
|
for (let i = 0; i < render_callbacks.length; i += 1) {
|
|||
|
const callback = render_callbacks[i];
|
|||
|
if (!seen_callbacks.has(callback)) {
|
|||
|
// ...so guard against infinite loops
|
|||
|
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);
|
|||
|
}
|
|||
|
}
|
|||
|
const outroing = new Set();
|
|||
|
let outros;
|
|||
|
function transition_in(block, local) {
|
|||
|
if (block && block.i) {
|
|||
|
outroing.delete(block);
|
|||
|
block.i(local);
|
|||
|
}
|
|||
|
}
|
|||
|
function transition_out(block, local, detach, callback) {
|
|||
|
if (block && block.o) {
|
|||
|
if (outroing.has(block))
|
|||
|
return;
|
|||
|
outroing.add(block);
|
|||
|
outros.c.push(() => {
|
|||
|
outroing.delete(block);
|
|||
|
if (callback) {
|
|||
|
if (detach)
|
|||
|
block.d(1);
|
|||
|
callback();
|
|||
|
}
|
|||
|
});
|
|||
|
block.o(local);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function get_spread_update(levels, updates) {
|
|||
|
const update = {};
|
|||
|
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) {
|
|||
|
if (!(key in n))
|
|||
|
to_null_out[key] = 1;
|
|||
|
}
|
|||
|
for (const key in n) {
|
|||
|
if (!accounted_for[key]) {
|
|||
|
update[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) {
|
|||
|
if (!(key in update))
|
|||
|
update[key] = undefined;
|
|||
|
}
|
|||
|
return update;
|
|||
|
}
|
|||
|
function create_component(block) {
|
|||
|
block && block.c();
|
|||
|
}
|
|||
|
function mount_component(component, target, anchor, customElement) {
|
|||
|
const { fragment, on_mount, on_destroy, after_update } = component.$$;
|
|||
|
fragment && fragment.m(target, anchor);
|
|||
|
if (!customElement) {
|
|||
|
// onMount happens before the initial afterUpdate
|
|||
|
add_render_callback(() => {
|
|||
|
const new_on_destroy = on_mount.map(run).filter(is_function);
|
|||
|
if (on_destroy) {
|
|||
|
on_destroy.push(...new_on_destroy);
|
|||
|
}
|
|||
|
else {
|
|||
|
// Edge case - component was destroyed immediately,
|
|||
|
// most likely as a result of a binding initialising
|
|||
|
run_all(new_on_destroy);
|
|||
|
}
|
|||
|
component.$$.on_mount = [];
|
|||
|
});
|
|||
|
}
|
|||
|
after_update.forEach(add_render_callback);
|
|||
|
}
|
|||
|
function destroy_component(component, detaching) {
|
|||
|
const $$ = component.$$;
|
|||
|
if ($$.fragment !== null) {
|
|||
|
run_all($$.on_destroy);
|
|||
|
$$.fragment && $$.fragment.d(detaching);
|
|||
|
// TODO null out other refs, including component.$$ (but need to
|
|||
|
// preserve final state?)
|
|||
|
$$.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, instance, create_fragment, not_equal, props, append_styles, dirty = [-1]) {
|
|||
|
const parent_component = current_component;
|
|||
|
set_current_component(component);
|
|||
|
const $$ = component.$$ = {
|
|||
|
fragment: null,
|
|||
|
ctx: null,
|
|||
|
// 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_styles && append_styles($$.root);
|
|||
|
let ready = false;
|
|||
|
$$.ctx = instance
|
|||
|
? instance(component, options.props || {}, (i, ret, ...rest) => {
|
|||
|
const value = rest.length ? rest[0] : ret;
|
|||
|
if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) {
|
|||
|
if (!$$.skip_bound && $$.bound[i])
|
|||
|
$$.bound[i](value);
|
|||
|
if (ready)
|
|||
|
make_dirty(component, i);
|
|||
|
}
|
|||
|
return ret;
|
|||
|
})
|
|||
|
: [];
|
|||
|
$$.update();
|
|||
|
ready = true;
|
|||
|
run_all($$.before_update);
|
|||
|
// `false` as a special case of no DOM component
|
|||
|
$$.fragment = create_fragment ? create_fragment($$.ctx) : false;
|
|||
|
if (options.target) {
|
|||
|
if (options.hydrate) {
|
|||
|
const nodes = children(options.target);
|
|||
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|||
|
$$.fragment && $$.fragment.l(nodes);
|
|||
|
nodes.forEach(detach);
|
|||
|
}
|
|||
|
else {
|
|||
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|||
|
$$.fragment && $$.fragment.c();
|
|||
|
}
|
|||
|
if (options.intro)
|
|||
|
transition_in(component.$$.fragment);
|
|||
|
mount_component(component, options.target, options.anchor, options.customElement);
|
|||
|
flush();
|
|||
|
}
|
|||
|
set_current_component(parent_component);
|
|||
|
}
|
|||
|
/**
|
|||
|
* Base class for Svelte components. Used when dev=false.
|
|||
|
*/
|
|||
|
class SvelteComponent {
|
|||
|
$destroy() {
|
|||
|
destroy_component(this, 1);
|
|||
|
this.$destroy = noop;
|
|||
|
}
|
|||
|
$on(type, callback) {
|
|||
|
const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));
|
|||
|
callbacks.push(callback);
|
|||
|
return () => {
|
|||
|
const index = callbacks.indexOf(callback);
|
|||
|
if (index !== -1)
|
|||
|
callbacks.splice(index, 1);
|
|||
|
};
|
|||
|
}
|
|||
|
$set($$props) {
|
|||
|
if (this.$$set && !is_empty($$props)) {
|
|||
|
this.$$.skip_bound = true;
|
|||
|
this.$$set($$props);
|
|||
|
this.$$.skip_bound = false;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* src/ui/component/ObsidianButton.svelte generated by Svelte v3.48.0 */
|
|||
|
|
|||
|
function create_fragment$3(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");
|
|||
|
if (default_slot) default_slot.c();
|
|||
|
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(ctx, [dirty]) {
|
|||
|
if (default_slot) {
|
|||
|
if (default_slot.p && (!current || dirty & /*$$scope*/ 8)) {
|
|||
|
update_slot_base(
|
|||
|
default_slot,
|
|||
|
default_slot_template,
|
|||
|
ctx,
|
|||
|
/*$$scope*/ ctx[3],
|
|||
|
!current
|
|||
|
? get_all_dirty_from_scope(/*$$scope*/ ctx[3])
|
|||
|
: get_slot_changes(default_slot_template, /*$$scope*/ ctx[3], dirty, null),
|
|||
|
null
|
|||
|
);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (!current || dirty & /*popup*/ 1) {
|
|||
|
attr(button, "aria-label", /*popup*/ ctx[0]);
|
|||
|
}
|
|||
|
|
|||
|
if (!current || dirty & /*disabled*/ 2) {
|
|||
|
button.disabled = /*disabled*/ ctx[1];
|
|||
|
}
|
|||
|
|
|||
|
if (dirty & /*disabled*/ 2) {
|
|||
|
toggle_class(button, "mod-cta", !/*disabled*/ ctx[1]);
|
|||
|
}
|
|||
|
},
|
|||
|
i(local) {
|
|||
|
if (current) return;
|
|||
|
transition_in(default_slot, local);
|
|||
|
current = true;
|
|||
|
},
|
|||
|
o(local) {
|
|||
|
transition_out(default_slot, local);
|
|||
|
current = false;
|
|||
|
},
|
|||
|
d(detaching) {
|
|||
|
if (detaching) detach(button);
|
|||
|
if (default_slot) default_slot.d(detaching);
|
|||
|
mounted = false;
|
|||
|
dispose();
|
|||
|
}
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
function instance$3($$self, $$props, $$invalidate) {
|
|||
|
let { $$slots: slots = {}, $$scope } = $$props;
|
|||
|
let { popup } = $$props;
|
|||
|
let { disabled = false } = $$props;
|
|||
|
const dispatcher = createEventDispatcher();
|
|||
|
|
|||
|
const handleClick = () => {
|
|||
|
dispatcher("click");
|
|||
|
};
|
|||
|
|
|||
|
$$self.$$set = $$props => {
|
|||
|
if ('popup' in $$props) $$invalidate(0, popup = $$props.popup);
|
|||
|
if ('disabled' in $$props) $$invalidate(1, disabled = $$props.disabled);
|
|||
|
if ('$$scope' in $$props) $$invalidate(3, $$scope = $$props.$$scope);
|
|||
|
};
|
|||
|
|
|||
|
return [popup, disabled, handleClick, $$scope, slots];
|
|||
|
}
|
|||
|
|
|||
|
class ObsidianButton extends SvelteComponent {
|
|||
|
constructor(options) {
|
|||
|
super();
|
|||
|
init(this, options, instance$3, create_fragment$3, safe_not_equal, { popup: 0, disabled: 1 });
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* node_modules/svelte-lucide-icons/icons/File.svelte generated by Svelte v3.48.0 */
|
|||
|
|
|||
|
function create_fragment$2(ctx) {
|
|||
|
let svg;
|
|||
|
let path;
|
|||
|
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");
|
|||
|
if (default_slot) default_slot.c();
|
|||
|
path = svg_element("path");
|
|||
|
polyline = svg_element("polyline");
|
|||
|
attr(path, "d", "M14.5 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V7.5L14.5 2z");
|
|||
|
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);
|
|||
|
}
|
|||
|
|
|||
|
append(svg, path);
|
|||
|
append(svg, polyline);
|
|||
|
current = true;
|
|||
|
},
|
|||
|
p(ctx, [dirty]) {
|
|||
|
if (default_slot) {
|
|||
|
if (default_slot.p && (!current || dirty & /*$$scope*/ 4)) {
|
|||
|
update_slot_base(
|
|||
|
default_slot,
|
|||
|
default_slot_template,
|
|||
|
ctx,
|
|||
|
/*$$scope*/ ctx[2],
|
|||
|
!current
|
|||
|
? get_all_dirty_from_scope(/*$$scope*/ ctx[2])
|
|||
|
: get_slot_changes(default_slot_template, /*$$scope*/ ctx[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*/ ctx[0] },
|
|||
|
(!current || dirty & /*size*/ 1) && { height: /*size*/ ctx[0] },
|
|||
|
{ viewBox: "0 0 24 24" },
|
|||
|
{ fill: "none" },
|
|||
|
{ stroke: "currentColor" },
|
|||
|
{ "stroke-width": "2" },
|
|||
|
{ "stroke-linecap": "round" },
|
|||
|
{ "stroke-linejoin": "round" },
|
|||
|
dirty & /*$$restProps*/ 2 && /*$$restProps*/ ctx[1]
|
|||
|
]));
|
|||
|
},
|
|||
|
i(local) {
|
|||
|
if (current) return;
|
|||
|
transition_in(default_slot, local);
|
|||
|
current = true;
|
|||
|
},
|
|||
|
o(local) {
|
|||
|
transition_out(default_slot, local);
|
|||
|
current = false;
|
|||
|
},
|
|||
|
d(detaching) {
|
|||
|
if (detaching) detach(svg);
|
|||
|
if (default_slot) default_slot.d(detaching);
|
|||
|
}
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
function instance$2($$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));
|
|||
|
if ('size' in $$new_props) $$invalidate(0, size = $$new_props.size);
|
|||
|
if ('$$scope' in $$new_props) $$invalidate(2, $$scope = $$new_props.$$scope);
|
|||
|
};
|
|||
|
|
|||
|
return [size, $$restProps, $$scope, slots];
|
|||
|
}
|
|||
|
|
|||
|
class File extends SvelteComponent {
|
|||
|
constructor(options) {
|
|||
|
super();
|
|||
|
init(this, options, instance$2, create_fragment$2, safe_not_equal, { size: 0 });
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* src/ui/component/ObsidianIconButton.svelte generated by Svelte v3.48.0 */
|
|||
|
|
|||
|
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_fragment$1(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");
|
|||
|
if (default_slot) default_slot.c();
|
|||
|
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(ctx, [dirty]) {
|
|||
|
if (default_slot) {
|
|||
|
if (default_slot.p && (!current || dirty & /*$$scope*/ 8)) {
|
|||
|
update_slot_base(
|
|||
|
default_slot,
|
|||
|
default_slot_template,
|
|||
|
ctx,
|
|||
|
/*$$scope*/ ctx[3],
|
|||
|
!current
|
|||
|
? get_all_dirty_from_scope(/*$$scope*/ ctx[3])
|
|||
|
: get_slot_changes(default_slot_template, /*$$scope*/ ctx[3], dirty, null),
|
|||
|
null
|
|||
|
);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (!current || dirty & /*popup*/ 1) {
|
|||
|
attr(button, "aria-label", /*popup*/ ctx[0]);
|
|||
|
}
|
|||
|
|
|||
|
if (!current || dirty & /*disabled*/ 2) {
|
|||
|
button.disabled = /*disabled*/ ctx[1];
|
|||
|
}
|
|||
|
|
|||
|
if (!current || dirty & /*disabled*/ 2 && button_class_value !== (button_class_value = "" + (null_to_empty(/*disabled*/ ctx[1]
|
|||
|
? "button-disabled"
|
|||
|
: "button-enabled") + " svelte-12yh6aw"))) {
|
|||
|
attr(button, "class", button_class_value);
|
|||
|
}
|
|||
|
},
|
|||
|
i(local) {
|
|||
|
if (current) return;
|
|||
|
transition_in(default_slot, local);
|
|||
|
current = true;
|
|||
|
},
|
|||
|
o(local) {
|
|||
|
transition_out(default_slot, local);
|
|||
|
current = false;
|
|||
|
},
|
|||
|
d(detaching) {
|
|||
|
if (detaching) detach(div);
|
|||
|
if (default_slot) default_slot.d(detaching);
|
|||
|
mounted = false;
|
|||
|
dispose();
|
|||
|
}
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
function instance$1($$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 = $$props => {
|
|||
|
if ('popup' in $$props) $$invalidate(0, popup = $$props.popup);
|
|||
|
if ('disabled' in $$props) $$invalidate(1, disabled = $$props.disabled);
|
|||
|
if ('$$scope' in $$props) $$invalidate(3, $$scope = $$props.$$scope);
|
|||
|
};
|
|||
|
|
|||
|
return [popup, disabled, handleClick, $$scope, slots];
|
|||
|
}
|
|||
|
|
|||
|
class ObsidianIconButton extends SvelteComponent {
|
|||
|
constructor(options) {
|
|||
|
super();
|
|||
|
init(this, options, instance$1, create_fragment$1, safe_not_equal, { popup: 0, disabled: 1 }, add_css);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* src/ui/component/CustomDictionaryWordAdd.svelte generated by Svelte v3.48.0 */
|
|||
|
|
|||
|
function get_each_context(ctx, list, i) {
|
|||
|
const child_ctx = ctx.slice();
|
|||
|
child_ctx[26] = list[i];
|
|||
|
return child_ctx;
|
|||
|
}
|
|||
|
|
|||
|
// (48:6) {#each dictionaries as dictionary}
|
|||
|
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];
|
|||
|
option.value = option.__value;
|
|||
|
},
|
|||
|
m(target, anchor) {
|
|||
|
insert(target, option, anchor);
|
|||
|
append(option, t0);
|
|||
|
append(option, t1);
|
|||
|
},
|
|||
|
p(ctx, dirty) {
|
|||
|
if (dirty & /*dictionaries*/ 32 && t0_value !== (t0_value = /*dictionary*/ ctx[26].path + "")) set_data(t0, t0_value);
|
|||
|
|
|||
|
if (dirty & /*dictionaries*/ 32 && option_value_value !== (option_value_value = /*dictionary*/ ctx[26])) {
|
|||
|
option.__value = option_value_value;
|
|||
|
option.value = option.__value;
|
|||
|
}
|
|||
|
},
|
|||
|
d(detaching) {
|
|||
|
if (detaching) detach(option);
|
|||
|
}
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
// (54:4) <ObsidianIconButton popup="Open the file" on:click={() => onClickFileIcon(selectedDictionary.path)} >
|
|||
|
function create_default_slot_1(ctx) {
|
|||
|
let file;
|
|||
|
let current;
|
|||
|
file = new File({});
|
|||
|
|
|||
|
return {
|
|||
|
c() {
|
|||
|
create_component(file.$$.fragment);
|
|||
|
},
|
|||
|
m(target, anchor) {
|
|||
|
mount_component(file, target, anchor);
|
|||
|
current = true;
|
|||
|
},
|
|||
|
i(local) {
|
|||
|
if (current) return;
|
|||
|
transition_in(file.$$.fragment, local);
|
|||
|
current = true;
|
|||
|
},
|
|||
|
o(local) {
|
|||
|
transition_out(file.$$.fragment, local);
|
|||
|
current = false;
|
|||
|
},
|
|||
|
d(detaching) {
|
|||
|
destroy_component(file, detaching);
|
|||
|
}
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
// (70:2) {#if enableDisplayedWord}
|
|||
|
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(ctx, dirty) {
|
|||
|
if (dirty & /*useDisplayedWord*/ 2) {
|
|||
|
input.checked = /*useDisplayedWord*/ ctx[1];
|
|||
|
}
|
|||
|
},
|
|||
|
d(detaching) {
|
|||
|
if (detaching) detach(label);
|
|||
|
mounted = false;
|
|||
|
dispose();
|
|||
|
}
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
// (77:2) {#if useDisplayedWord}
|
|||
|
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]);
|
|||
|
/*textarea_binding*/ ctx[23](textarea);
|
|||
|
|
|||
|
if (!mounted) {
|
|||
|
dispose = listen(textarea, "input", /*textarea_input_handler*/ ctx[22]);
|
|||
|
mounted = true;
|
|||
|
}
|
|||
|
},
|
|||
|
p(ctx, dirty) {
|
|||
|
if (dirty & /*displayedWord*/ 8) {
|
|||
|
set_input_value(textarea, /*displayedWord*/ ctx[3]);
|
|||
|
}
|
|||
|
},
|
|||
|
d(detaching) {
|
|||
|
if (detaching) detach(h3);
|
|||
|
if (detaching) detach(t1);
|
|||
|
if (detaching) detach(textarea);
|
|||
|
/*textarea_binding*/ ctx[23](null);
|
|||
|
mounted = false;
|
|||
|
dispose();
|
|||
|
}
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
// (94:4) <ObsidianButton disabled={!enableSubmit} on:click={handleSubmit} >
|
|||
|
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_fragment(ctx) {
|
|||
|
let div2;
|
|||
|
let h2;
|
|||
|
let t1;
|
|||
|
let h30;
|
|||
|
let t3;
|
|||
|
let div0;
|
|||
|
let select;
|
|||
|
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 = /*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({
|
|||
|
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({
|
|||
|
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");
|
|||
|
select = 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();
|
|||
|
if (if_block0) if_block0.c();
|
|||
|
t9 = space();
|
|||
|
if (if_block1) if_block1.c();
|
|||
|
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(select, "class", "dropdown");
|
|||
|
if (/*selectedDictionary*/ ctx[2] === void 0) add_render_callback(() => /*select_change_handler*/ ctx[17].call(select));
|
|||
|
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, select);
|
|||
|
|
|||
|
for (let i = 0; i < each_blocks.length; i += 1) {
|
|||
|
each_blocks[i].m(select, null);
|
|||
|
}
|
|||
|
|
|||
|
select_option(select, /*selectedDictionary*/ ctx[2]);
|
|||
|
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, /*word*/ ctx[0]);
|
|||
|
/*textarea0_binding*/ ctx[20](textarea0);
|
|||
|
append(div2, t8);
|
|||
|
if (if_block0) if_block0.m(div2, null);
|
|||
|
append(div2, t9);
|
|||
|
if (if_block1) if_block1.m(div2, null);
|
|||
|
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(select, "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(ctx, [dirty]) {
|
|||
|
if (dirty & /*dictionaries*/ 32) {
|
|||
|
each_value = /*dictionaries*/ ctx[5];
|
|||
|
let i;
|
|||
|
|
|||
|
for (i = 0; i < each_value.length; i += 1) {
|
|||
|
const child_ctx = get_each_context(ctx, 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(select, 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(select, /*selectedDictionary*/ ctx[2]);
|
|||
|
}
|
|||
|
|
|||
|
const obsidianiconbutton_changes = {};
|
|||
|
|
|||
|
if (dirty & /*$$scope*/ 536870912) {
|
|||
|
obsidianiconbutton_changes.$$scope = { dirty, ctx };
|
|||
|
}
|
|||
|
|
|||
|
obsidianiconbutton.$set(obsidianiconbutton_changes);
|
|||
|
if (!current || dirty & /*firstWordTitle*/ 1024) set_data(t6, /*firstWordTitle*/ ctx[10]);
|
|||
|
|
|||
|
if (dirty & /*word*/ 1) {
|
|||
|
set_input_value(textarea0, /*word*/ ctx[0]);
|
|||
|
}
|
|||
|
|
|||
|
if (/*enableDisplayedWord*/ ctx[11]) {
|
|||
|
if (if_block0) {
|
|||
|
if_block0.p(ctx, dirty);
|
|||
|
} else {
|
|||
|
if_block0 = create_if_block_1(ctx);
|
|||
|
if_block0.c();
|
|||
|
if_block0.m(div2, t9);
|
|||
|
}
|
|||
|
} else if (if_block0) {
|
|||
|
if_block0.d(1);
|
|||
|
if_block0 = null;
|
|||
|
}
|
|||
|
|
|||
|
if (/*useDisplayedWord*/ ctx[1]) {
|
|||
|
if (if_block1) {
|
|||
|
if_block1.p(ctx, dirty);
|
|||
|
} else {
|
|||
|
if_block1 = create_if_block(ctx);
|
|||
|
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*/ ctx[4]) {
|
|||
|
set_input_value(input, /*description*/ ctx[4]);
|
|||
|
}
|
|||
|
|
|||
|
if (dirty & /*aliasesStr*/ 256) {
|
|||
|
set_input_value(textarea1, /*aliasesStr*/ ctx[8]);
|
|||
|
}
|
|||
|
|
|||
|
const obsidianbutton_changes = {};
|
|||
|
if (dirty & /*enableSubmit*/ 4096) obsidianbutton_changes.disabled = !/*enableSubmit*/ ctx[12];
|
|||
|
|
|||
|
if (dirty & /*$$scope*/ 536870912) {
|
|||
|
obsidianbutton_changes.$$scope = { dirty, ctx };
|
|||
|
}
|
|||
|
|
|||
|
obsidianbutton.$set(obsidianbutton_changes);
|
|||
|
},
|
|||
|
i(local) {
|
|||
|
if (current) return;
|
|||
|
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);
|
|||
|
/*textarea0_binding*/ ctx[20](null);
|
|||
|
if (if_block0) if_block0.d();
|
|||
|
if (if_block1) if_block1.d();
|
|||
|
destroy_component(obsidianbutton);
|
|||
|
mounted = false;
|
|||
|
run_all(dispose);
|
|||
|
}
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
function instance($$self, $$props, $$invalidate) {
|
|||
|
let enableSubmit;
|
|||
|
let enableDisplayedWord;
|
|||
|
let firstWordTitle;
|
|||
|
let { dictionaries } = $$props;
|
|||
|
let { selectedDictionary } = $$props;
|
|||
|
let { word = "" } = $$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 || word,
|
|||
|
description,
|
|||
|
aliases: aliasesStr.split("\n"),
|
|||
|
type: "customDictionary",
|
|||
|
createdPath: selectedDictionary.path,
|
|||
|
insertedText: displayedWord ? word : undefined
|
|||
|
});
|
|||
|
};
|
|||
|
|
|||
|
onMount(() => {
|
|||
|
setTimeout(() => 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() {
|
|||
|
word = this.value;
|
|||
|
$$invalidate(0, word);
|
|||
|
}
|
|||
|
|
|||
|
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 = $$props => {
|
|||
|
if ('dictionaries' in $$props) $$invalidate(5, dictionaries = $$props.dictionaries);
|
|||
|
if ('selectedDictionary' in $$props) $$invalidate(2, selectedDictionary = $$props.selectedDictionary);
|
|||
|
if ('word' in $$props) $$invalidate(0, word = $$props.word);
|
|||
|
if ('useDisplayedWord' in $$props) $$invalidate(1, useDisplayedWord = $$props.useDisplayedWord);
|
|||
|
if ('displayedWord' in $$props) $$invalidate(3, displayedWord = $$props.displayedWord);
|
|||
|
if ('description' in $$props) $$invalidate(4, description = $$props.description);
|
|||
|
if ('aliases' in $$props) $$invalidate(14, aliases = $$props.aliases);
|
|||
|
if ('dividerForDisplay' in $$props) $$invalidate(15, dividerForDisplay = $$props.dividerForDisplay);
|
|||
|
if ('onSubmit' in $$props) $$invalidate(16, onSubmit = $$props.onSubmit);
|
|||
|
if ('onClickFileIcon' in $$props) $$invalidate(6, onClickFileIcon = $$props.onClickFileIcon);
|
|||
|
};
|
|||
|
|
|||
|
$$self.$$.update = () => {
|
|||
|
if ($$self.$$.dirty & /*word*/ 1) {
|
|||
|
$$invalidate(12, enableSubmit = word.length > 0);
|
|||
|
}
|
|||
|
|
|||
|
if ($$self.$$.dirty & /*dividerForDisplay*/ 32768) {
|
|||
|
$$invalidate(11, enableDisplayedWord = Boolean(dividerForDisplay));
|
|||
|
}
|
|||
|
|
|||
|
if ($$self.$$.dirty & /*useDisplayedWord*/ 2) {
|
|||
|
$$invalidate(10, firstWordTitle = useDisplayedWord ? "Inserted word" : "Word");
|
|||
|
}
|
|||
|
|
|||
|
if ($$self.$$.dirty & /*useDisplayedWord, displayedWordRef*/ 130) {
|
|||
|
{
|
|||
|
if (useDisplayedWord) {
|
|||
|
displayedWordRef === null || displayedWordRef === void 0
|
|||
|
? void 0
|
|||
|
: displayedWordRef.focus();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
return [
|
|||
|
word,
|
|||
|
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
|
|||
|
];
|
|||
|
}
|
|||
|
|
|||
|
class CustomDictionaryWordAdd extends SvelteComponent {
|
|||
|
constructor(options) {
|
|||
|
super();
|
|||
|
|
|||
|
init(this, options, instance, create_fragment, safe_not_equal, {
|
|||
|
dictionaries: 5,
|
|||
|
selectedDictionary: 2,
|
|||
|
word: 0,
|
|||
|
useDisplayedWord: 1,
|
|||
|
displayedWord: 3,
|
|||
|
description: 4,
|
|||
|
aliases: 14,
|
|||
|
dividerForDisplay: 15,
|
|||
|
onSubmit: 16,
|
|||
|
onClickFileIcon: 6
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
class CustomDictionaryWordAddModal extends obsidian.Modal {
|
|||
|
constructor(app, dictionaryPaths, initialValue = "", dividerForDisplay = "", onSubmit) {
|
|||
|
super(app);
|
|||
|
const appHelper = new AppHelper(app);
|
|||
|
const dictionaries = dictionaryPaths.map((x) => ({ id: x, path: x }));
|
|||
|
const { contentEl } = this;
|
|||
|
this.component = new CustomDictionaryWordAdd({
|
|||
|
target: contentEl,
|
|||
|
props: {
|
|||
|
dictionaries,
|
|||
|
selectedDictionary: dictionaries[0],
|
|||
|
word: initialValue,
|
|||
|
dividerForDisplay,
|
|||
|
onSubmit: onSubmit,
|
|||
|
onClickFileIcon: (dictionaryPath) => {
|
|||
|
const markdownFile = appHelper.getMarkdownFileByPath(dictionaryPath);
|
|||
|
if (!markdownFile) {
|
|||
|
// noinspection ObjectAllocationIgnored
|
|||
|
new obsidian.Notice(`Can't open ${dictionaryPath}`);
|
|||
|
return;
|
|||
|
}
|
|||
|
this.close();
|
|||
|
appHelper.openMarkdownFile(markdownFile, true);
|
|||
|
},
|
|||
|
},
|
|||
|
});
|
|||
|
}
|
|||
|
onClose() {
|
|||
|
super.onClose();
|
|||
|
this.component.$destroy();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
class VariousComponents extends obsidian.Plugin {
|
|||
|
onunload() {
|
|||
|
super.onunload();
|
|||
|
this.suggester.unregister();
|
|||
|
}
|
|||
|
onload() {
|
|||
|
return __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.appHelper = new AppHelper(this.app);
|
|||
|
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();
|
|||
|
}));
|
|||
|
}));
|
|||
|
yield this.loadSettings();
|
|||
|
this.settingTab = new VariousComplementsSettingTab(this.app, this);
|
|||
|
this.addSettingTab(this.settingTab);
|
|||
|
this.statusBar = ProviderStatusBar.new(this.addStatusBarItem(), this.settings.showMatchStrategy, this.settings.showIndexingStatus);
|
|||
|
this.statusBar.setOnClickStrategyListener(() => __awaiter(this, void 0, void 0, function* () {
|
|||
|
yield this.settingTab.toggleMatchStrategy();
|
|||
|
}));
|
|||
|
const debouncedSaveData = obsidian.debounce(() => __awaiter(this, void 0, void 0, function* () {
|
|||
|
yield this.saveData(this.settings);
|
|||
|
}), 5000);
|
|||
|
this.suggester = yield 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: () => __awaiter(this, void 0, void 0, function* () {
|
|||
|
yield this.suggester.refreshCustomDictionaryTokens();
|
|||
|
}),
|
|||
|
});
|
|||
|
this.addCommand({
|
|||
|
id: "reload-current-vault",
|
|||
|
name: "Reload current vault",
|
|||
|
callback: () => __awaiter(this, void 0, void 0, function* () {
|
|||
|
yield this.suggester.refreshCurrentVaultTokens();
|
|||
|
}),
|
|||
|
});
|
|||
|
this.addCommand({
|
|||
|
id: "toggle-match-strategy",
|
|||
|
name: "Toggle Match strategy",
|
|||
|
callback: () => __awaiter(this, void 0, void 0, function* () {
|
|||
|
yield this.settingTab.toggleMatchStrategy();
|
|||
|
}),
|
|||
|
});
|
|||
|
this.addCommand({
|
|||
|
id: "toggle-complement-automatically",
|
|||
|
name: "Toggle Complement automatically",
|
|||
|
callback: () => __awaiter(this, void 0, void 0, function* () {
|
|||
|
yield this.settingTab.toggleComplementAutomatically();
|
|||
|
}),
|
|||
|
});
|
|||
|
this.addCommand({
|
|||
|
id: "show-suggestions",
|
|||
|
name: "Show suggestions",
|
|||
|
hotkeys: [{ modifiers: ["Mod"], key: " " }],
|
|||
|
callback: () => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.suggester.triggerComplete();
|
|||
|
}),
|
|||
|
});
|
|||
|
this.addCommand({
|
|||
|
id: "add-word-custom-dictionary",
|
|||
|
name: "Add a word to a custom dictionary",
|
|||
|
hotkeys: [{ modifiers: ["Mod", "Shift"], key: " " }],
|
|||
|
callback: () => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.addWordToCustomDictionary();
|
|||
|
}),
|
|||
|
});
|
|||
|
this.addCommand({
|
|||
|
id: "predictable-complements",
|
|||
|
name: "Predictable complement",
|
|||
|
callback: () => __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.suggester.predictableComplete();
|
|||
|
}),
|
|||
|
});
|
|||
|
this.addCommand({
|
|||
|
id: "copy-plugin-settings",
|
|||
|
name: "Copy plugin settings",
|
|||
|
callback: () => __awaiter(this, void 0, void 0, function* () {
|
|||
|
yield navigator.clipboard.writeText(this.settingTab.getPluginSettingsAsJsonString());
|
|||
|
// noinspection ObjectAllocationIgnored
|
|||
|
new obsidian.Notice("Copy settings of Various Complements");
|
|||
|
}),
|
|||
|
});
|
|||
|
});
|
|||
|
}
|
|||
|
loadSettings() {
|
|||
|
return __awaiter(this, void 0, void 0, function* () {
|
|||
|
this.settings = Object.assign(Object.assign({}, DEFAULT_SETTINGS), (yield this.loadData()));
|
|||
|
});
|
|||
|
}
|
|||
|
saveSettings(needUpdateTokens = {}) {
|
|||
|
return __awaiter(this, void 0, void 0, function* () {
|
|||
|
yield this.saveData(this.settings);
|
|||
|
yield this.suggester.updateSettings(this.settings);
|
|||
|
if (needUpdateTokens.currentFile) {
|
|||
|
yield this.suggester.refreshCurrentFileTokens();
|
|||
|
}
|
|||
|
if (needUpdateTokens.currentVault) {
|
|||
|
yield this.suggester.refreshCurrentVaultTokens();
|
|||
|
}
|
|||
|
if (needUpdateTokens.customDictionary) {
|
|||
|
yield this.suggester.refreshCustomDictionaryTokens();
|
|||
|
}
|
|||
|
if (needUpdateTokens.internalLink) {
|
|||
|
yield this.suggester.refreshInternalLinkTokens();
|
|||
|
}
|
|||
|
if (needUpdateTokens.frontMatter) {
|
|||
|
yield this.suggester.refreshFrontMatterTokens();
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
addWordToCustomDictionary() {
|
|||
|
const selectedWord = this.appHelper.getSelection();
|
|||
|
const provider = this.suggester.customDictionaryWordProvider;
|
|||
|
const modal = new CustomDictionaryWordAddModal(this.app, provider.editablePaths, selectedWord, this.settings.delimiterToDivideSuggestionsForDisplayFromInsertion, (dictionaryPath, word) => __awaiter(this, void 0, void 0, function* () {
|
|||
|
if (provider.wordByValue[word.value]) {
|
|||
|
// noinspection ObjectAllocationIgnored
|
|||
|
new obsidian.Notice(`⚠ ${word.value} already exists`, 0);
|
|||
|
return;
|
|||
|
}
|
|||
|
yield provider.addWordWithDictionary(word, dictionaryPath);
|
|||
|
// noinspection ObjectAllocationIgnored
|
|||
|
new obsidian.Notice(`Added ${word.value}`);
|
|||
|
modal.close();
|
|||
|
}));
|
|||
|
modal.open();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
module.exports = VariousComponents;
|
|||
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsInNyYy91dGlsL3N0cmluZ3MudHMiLCJzcmMvdG9rZW5pemVyL3Rva2VuaXplcnMvRGVmYXVsdFRva2VuaXplci50cyIsInNyYy90b2tlbml6ZXIvdG9rZW5pemVycy9BcmFiaWNUb2tlbml6ZXIudHMiLCJzcmMvZXh0ZXJuYWwvdGlueS1zZWdtZW50ZXIudHMiLCJzcmMvdG9rZW5pemVyL3Rva2VuaXplcnMvSmFwYW5lc2VUb2tlbml6ZXIudHMiLCJzcmMvdG9rZW5pemVyL3Rva2VuaXplcnMvRW5nbGlzaE9ubHlUb2tlbml6ZXIudHMiLCJzcmMvdG9rZW5pemVyL3Rva2VuaXplci50cyIsInNyYy90b2tlbml6ZXIvVG9rZW5pemVTdHJhdGVneS50cyIsInNyYy9hcHAtaGVscGVyLnRzIiwic3JjL3V0aWwvY29sbGVjdGlvbi1oZWxwZXIudHMiLCJzcmMvbW9kZWwvV29yZC50cyIsInNyYy9wcm92aWRlci9zdWdnZXN0ZXIudHMiLCJzcmMvdXRpbC9wYXRoLnRzIiwic3JjL3Byb3ZpZGVyL0N1c3RvbURpY3Rpb25hcnlXb3JkUHJvdmlkZXIudHMiLCJzcmMvcHJvdmlkZXIvQ3VycmVudEZpbGVXb3JkUHJvdmlkZXIudHMiLCJzcmMvcHJvdmlkZXIvSW50ZXJuYWxMaW5rV29yZFByb3ZpZGVyLnRzIiwic3JjL3Byb3ZpZGVyL01hdGNoU3RyYXRlZ3kudHMiLCJzcmMvb3B0aW9uL0N5Y2xlVGhyb3VnaFN1Z2dlc3Rpb25zS2V5cy50cyIsInNyYy9vcHRpb24vQ29sdW1uRGVsaW1pdGVyLnRzIiwic3JjL29wdGlvbi9TZWxlY3RTdWdnZXN0aW9uS2V5LnRzIiwic3JjL3Byb3ZpZGVyL0N1cnJlbnRWYXVsdFdvcmRQcm92aWRlci50cyIsInNyYy9vcHRpb24vT3BlblNvdXJjZUZpbGVLZXlzLnRzIiwic3JjL29wdGlvbi9EZXNjcmlwdGlvbk9uU3VnZ2VzdGlvbi50cyIsInNyYy9wcm92aWRlci9Gcm9udE1hdHRlcldvcmRQcm92aWRlci50cyIsInNyYy9wcm92aWRlci9TcGVjaWZpY01hdGNoU3RyYXRlZ3kudHMiLCJzcmMvc3RvcmFnZS9TZWxlY3Rpb25IaXN0b3J5U3RvcmFnZS50cyIsInNyYy91aS9BdXRvQ29tcGxldGVTdWdnZXN0LnRzIiwic3JjL3NldHRpbmcvc2V0dGluZ3MudHMiLCJzcmMvdWkvUHJvdmlkZXJTdGF0dXNCYXIudHMiLCJub2RlX21vZHVsZXMvc3ZlbHRlL2ludGVybmFsL2luZGV4Lm1qcyIsInNyYy91aS9jb21wb25lbnQvT2JzaWRpYW5CdXR0b24uc3ZlbHRlIiwibm9kZV9tb2R1bGVzL3N2ZWx0ZS1sdWNpZGUtaWNvbnMvaWNvbnMvRmlsZS5zdmVsdGUiLCJzcmMvdWkvY29tcG9uZW50L09ic2lkaWFuSWNvbkJ1dHRvbi5zdmVsdGUiLCJzcmMvdWkvY29tcG9uZW50L0N1c3RvbURpY3Rpb25hcnlXb3JkQWRkLnN2ZWx0ZSIsInNyYy91aS9DdXN0b21EaWN0aW9uYXJ5V29yZEFkZE1vZGFsLnRzIiwic3JjL21haW4udHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi5cclxuXHJcblBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueVxyXG5wdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQuXHJcblxyXG5USEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIXHJcblJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWVxyXG5BTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXHJcbklORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTVxyXG5MT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUlxyXG5PVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXHJcblBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXHJcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcbi8qIGdsb2JhbCBSZWZsZWN0LCBQcm9taXNlICovXHJcblxyXG52YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXh0ZW5kcyhkLCBiKSB7XHJcbiAgICBpZiAodHlwZW9mIGIgIT09IFwiZnVuY3Rpb25cIiAmJiBiICE9PSBudWxsKVxyXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDbGFzcyBleHRlbmRzIHZhbHVlIFwiICsgU3RyaW5nKGIpICsgXCIgaXMgbm90IGEgY29uc3RydWN0b3Igb3IgbnVsbFwiKTtcclxuICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2F
|