@bobfrankston/rmfmail 1.0.676 → 1.0.678
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/TODO.md +11 -1
- package/bin/build-spellcheck-dict.js +25 -0
- package/client/app.bundle.js +16 -19
- package/client/app.bundle.js.map +2 -2
- package/client/app.js +34 -22
- package/client/app.js.map +1 -1
- package/client/app.ts +34 -24
- package/client/components/calendar-sidebar.js +14 -1
- package/client/components/calendar-sidebar.js.map +1 -1
- package/client/components/calendar-sidebar.ts +13 -1
- package/client/compose/compose.bundle.js +1254 -4
- package/client/compose/compose.bundle.js.map +4 -4
- package/client/compose/compose.css +28 -2
- package/client/compose/compose.js +23 -1
- package/client/compose/compose.js.map +1 -1
- package/client/compose/compose.ts +21 -1
- package/client/compose/spellcheck.js +296 -0
- package/client/compose/spellcheck.js.map +1 -0
- package/client/compose/spellcheck.ts +267 -0
- package/client/lib/dict/en.aff +205 -0
- package/client/lib/dict/en.dic +49569 -0
- package/client/lib/rmf-tiny.js +3 -2
- package/package.json +8 -2
- package/packages/mailx-service/index.d.ts.map +1 -1
- package/packages/mailx-service/index.js +9 -1
- package/packages/mailx-service/index.js.map +1 -1
- package/packages/mailx-service/index.ts +9 -1
|
@@ -1,12 +1,35 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
1
2
|
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
2
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
3
7
|
var __esm = (fn, res) => function __init() {
|
|
4
8
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
5
9
|
};
|
|
10
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
11
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
12
|
+
};
|
|
6
13
|
var __export = (target, all) => {
|
|
7
14
|
for (var name in all)
|
|
8
15
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
16
|
};
|
|
17
|
+
var __copyProps = (to, from, except, desc) => {
|
|
18
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
19
|
+
for (let key of __getOwnPropNames(from))
|
|
20
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
21
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
22
|
+
}
|
|
23
|
+
return to;
|
|
24
|
+
};
|
|
25
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
26
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
27
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
28
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
29
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
30
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
31
|
+
mod
|
|
32
|
+
));
|
|
10
33
|
|
|
11
34
|
// client/lib/api-client.js
|
|
12
35
|
var api_client_exports = {};
|
|
@@ -524,10 +547,10 @@ async function createTinyMceEditor(container2, opts = {}) {
|
|
|
524
547
|
// All free / OSS plugins bundled in the jsDelivr tinymce@6 script.
|
|
525
548
|
// No premium plugins listed — listing one without an API key
|
|
526
549
|
// triggers TinyMCE's upsell dialog on every load.
|
|
527
|
-
plugins: "paste lists link table code image searchreplace autolink wordcount emoticons charmap insertdatetime quickbars nonbreaking directionality",
|
|
550
|
+
plugins: "paste lists advlist link table code codesample image searchreplace autolink wordcount emoticons charmap insertdatetime quickbars nonbreaking directionality help",
|
|
528
551
|
toolbar: [
|
|
529
552
|
"undo redo | bold italic underline strikethrough | forecolor backcolor",
|
|
530
|
-
"bullist numlist outdent indent | link table image code | emoticons charmap"
|
|
553
|
+
"bullist numlist outdent indent | link table image code codesample | emoticons charmap | help"
|
|
531
554
|
].join(" | "),
|
|
532
555
|
// Include "tools" so wordcount and searchreplace are reachable.
|
|
533
556
|
menubar: "file edit view insert format tools",
|
|
@@ -685,7 +708,8 @@ async function createTinyMceEditor(container2, opts = {}) {
|
|
|
685
708
|
},
|
|
686
709
|
off(event, handler) {
|
|
687
710
|
editor2.off(event, handler);
|
|
688
|
-
}
|
|
711
|
+
},
|
|
712
|
+
nativeEditor: editor2
|
|
689
713
|
};
|
|
690
714
|
}
|
|
691
715
|
var init_rmf_tiny = __esm({
|
|
@@ -694,6 +718,1213 @@ var init_rmf_tiny = __esm({
|
|
|
694
718
|
}
|
|
695
719
|
});
|
|
696
720
|
|
|
721
|
+
// node_modules/is-buffer/index.js
|
|
722
|
+
var require_is_buffer = __commonJS({
|
|
723
|
+
"node_modules/is-buffer/index.js"(exports, module) {
|
|
724
|
+
module.exports = function isBuffer(obj) {
|
|
725
|
+
return obj != null && obj.constructor != null && typeof obj.constructor.isBuffer === "function" && obj.constructor.isBuffer(obj);
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
});
|
|
729
|
+
|
|
730
|
+
// node_modules/nspell/lib/util/rule-codes.js
|
|
731
|
+
var require_rule_codes = __commonJS({
|
|
732
|
+
"node_modules/nspell/lib/util/rule-codes.js"(exports, module) {
|
|
733
|
+
"use strict";
|
|
734
|
+
module.exports = ruleCodes;
|
|
735
|
+
var NO_CODES = [];
|
|
736
|
+
function ruleCodes(flags, value) {
|
|
737
|
+
var index = 0;
|
|
738
|
+
var result;
|
|
739
|
+
if (!value) return NO_CODES;
|
|
740
|
+
if (flags.FLAG === "long") {
|
|
741
|
+
result = new Array(Math.ceil(value.length / 2));
|
|
742
|
+
while (index < value.length) {
|
|
743
|
+
result[index / 2] = value.slice(index, index + 2);
|
|
744
|
+
index += 2;
|
|
745
|
+
}
|
|
746
|
+
return result;
|
|
747
|
+
}
|
|
748
|
+
return value.split(flags.FLAG === "num" ? "," : "");
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
});
|
|
752
|
+
|
|
753
|
+
// node_modules/nspell/lib/util/affix.js
|
|
754
|
+
var require_affix = __commonJS({
|
|
755
|
+
"node_modules/nspell/lib/util/affix.js"(exports, module) {
|
|
756
|
+
"use strict";
|
|
757
|
+
var parse = require_rule_codes();
|
|
758
|
+
module.exports = affix;
|
|
759
|
+
var push = [].push;
|
|
760
|
+
var alphabet = "etaoinshrdlcumwfgypbvkjxqz".split("");
|
|
761
|
+
var whiteSpaceExpression = /\s+/;
|
|
762
|
+
var defaultKeyboardLayout = [
|
|
763
|
+
"qwertzuop",
|
|
764
|
+
"yxcvbnm",
|
|
765
|
+
"qaw",
|
|
766
|
+
"say",
|
|
767
|
+
"wse",
|
|
768
|
+
"dsx",
|
|
769
|
+
"sy",
|
|
770
|
+
"edr",
|
|
771
|
+
"fdc",
|
|
772
|
+
"dx",
|
|
773
|
+
"rft",
|
|
774
|
+
"gfv",
|
|
775
|
+
"fc",
|
|
776
|
+
"tgz",
|
|
777
|
+
"hgb",
|
|
778
|
+
"gv",
|
|
779
|
+
"zhu",
|
|
780
|
+
"jhn",
|
|
781
|
+
"hb",
|
|
782
|
+
"uji",
|
|
783
|
+
"kjm",
|
|
784
|
+
"jn",
|
|
785
|
+
"iko",
|
|
786
|
+
"lkm"
|
|
787
|
+
];
|
|
788
|
+
function affix(doc) {
|
|
789
|
+
var rules = /* @__PURE__ */ Object.create(null);
|
|
790
|
+
var compoundRuleCodes = /* @__PURE__ */ Object.create(null);
|
|
791
|
+
var flags = /* @__PURE__ */ Object.create(null);
|
|
792
|
+
var replacementTable = [];
|
|
793
|
+
var conversion = { in: [], out: [] };
|
|
794
|
+
var compoundRules = [];
|
|
795
|
+
var aff = doc.toString("utf8");
|
|
796
|
+
var lines = [];
|
|
797
|
+
var last = 0;
|
|
798
|
+
var index = aff.indexOf("\n");
|
|
799
|
+
var parts;
|
|
800
|
+
var line;
|
|
801
|
+
var ruleType;
|
|
802
|
+
var count;
|
|
803
|
+
var remove;
|
|
804
|
+
var add;
|
|
805
|
+
var source;
|
|
806
|
+
var entry;
|
|
807
|
+
var position;
|
|
808
|
+
var rule;
|
|
809
|
+
var value;
|
|
810
|
+
var offset;
|
|
811
|
+
var character;
|
|
812
|
+
flags.KEY = [];
|
|
813
|
+
while (index > -1) {
|
|
814
|
+
pushLine(aff.slice(last, index));
|
|
815
|
+
last = index + 1;
|
|
816
|
+
index = aff.indexOf("\n", last);
|
|
817
|
+
}
|
|
818
|
+
pushLine(aff.slice(last));
|
|
819
|
+
index = -1;
|
|
820
|
+
while (++index < lines.length) {
|
|
821
|
+
line = lines[index];
|
|
822
|
+
parts = line.split(whiteSpaceExpression);
|
|
823
|
+
ruleType = parts[0];
|
|
824
|
+
if (ruleType === "REP") {
|
|
825
|
+
count = index + parseInt(parts[1], 10);
|
|
826
|
+
while (++index <= count) {
|
|
827
|
+
parts = lines[index].split(whiteSpaceExpression);
|
|
828
|
+
replacementTable.push([parts[1], parts[2]]);
|
|
829
|
+
}
|
|
830
|
+
index--;
|
|
831
|
+
} else if (ruleType === "ICONV" || ruleType === "OCONV") {
|
|
832
|
+
count = index + parseInt(parts[1], 10);
|
|
833
|
+
entry = conversion[ruleType === "ICONV" ? "in" : "out"];
|
|
834
|
+
while (++index <= count) {
|
|
835
|
+
parts = lines[index].split(whiteSpaceExpression);
|
|
836
|
+
entry.push([new RegExp(parts[1], "g"), parts[2]]);
|
|
837
|
+
}
|
|
838
|
+
index--;
|
|
839
|
+
} else if (ruleType === "COMPOUNDRULE") {
|
|
840
|
+
count = index + parseInt(parts[1], 10);
|
|
841
|
+
while (++index <= count) {
|
|
842
|
+
rule = lines[index].split(whiteSpaceExpression)[1];
|
|
843
|
+
position = -1;
|
|
844
|
+
compoundRules.push(rule);
|
|
845
|
+
while (++position < rule.length) {
|
|
846
|
+
compoundRuleCodes[rule.charAt(position)] = [];
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
index--;
|
|
850
|
+
} else if (ruleType === "PFX" || ruleType === "SFX") {
|
|
851
|
+
count = index + parseInt(parts[3], 10);
|
|
852
|
+
rule = {
|
|
853
|
+
type: ruleType,
|
|
854
|
+
combineable: parts[2] === "Y",
|
|
855
|
+
entries: []
|
|
856
|
+
};
|
|
857
|
+
rules[parts[1]] = rule;
|
|
858
|
+
while (++index <= count) {
|
|
859
|
+
parts = lines[index].split(whiteSpaceExpression);
|
|
860
|
+
remove = parts[2];
|
|
861
|
+
add = parts[3].split("/");
|
|
862
|
+
source = parts[4];
|
|
863
|
+
entry = {
|
|
864
|
+
add: "",
|
|
865
|
+
remove: "",
|
|
866
|
+
match: "",
|
|
867
|
+
continuation: parse(flags, add[1])
|
|
868
|
+
};
|
|
869
|
+
if (add && add[0] !== "0") {
|
|
870
|
+
entry.add = add[0];
|
|
871
|
+
}
|
|
872
|
+
try {
|
|
873
|
+
if (remove !== "0") {
|
|
874
|
+
entry.remove = ruleType === "SFX" ? end(remove) : remove;
|
|
875
|
+
}
|
|
876
|
+
if (source && source !== ".") {
|
|
877
|
+
entry.match = ruleType === "SFX" ? end(source) : start(source);
|
|
878
|
+
}
|
|
879
|
+
} catch (_) {
|
|
880
|
+
entry = null;
|
|
881
|
+
}
|
|
882
|
+
if (entry) {
|
|
883
|
+
rule.entries.push(entry);
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
index--;
|
|
887
|
+
} else if (ruleType === "TRY") {
|
|
888
|
+
source = parts[1];
|
|
889
|
+
offset = -1;
|
|
890
|
+
value = [];
|
|
891
|
+
while (++offset < source.length) {
|
|
892
|
+
character = source.charAt(offset);
|
|
893
|
+
if (character.toLowerCase() === character) {
|
|
894
|
+
value.push(character);
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
offset = -1;
|
|
898
|
+
while (++offset < alphabet.length) {
|
|
899
|
+
if (source.indexOf(alphabet[offset]) < 0) {
|
|
900
|
+
value.push(alphabet[offset]);
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
flags[ruleType] = value;
|
|
904
|
+
} else if (ruleType === "KEY") {
|
|
905
|
+
push.apply(flags[ruleType], parts[1].split("|"));
|
|
906
|
+
} else if (ruleType === "COMPOUNDMIN") {
|
|
907
|
+
flags[ruleType] = Number(parts[1]);
|
|
908
|
+
} else if (ruleType === "ONLYINCOMPOUND") {
|
|
909
|
+
flags[ruleType] = parts[1];
|
|
910
|
+
compoundRuleCodes[parts[1]] = [];
|
|
911
|
+
} else if (ruleType === "FLAG" || ruleType === "KEEPCASE" || ruleType === "NOSUGGEST" || ruleType === "WORDCHARS") {
|
|
912
|
+
flags[ruleType] = parts[1];
|
|
913
|
+
} else {
|
|
914
|
+
flags[ruleType] = parts[1];
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
if (isNaN(flags.COMPOUNDMIN)) {
|
|
918
|
+
flags.COMPOUNDMIN = 3;
|
|
919
|
+
}
|
|
920
|
+
if (!flags.KEY.length) {
|
|
921
|
+
flags.KEY = defaultKeyboardLayout;
|
|
922
|
+
}
|
|
923
|
+
if (!flags.TRY) {
|
|
924
|
+
flags.TRY = alphabet.concat();
|
|
925
|
+
}
|
|
926
|
+
if (!flags.KEEPCASE) {
|
|
927
|
+
flags.KEEPCASE = false;
|
|
928
|
+
}
|
|
929
|
+
return {
|
|
930
|
+
compoundRuleCodes,
|
|
931
|
+
replacementTable,
|
|
932
|
+
conversion,
|
|
933
|
+
compoundRules,
|
|
934
|
+
rules,
|
|
935
|
+
flags
|
|
936
|
+
};
|
|
937
|
+
function pushLine(line2) {
|
|
938
|
+
line2 = line2.trim();
|
|
939
|
+
if (line2 && line2.charCodeAt(0) !== 35) {
|
|
940
|
+
lines.push(line2);
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
function end(source) {
|
|
945
|
+
return new RegExp(source + "$");
|
|
946
|
+
}
|
|
947
|
+
function start(source) {
|
|
948
|
+
return new RegExp("^" + source);
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
});
|
|
952
|
+
|
|
953
|
+
// node_modules/nspell/lib/util/normalize.js
|
|
954
|
+
var require_normalize = __commonJS({
|
|
955
|
+
"node_modules/nspell/lib/util/normalize.js"(exports, module) {
|
|
956
|
+
"use strict";
|
|
957
|
+
module.exports = normalize;
|
|
958
|
+
function normalize(value, patterns) {
|
|
959
|
+
var index = -1;
|
|
960
|
+
while (++index < patterns.length) {
|
|
961
|
+
value = value.replace(patterns[index][0], patterns[index][1]);
|
|
962
|
+
}
|
|
963
|
+
return value;
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
});
|
|
967
|
+
|
|
968
|
+
// node_modules/nspell/lib/util/flag.js
|
|
969
|
+
var require_flag = __commonJS({
|
|
970
|
+
"node_modules/nspell/lib/util/flag.js"(exports, module) {
|
|
971
|
+
"use strict";
|
|
972
|
+
module.exports = flag;
|
|
973
|
+
function flag(values, value, flags) {
|
|
974
|
+
return flags && value in values && flags.indexOf(values[value]) > -1;
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
});
|
|
978
|
+
|
|
979
|
+
// node_modules/nspell/lib/util/exact.js
|
|
980
|
+
var require_exact = __commonJS({
|
|
981
|
+
"node_modules/nspell/lib/util/exact.js"(exports, module) {
|
|
982
|
+
"use strict";
|
|
983
|
+
var flag = require_flag();
|
|
984
|
+
module.exports = exact;
|
|
985
|
+
function exact(context, value) {
|
|
986
|
+
var index = -1;
|
|
987
|
+
if (context.data[value]) {
|
|
988
|
+
return !flag(context.flags, "ONLYINCOMPOUND", context.data[value]);
|
|
989
|
+
}
|
|
990
|
+
if (value.length >= context.flags.COMPOUNDMIN) {
|
|
991
|
+
while (++index < context.compoundRules.length) {
|
|
992
|
+
if (context.compoundRules[index].test(value)) {
|
|
993
|
+
return true;
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
return false;
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
});
|
|
1001
|
+
|
|
1002
|
+
// node_modules/nspell/lib/util/form.js
|
|
1003
|
+
var require_form = __commonJS({
|
|
1004
|
+
"node_modules/nspell/lib/util/form.js"(exports, module) {
|
|
1005
|
+
"use strict";
|
|
1006
|
+
var normalize = require_normalize();
|
|
1007
|
+
var exact = require_exact();
|
|
1008
|
+
var flag = require_flag();
|
|
1009
|
+
module.exports = form;
|
|
1010
|
+
function form(context, value, all) {
|
|
1011
|
+
var normal = value.trim();
|
|
1012
|
+
var alternative;
|
|
1013
|
+
if (!normal) {
|
|
1014
|
+
return null;
|
|
1015
|
+
}
|
|
1016
|
+
normal = normalize(normal, context.conversion.in);
|
|
1017
|
+
if (exact(context, normal)) {
|
|
1018
|
+
if (!all && flag(context.flags, "FORBIDDENWORD", context.data[normal])) {
|
|
1019
|
+
return null;
|
|
1020
|
+
}
|
|
1021
|
+
return normal;
|
|
1022
|
+
}
|
|
1023
|
+
if (normal.toUpperCase() === normal) {
|
|
1024
|
+
alternative = normal.charAt(0) + normal.slice(1).toLowerCase();
|
|
1025
|
+
if (ignore(context.flags, context.data[alternative], all)) {
|
|
1026
|
+
return null;
|
|
1027
|
+
}
|
|
1028
|
+
if (exact(context, alternative)) {
|
|
1029
|
+
return alternative;
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
alternative = normal.toLowerCase();
|
|
1033
|
+
if (alternative !== normal) {
|
|
1034
|
+
if (ignore(context.flags, context.data[alternative], all)) {
|
|
1035
|
+
return null;
|
|
1036
|
+
}
|
|
1037
|
+
if (exact(context, alternative)) {
|
|
1038
|
+
return alternative;
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
return null;
|
|
1042
|
+
}
|
|
1043
|
+
function ignore(flags, dict, all) {
|
|
1044
|
+
return flag(flags, "KEEPCASE", dict) || all || flag(flags, "FORBIDDENWORD", dict);
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
});
|
|
1048
|
+
|
|
1049
|
+
// node_modules/nspell/lib/correct.js
|
|
1050
|
+
var require_correct = __commonJS({
|
|
1051
|
+
"node_modules/nspell/lib/correct.js"(exports, module) {
|
|
1052
|
+
"use strict";
|
|
1053
|
+
var form = require_form();
|
|
1054
|
+
module.exports = correct;
|
|
1055
|
+
function correct(value) {
|
|
1056
|
+
return Boolean(form(this, value));
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
});
|
|
1060
|
+
|
|
1061
|
+
// node_modules/nspell/lib/util/casing.js
|
|
1062
|
+
var require_casing = __commonJS({
|
|
1063
|
+
"node_modules/nspell/lib/util/casing.js"(exports, module) {
|
|
1064
|
+
"use strict";
|
|
1065
|
+
module.exports = casing;
|
|
1066
|
+
function casing(value) {
|
|
1067
|
+
var head = exact(value.charAt(0));
|
|
1068
|
+
var rest = value.slice(1);
|
|
1069
|
+
if (!rest) {
|
|
1070
|
+
return head;
|
|
1071
|
+
}
|
|
1072
|
+
rest = exact(rest);
|
|
1073
|
+
if (head === rest) {
|
|
1074
|
+
return head;
|
|
1075
|
+
}
|
|
1076
|
+
if (head === "u" && rest === "l") {
|
|
1077
|
+
return "s";
|
|
1078
|
+
}
|
|
1079
|
+
return null;
|
|
1080
|
+
}
|
|
1081
|
+
function exact(value) {
|
|
1082
|
+
return value === value.toLowerCase() ? "l" : value === value.toUpperCase() ? "u" : null;
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
});
|
|
1086
|
+
|
|
1087
|
+
// node_modules/nspell/lib/suggest.js
|
|
1088
|
+
var require_suggest = __commonJS({
|
|
1089
|
+
"node_modules/nspell/lib/suggest.js"(exports, module) {
|
|
1090
|
+
"use strict";
|
|
1091
|
+
var casing = require_casing();
|
|
1092
|
+
var normalize = require_normalize();
|
|
1093
|
+
var flag = require_flag();
|
|
1094
|
+
var form = require_form();
|
|
1095
|
+
module.exports = suggest;
|
|
1096
|
+
var push = [].push;
|
|
1097
|
+
function suggest(value) {
|
|
1098
|
+
var self = this;
|
|
1099
|
+
var charAdded = {};
|
|
1100
|
+
var suggestions = [];
|
|
1101
|
+
var weighted = {};
|
|
1102
|
+
var memory;
|
|
1103
|
+
var replacement;
|
|
1104
|
+
var edits = [];
|
|
1105
|
+
var values;
|
|
1106
|
+
var index;
|
|
1107
|
+
var offset;
|
|
1108
|
+
var position;
|
|
1109
|
+
var count;
|
|
1110
|
+
var otherOffset;
|
|
1111
|
+
var otherCharacter;
|
|
1112
|
+
var character;
|
|
1113
|
+
var group;
|
|
1114
|
+
var before;
|
|
1115
|
+
var after;
|
|
1116
|
+
var upper;
|
|
1117
|
+
var insensitive;
|
|
1118
|
+
var firstLevel;
|
|
1119
|
+
var previous;
|
|
1120
|
+
var next;
|
|
1121
|
+
var nextCharacter;
|
|
1122
|
+
var max;
|
|
1123
|
+
var distance;
|
|
1124
|
+
var size;
|
|
1125
|
+
var normalized;
|
|
1126
|
+
var suggestion;
|
|
1127
|
+
var currentCase;
|
|
1128
|
+
value = normalize(value.trim(), self.conversion.in);
|
|
1129
|
+
if (!value || self.correct(value)) {
|
|
1130
|
+
return [];
|
|
1131
|
+
}
|
|
1132
|
+
currentCase = casing(value);
|
|
1133
|
+
index = -1;
|
|
1134
|
+
while (++index < self.replacementTable.length) {
|
|
1135
|
+
replacement = self.replacementTable[index];
|
|
1136
|
+
offset = value.indexOf(replacement[0]);
|
|
1137
|
+
while (offset > -1) {
|
|
1138
|
+
edits.push(value.replace(replacement[0], replacement[1]));
|
|
1139
|
+
offset = value.indexOf(replacement[0], offset + 1);
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
index = -1;
|
|
1143
|
+
while (++index < value.length) {
|
|
1144
|
+
character = value.charAt(index);
|
|
1145
|
+
before = value.slice(0, index);
|
|
1146
|
+
after = value.slice(index + 1);
|
|
1147
|
+
insensitive = character.toLowerCase();
|
|
1148
|
+
upper = insensitive !== character;
|
|
1149
|
+
charAdded = {};
|
|
1150
|
+
offset = -1;
|
|
1151
|
+
while (++offset < self.flags.KEY.length) {
|
|
1152
|
+
group = self.flags.KEY[offset];
|
|
1153
|
+
position = group.indexOf(insensitive);
|
|
1154
|
+
if (position < 0) {
|
|
1155
|
+
continue;
|
|
1156
|
+
}
|
|
1157
|
+
otherOffset = -1;
|
|
1158
|
+
while (++otherOffset < group.length) {
|
|
1159
|
+
if (otherOffset !== position) {
|
|
1160
|
+
otherCharacter = group.charAt(otherOffset);
|
|
1161
|
+
if (charAdded[otherCharacter]) {
|
|
1162
|
+
continue;
|
|
1163
|
+
}
|
|
1164
|
+
charAdded[otherCharacter] = true;
|
|
1165
|
+
if (upper) {
|
|
1166
|
+
otherCharacter = otherCharacter.toUpperCase();
|
|
1167
|
+
}
|
|
1168
|
+
edits.push(before + otherCharacter + after);
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
index = -1;
|
|
1174
|
+
nextCharacter = value.charAt(0);
|
|
1175
|
+
values = [""];
|
|
1176
|
+
max = 1;
|
|
1177
|
+
distance = 0;
|
|
1178
|
+
while (++index < value.length) {
|
|
1179
|
+
character = nextCharacter;
|
|
1180
|
+
nextCharacter = value.charAt(index + 1);
|
|
1181
|
+
before = value.slice(0, index);
|
|
1182
|
+
replacement = character === nextCharacter ? "" : character + character;
|
|
1183
|
+
offset = -1;
|
|
1184
|
+
count = values.length;
|
|
1185
|
+
while (++offset < count) {
|
|
1186
|
+
if (offset <= max) {
|
|
1187
|
+
values.push(values[offset] + replacement);
|
|
1188
|
+
}
|
|
1189
|
+
values[offset] += character;
|
|
1190
|
+
}
|
|
1191
|
+
if (++distance < 3) {
|
|
1192
|
+
max = values.length;
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
push.apply(edits, values);
|
|
1196
|
+
values = [value];
|
|
1197
|
+
replacement = value.toLowerCase();
|
|
1198
|
+
if (value === replacement || currentCase === null) {
|
|
1199
|
+
values.push(value.charAt(0).toUpperCase() + replacement.slice(1));
|
|
1200
|
+
}
|
|
1201
|
+
replacement = value.toUpperCase();
|
|
1202
|
+
if (value !== replacement) {
|
|
1203
|
+
values.push(replacement);
|
|
1204
|
+
}
|
|
1205
|
+
memory = {
|
|
1206
|
+
state: {},
|
|
1207
|
+
weighted,
|
|
1208
|
+
suggestions
|
|
1209
|
+
};
|
|
1210
|
+
firstLevel = generate(self, memory, values, edits);
|
|
1211
|
+
previous = 0;
|
|
1212
|
+
max = Math.min(firstLevel.length, Math.pow(Math.max(15 - value.length, 3), 3));
|
|
1213
|
+
size = Math.max(Math.pow(10 - value.length, 3), 1);
|
|
1214
|
+
while (!suggestions.length && previous < max) {
|
|
1215
|
+
next = previous + size;
|
|
1216
|
+
generate(self, memory, firstLevel.slice(previous, next));
|
|
1217
|
+
previous = next;
|
|
1218
|
+
}
|
|
1219
|
+
suggestions.sort(sort);
|
|
1220
|
+
values = [];
|
|
1221
|
+
normalized = [];
|
|
1222
|
+
index = -1;
|
|
1223
|
+
while (++index < suggestions.length) {
|
|
1224
|
+
suggestion = normalize(suggestions[index], self.conversion.out);
|
|
1225
|
+
replacement = suggestion.toLowerCase();
|
|
1226
|
+
if (normalized.indexOf(replacement) < 0) {
|
|
1227
|
+
values.push(suggestion);
|
|
1228
|
+
normalized.push(replacement);
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
return values;
|
|
1232
|
+
function sort(a, b) {
|
|
1233
|
+
return sortWeight(a, b) || sortCasing(a, b) || sortAlpha(a, b);
|
|
1234
|
+
}
|
|
1235
|
+
function sortWeight(a, b) {
|
|
1236
|
+
return weighted[a] === weighted[b] ? 0 : weighted[a] > weighted[b] ? -1 : 1;
|
|
1237
|
+
}
|
|
1238
|
+
function sortCasing(a, b) {
|
|
1239
|
+
var leftCasing = casing(a);
|
|
1240
|
+
var rightCasing = casing(b);
|
|
1241
|
+
return leftCasing === rightCasing ? 0 : leftCasing === currentCase ? -1 : rightCasing === currentCase ? 1 : void 0;
|
|
1242
|
+
}
|
|
1243
|
+
function sortAlpha(a, b) {
|
|
1244
|
+
return a.localeCompare(b);
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
function generate(context, memory, words, edits) {
|
|
1248
|
+
var characters = context.flags.TRY;
|
|
1249
|
+
var data = context.data;
|
|
1250
|
+
var flags = context.flags;
|
|
1251
|
+
var result = [];
|
|
1252
|
+
var index = -1;
|
|
1253
|
+
var word;
|
|
1254
|
+
var before;
|
|
1255
|
+
var character;
|
|
1256
|
+
var nextCharacter;
|
|
1257
|
+
var nextAfter;
|
|
1258
|
+
var nextNextAfter;
|
|
1259
|
+
var nextUpper;
|
|
1260
|
+
var currentCase;
|
|
1261
|
+
var position;
|
|
1262
|
+
var after;
|
|
1263
|
+
var upper;
|
|
1264
|
+
var inject;
|
|
1265
|
+
var offset;
|
|
1266
|
+
if (edits) {
|
|
1267
|
+
while (++index < edits.length) {
|
|
1268
|
+
check(edits[index], true);
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
index = -1;
|
|
1272
|
+
while (++index < words.length) {
|
|
1273
|
+
word = words[index];
|
|
1274
|
+
before = "";
|
|
1275
|
+
character = "";
|
|
1276
|
+
nextCharacter = word.charAt(0);
|
|
1277
|
+
nextAfter = word;
|
|
1278
|
+
nextNextAfter = word.slice(1);
|
|
1279
|
+
nextUpper = nextCharacter.toLowerCase() !== nextCharacter;
|
|
1280
|
+
currentCase = casing(word);
|
|
1281
|
+
position = -1;
|
|
1282
|
+
while (++position <= word.length) {
|
|
1283
|
+
before += character;
|
|
1284
|
+
after = nextAfter;
|
|
1285
|
+
nextAfter = nextNextAfter;
|
|
1286
|
+
nextNextAfter = nextAfter.slice(1);
|
|
1287
|
+
character = nextCharacter;
|
|
1288
|
+
nextCharacter = word.charAt(position + 1);
|
|
1289
|
+
upper = nextUpper;
|
|
1290
|
+
if (nextCharacter) {
|
|
1291
|
+
nextUpper = nextCharacter.toLowerCase() !== nextCharacter;
|
|
1292
|
+
}
|
|
1293
|
+
if (nextAfter && upper !== nextUpper) {
|
|
1294
|
+
check(before + switchCase(nextAfter));
|
|
1295
|
+
check(
|
|
1296
|
+
before + switchCase(nextCharacter) + switchCase(character) + nextNextAfter
|
|
1297
|
+
);
|
|
1298
|
+
}
|
|
1299
|
+
check(before + nextAfter);
|
|
1300
|
+
if (nextAfter) {
|
|
1301
|
+
check(before + nextCharacter + character + nextNextAfter);
|
|
1302
|
+
}
|
|
1303
|
+
offset = -1;
|
|
1304
|
+
while (++offset < characters.length) {
|
|
1305
|
+
inject = characters[offset];
|
|
1306
|
+
if (upper && inject !== inject.toUpperCase()) {
|
|
1307
|
+
if (currentCase !== "s") {
|
|
1308
|
+
check(before + inject + after);
|
|
1309
|
+
check(before + inject + nextAfter);
|
|
1310
|
+
}
|
|
1311
|
+
inject = inject.toUpperCase();
|
|
1312
|
+
check(before + inject + after);
|
|
1313
|
+
check(before + inject + nextAfter);
|
|
1314
|
+
} else {
|
|
1315
|
+
check(before + inject + after);
|
|
1316
|
+
check(before + inject + nextAfter);
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
return result;
|
|
1322
|
+
function check(value, double) {
|
|
1323
|
+
var state = memory.state[value];
|
|
1324
|
+
var corrected;
|
|
1325
|
+
if (state !== Boolean(state)) {
|
|
1326
|
+
result.push(value);
|
|
1327
|
+
corrected = form(context, value);
|
|
1328
|
+
state = corrected && !flag(flags, "NOSUGGEST", data[corrected]);
|
|
1329
|
+
memory.state[value] = state;
|
|
1330
|
+
if (state) {
|
|
1331
|
+
memory.weighted[value] = double ? 10 : 0;
|
|
1332
|
+
memory.suggestions.push(value);
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
if (state) {
|
|
1336
|
+
memory.weighted[value]++;
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
function switchCase(fragment) {
|
|
1340
|
+
var first = fragment.charAt(0);
|
|
1341
|
+
return (first.toLowerCase() === first ? first.toUpperCase() : first.toLowerCase()) + fragment.slice(1);
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
});
|
|
1346
|
+
|
|
1347
|
+
// node_modules/nspell/lib/spell.js
|
|
1348
|
+
var require_spell = __commonJS({
|
|
1349
|
+
"node_modules/nspell/lib/spell.js"(exports, module) {
|
|
1350
|
+
"use strict";
|
|
1351
|
+
var form = require_form();
|
|
1352
|
+
var flag = require_flag();
|
|
1353
|
+
module.exports = spell;
|
|
1354
|
+
function spell(word) {
|
|
1355
|
+
var self = this;
|
|
1356
|
+
var value = form(self, word, true);
|
|
1357
|
+
return {
|
|
1358
|
+
correct: self.correct(word),
|
|
1359
|
+
forbidden: Boolean(
|
|
1360
|
+
value && flag(self.flags, "FORBIDDENWORD", self.data[value])
|
|
1361
|
+
),
|
|
1362
|
+
warn: Boolean(value && flag(self.flags, "WARN", self.data[value]))
|
|
1363
|
+
};
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
});
|
|
1367
|
+
|
|
1368
|
+
// node_modules/nspell/lib/util/apply.js
|
|
1369
|
+
var require_apply = __commonJS({
|
|
1370
|
+
"node_modules/nspell/lib/util/apply.js"(exports, module) {
|
|
1371
|
+
"use strict";
|
|
1372
|
+
module.exports = apply;
|
|
1373
|
+
function apply(value, rule, rules, words) {
|
|
1374
|
+
var index = -1;
|
|
1375
|
+
var entry;
|
|
1376
|
+
var next;
|
|
1377
|
+
var continuationRule;
|
|
1378
|
+
var continuation;
|
|
1379
|
+
var position;
|
|
1380
|
+
while (++index < rule.entries.length) {
|
|
1381
|
+
entry = rule.entries[index];
|
|
1382
|
+
continuation = entry.continuation;
|
|
1383
|
+
position = -1;
|
|
1384
|
+
if (!entry.match || entry.match.test(value)) {
|
|
1385
|
+
next = entry.remove ? value.replace(entry.remove, "") : value;
|
|
1386
|
+
next = rule.type === "SFX" ? next + entry.add : entry.add + next;
|
|
1387
|
+
words.push(next);
|
|
1388
|
+
if (continuation && continuation.length) {
|
|
1389
|
+
while (++position < continuation.length) {
|
|
1390
|
+
continuationRule = rules[continuation[position]];
|
|
1391
|
+
if (continuationRule) {
|
|
1392
|
+
apply(next, continuationRule, rules, words);
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
return words;
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
});
|
|
1402
|
+
|
|
1403
|
+
// node_modules/nspell/lib/util/add.js
|
|
1404
|
+
var require_add = __commonJS({
|
|
1405
|
+
"node_modules/nspell/lib/util/add.js"(exports, module) {
|
|
1406
|
+
"use strict";
|
|
1407
|
+
var apply = require_apply();
|
|
1408
|
+
module.exports = add;
|
|
1409
|
+
var push = [].push;
|
|
1410
|
+
var NO_RULES = [];
|
|
1411
|
+
function addRules(dict, word, rules) {
|
|
1412
|
+
var curr = dict[word];
|
|
1413
|
+
if (word in dict) {
|
|
1414
|
+
if (curr === NO_RULES) {
|
|
1415
|
+
dict[word] = rules.concat();
|
|
1416
|
+
} else {
|
|
1417
|
+
push.apply(curr, rules);
|
|
1418
|
+
}
|
|
1419
|
+
} else {
|
|
1420
|
+
dict[word] = rules.concat();
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
function add(dict, word, codes, options) {
|
|
1424
|
+
var position = -1;
|
|
1425
|
+
var rule;
|
|
1426
|
+
var offset;
|
|
1427
|
+
var subposition;
|
|
1428
|
+
var suboffset;
|
|
1429
|
+
var combined;
|
|
1430
|
+
var newWords;
|
|
1431
|
+
var otherNewWords;
|
|
1432
|
+
if (!("NEEDAFFIX" in options.flags) || codes.indexOf(options.flags.NEEDAFFIX) < 0) {
|
|
1433
|
+
addRules(dict, word, codes);
|
|
1434
|
+
}
|
|
1435
|
+
while (++position < codes.length) {
|
|
1436
|
+
rule = options.rules[codes[position]];
|
|
1437
|
+
if (codes[position] in options.compoundRuleCodes) {
|
|
1438
|
+
options.compoundRuleCodes[codes[position]].push(word);
|
|
1439
|
+
}
|
|
1440
|
+
if (rule) {
|
|
1441
|
+
newWords = apply(word, rule, options.rules, []);
|
|
1442
|
+
offset = -1;
|
|
1443
|
+
while (++offset < newWords.length) {
|
|
1444
|
+
if (!(newWords[offset] in dict)) {
|
|
1445
|
+
dict[newWords[offset]] = NO_RULES;
|
|
1446
|
+
}
|
|
1447
|
+
if (rule.combineable) {
|
|
1448
|
+
subposition = position;
|
|
1449
|
+
while (++subposition < codes.length) {
|
|
1450
|
+
combined = options.rules[codes[subposition]];
|
|
1451
|
+
if (combined && combined.combineable && rule.type !== combined.type) {
|
|
1452
|
+
otherNewWords = apply(
|
|
1453
|
+
newWords[offset],
|
|
1454
|
+
combined,
|
|
1455
|
+
options.rules,
|
|
1456
|
+
[]
|
|
1457
|
+
);
|
|
1458
|
+
suboffset = -1;
|
|
1459
|
+
while (++suboffset < otherNewWords.length) {
|
|
1460
|
+
if (!(otherNewWords[suboffset] in dict)) {
|
|
1461
|
+
dict[otherNewWords[suboffset]] = NO_RULES;
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1472
|
+
});
|
|
1473
|
+
|
|
1474
|
+
// node_modules/nspell/lib/add.js
|
|
1475
|
+
var require_add2 = __commonJS({
|
|
1476
|
+
"node_modules/nspell/lib/add.js"(exports, module) {
|
|
1477
|
+
"use strict";
|
|
1478
|
+
var push = require_add();
|
|
1479
|
+
module.exports = add;
|
|
1480
|
+
var NO_CODES = [];
|
|
1481
|
+
function add(value, model) {
|
|
1482
|
+
var self = this;
|
|
1483
|
+
push(self.data, value, self.data[model] || NO_CODES, self);
|
|
1484
|
+
return self;
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
});
|
|
1488
|
+
|
|
1489
|
+
// node_modules/nspell/lib/remove.js
|
|
1490
|
+
var require_remove = __commonJS({
|
|
1491
|
+
"node_modules/nspell/lib/remove.js"(exports, module) {
|
|
1492
|
+
"use strict";
|
|
1493
|
+
module.exports = remove;
|
|
1494
|
+
function remove(value) {
|
|
1495
|
+
var self = this;
|
|
1496
|
+
delete self.data[value];
|
|
1497
|
+
return self;
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
});
|
|
1501
|
+
|
|
1502
|
+
// node_modules/nspell/lib/word-characters.js
|
|
1503
|
+
var require_word_characters = __commonJS({
|
|
1504
|
+
"node_modules/nspell/lib/word-characters.js"(exports, module) {
|
|
1505
|
+
"use strict";
|
|
1506
|
+
module.exports = wordCharacters;
|
|
1507
|
+
function wordCharacters() {
|
|
1508
|
+
return this.flags.WORDCHARS || null;
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1511
|
+
});
|
|
1512
|
+
|
|
1513
|
+
// node_modules/nspell/lib/util/dictionary.js
|
|
1514
|
+
var require_dictionary = __commonJS({
|
|
1515
|
+
"node_modules/nspell/lib/util/dictionary.js"(exports, module) {
|
|
1516
|
+
"use strict";
|
|
1517
|
+
var parseCodes = require_rule_codes();
|
|
1518
|
+
var add = require_add();
|
|
1519
|
+
module.exports = parse;
|
|
1520
|
+
var whiteSpaceExpression = /\s/g;
|
|
1521
|
+
function parse(buf, options, dict) {
|
|
1522
|
+
var value = buf.toString("utf8");
|
|
1523
|
+
var last = value.indexOf("\n") + 1;
|
|
1524
|
+
var index = value.indexOf("\n", last);
|
|
1525
|
+
while (index > -1) {
|
|
1526
|
+
if (value.charCodeAt(last) !== 9) {
|
|
1527
|
+
parseLine(value.slice(last, index), options, dict);
|
|
1528
|
+
}
|
|
1529
|
+
last = index + 1;
|
|
1530
|
+
index = value.indexOf("\n", last);
|
|
1531
|
+
}
|
|
1532
|
+
parseLine(value.slice(last), options, dict);
|
|
1533
|
+
}
|
|
1534
|
+
function parseLine(line, options, dict) {
|
|
1535
|
+
var slashOffset = line.indexOf("/");
|
|
1536
|
+
var hashOffset = line.indexOf("#");
|
|
1537
|
+
var codes = "";
|
|
1538
|
+
var word;
|
|
1539
|
+
var result;
|
|
1540
|
+
while (slashOffset > -1 && line.charCodeAt(slashOffset - 1) === 92) {
|
|
1541
|
+
line = line.slice(0, slashOffset - 1) + line.slice(slashOffset);
|
|
1542
|
+
slashOffset = line.indexOf("/", slashOffset);
|
|
1543
|
+
}
|
|
1544
|
+
if (hashOffset > -1) {
|
|
1545
|
+
if (slashOffset > -1 && slashOffset < hashOffset) {
|
|
1546
|
+
word = line.slice(0, slashOffset);
|
|
1547
|
+
whiteSpaceExpression.lastIndex = slashOffset + 1;
|
|
1548
|
+
result = whiteSpaceExpression.exec(line);
|
|
1549
|
+
codes = line.slice(slashOffset + 1, result ? result.index : void 0);
|
|
1550
|
+
} else {
|
|
1551
|
+
word = line.slice(0, hashOffset);
|
|
1552
|
+
}
|
|
1553
|
+
} else if (slashOffset > -1) {
|
|
1554
|
+
word = line.slice(0, slashOffset);
|
|
1555
|
+
codes = line.slice(slashOffset + 1);
|
|
1556
|
+
} else {
|
|
1557
|
+
word = line;
|
|
1558
|
+
}
|
|
1559
|
+
word = word.trim();
|
|
1560
|
+
if (word) {
|
|
1561
|
+
add(dict, word, parseCodes(options.flags, codes.trim()), options);
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
});
|
|
1566
|
+
|
|
1567
|
+
// node_modules/nspell/lib/dictionary.js
|
|
1568
|
+
var require_dictionary2 = __commonJS({
|
|
1569
|
+
"node_modules/nspell/lib/dictionary.js"(exports, module) {
|
|
1570
|
+
"use strict";
|
|
1571
|
+
var parse = require_dictionary();
|
|
1572
|
+
module.exports = add;
|
|
1573
|
+
function add(buf) {
|
|
1574
|
+
var self = this;
|
|
1575
|
+
var index = -1;
|
|
1576
|
+
var rule;
|
|
1577
|
+
var source;
|
|
1578
|
+
var character;
|
|
1579
|
+
var offset;
|
|
1580
|
+
parse(buf, self, self.data);
|
|
1581
|
+
while (++index < self.compoundRules.length) {
|
|
1582
|
+
rule = self.compoundRules[index];
|
|
1583
|
+
source = "";
|
|
1584
|
+
offset = -1;
|
|
1585
|
+
while (++offset < rule.length) {
|
|
1586
|
+
character = rule.charAt(offset);
|
|
1587
|
+
source += self.compoundRuleCodes[character].length ? "(?:" + self.compoundRuleCodes[character].join("|") + ")" : character;
|
|
1588
|
+
}
|
|
1589
|
+
self.compoundRules[index] = new RegExp(source, "i");
|
|
1590
|
+
}
|
|
1591
|
+
return self;
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
});
|
|
1595
|
+
|
|
1596
|
+
// node_modules/nspell/lib/personal.js
|
|
1597
|
+
var require_personal = __commonJS({
|
|
1598
|
+
"node_modules/nspell/lib/personal.js"(exports, module) {
|
|
1599
|
+
"use strict";
|
|
1600
|
+
module.exports = add;
|
|
1601
|
+
function add(buf) {
|
|
1602
|
+
var self = this;
|
|
1603
|
+
var lines = buf.toString("utf8").split("\n");
|
|
1604
|
+
var index = -1;
|
|
1605
|
+
var line;
|
|
1606
|
+
var forbidden;
|
|
1607
|
+
var word;
|
|
1608
|
+
var flag;
|
|
1609
|
+
if (self.flags.FORBIDDENWORD === void 0) self.flags.FORBIDDENWORD = false;
|
|
1610
|
+
flag = self.flags.FORBIDDENWORD;
|
|
1611
|
+
while (++index < lines.length) {
|
|
1612
|
+
line = lines[index].trim();
|
|
1613
|
+
if (!line) {
|
|
1614
|
+
continue;
|
|
1615
|
+
}
|
|
1616
|
+
line = line.split("/");
|
|
1617
|
+
word = line[0];
|
|
1618
|
+
forbidden = word.charAt(0) === "*";
|
|
1619
|
+
if (forbidden) {
|
|
1620
|
+
word = word.slice(1);
|
|
1621
|
+
}
|
|
1622
|
+
self.add(word, line[1]);
|
|
1623
|
+
if (forbidden) {
|
|
1624
|
+
self.data[word].push(flag);
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
return self;
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
});
|
|
1631
|
+
|
|
1632
|
+
// node_modules/nspell/lib/index.js
|
|
1633
|
+
var require_lib = __commonJS({
|
|
1634
|
+
"node_modules/nspell/lib/index.js"(exports, module) {
|
|
1635
|
+
"use strict";
|
|
1636
|
+
var buffer = require_is_buffer();
|
|
1637
|
+
var affix = require_affix();
|
|
1638
|
+
module.exports = NSpell2;
|
|
1639
|
+
var proto = NSpell2.prototype;
|
|
1640
|
+
proto.correct = require_correct();
|
|
1641
|
+
proto.suggest = require_suggest();
|
|
1642
|
+
proto.spell = require_spell();
|
|
1643
|
+
proto.add = require_add2();
|
|
1644
|
+
proto.remove = require_remove();
|
|
1645
|
+
proto.wordCharacters = require_word_characters();
|
|
1646
|
+
proto.dictionary = require_dictionary2();
|
|
1647
|
+
proto.personal = require_personal();
|
|
1648
|
+
function NSpell2(aff, dic) {
|
|
1649
|
+
var index = -1;
|
|
1650
|
+
var dictionaries;
|
|
1651
|
+
if (!(this instanceof NSpell2)) {
|
|
1652
|
+
return new NSpell2(aff, dic);
|
|
1653
|
+
}
|
|
1654
|
+
if (typeof aff === "string" || buffer(aff)) {
|
|
1655
|
+
if (typeof dic === "string" || buffer(dic)) {
|
|
1656
|
+
dictionaries = [{ dic }];
|
|
1657
|
+
}
|
|
1658
|
+
} else if (aff) {
|
|
1659
|
+
if ("length" in aff) {
|
|
1660
|
+
dictionaries = aff;
|
|
1661
|
+
aff = aff[0] && aff[0].aff;
|
|
1662
|
+
} else {
|
|
1663
|
+
if (aff.dic) {
|
|
1664
|
+
dictionaries = [aff];
|
|
1665
|
+
}
|
|
1666
|
+
aff = aff.aff;
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
if (!aff) {
|
|
1670
|
+
throw new Error("Missing `aff` in dictionary");
|
|
1671
|
+
}
|
|
1672
|
+
aff = affix(aff);
|
|
1673
|
+
this.data = /* @__PURE__ */ Object.create(null);
|
|
1674
|
+
this.compoundRuleCodes = aff.compoundRuleCodes;
|
|
1675
|
+
this.replacementTable = aff.replacementTable;
|
|
1676
|
+
this.conversion = aff.conversion;
|
|
1677
|
+
this.compoundRules = aff.compoundRules;
|
|
1678
|
+
this.rules = aff.rules;
|
|
1679
|
+
this.flags = aff.flags;
|
|
1680
|
+
if (dictionaries) {
|
|
1681
|
+
while (++index < dictionaries.length) {
|
|
1682
|
+
if (dictionaries[index].dic) {
|
|
1683
|
+
this.dictionary(dictionaries[index].dic);
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
});
|
|
1690
|
+
|
|
1691
|
+
// client/compose/spellcheck.js
|
|
1692
|
+
var spellcheck_exports = {};
|
|
1693
|
+
__export(spellcheck_exports, {
|
|
1694
|
+
wireSpellcheck: () => wireSpellcheck
|
|
1695
|
+
});
|
|
1696
|
+
async function getSpell() {
|
|
1697
|
+
if (spellPromise)
|
|
1698
|
+
return spellPromise;
|
|
1699
|
+
spellPromise = (async () => {
|
|
1700
|
+
const [affRes, dicRes] = await Promise.all([
|
|
1701
|
+
fetch("../lib/dict/en.aff"),
|
|
1702
|
+
fetch("../lib/dict/en.dic")
|
|
1703
|
+
]);
|
|
1704
|
+
if (!affRes.ok || !dicRes.ok) {
|
|
1705
|
+
throw new Error(`spellcheck: dict fetch failed (aff=${affRes.status} dic=${dicRes.status})`);
|
|
1706
|
+
}
|
|
1707
|
+
const [aff, dic] = await Promise.all([affRes.text(), dicRes.text()]);
|
|
1708
|
+
const sp = new import_nspell.default({ aff, dic });
|
|
1709
|
+
try {
|
|
1710
|
+
const raw = localStorage.getItem(USER_DICT_KEY);
|
|
1711
|
+
if (raw)
|
|
1712
|
+
for (const w of JSON.parse(raw))
|
|
1713
|
+
sp.add(w);
|
|
1714
|
+
} catch {
|
|
1715
|
+
}
|
|
1716
|
+
return sp;
|
|
1717
|
+
})();
|
|
1718
|
+
return spellPromise;
|
|
1719
|
+
}
|
|
1720
|
+
function addToUserDict(word, sp) {
|
|
1721
|
+
try {
|
|
1722
|
+
const raw = localStorage.getItem(USER_DICT_KEY);
|
|
1723
|
+
const arr = raw ? JSON.parse(raw) : [];
|
|
1724
|
+
if (arr.includes(word))
|
|
1725
|
+
return;
|
|
1726
|
+
arr.push(word);
|
|
1727
|
+
localStorage.setItem(USER_DICT_KEY, JSON.stringify(arr));
|
|
1728
|
+
} catch {
|
|
1729
|
+
}
|
|
1730
|
+
sp.add(word);
|
|
1731
|
+
}
|
|
1732
|
+
function wordAtPoint(doc, x, y) {
|
|
1733
|
+
const anyDoc = doc;
|
|
1734
|
+
let caretNode = null;
|
|
1735
|
+
let caretOffset = 0;
|
|
1736
|
+
if (typeof anyDoc.caretRangeFromPoint === "function") {
|
|
1737
|
+
const r = anyDoc.caretRangeFromPoint(x, y);
|
|
1738
|
+
if (!r)
|
|
1739
|
+
return null;
|
|
1740
|
+
caretNode = r.startContainer;
|
|
1741
|
+
caretOffset = r.startOffset;
|
|
1742
|
+
} else if (typeof anyDoc.caretPositionFromPoint === "function") {
|
|
1743
|
+
const p = anyDoc.caretPositionFromPoint(x, y);
|
|
1744
|
+
if (!p)
|
|
1745
|
+
return null;
|
|
1746
|
+
caretNode = p.offsetNode;
|
|
1747
|
+
caretOffset = p.offset;
|
|
1748
|
+
} else {
|
|
1749
|
+
return null;
|
|
1750
|
+
}
|
|
1751
|
+
if (!caretNode || caretNode.nodeType !== Node.TEXT_NODE)
|
|
1752
|
+
return null;
|
|
1753
|
+
const text = caretNode.data;
|
|
1754
|
+
const isWordChar = (ch) => /[\p{L}\p{N}'’\-]/u.test(ch);
|
|
1755
|
+
let start = caretOffset;
|
|
1756
|
+
let end = caretOffset;
|
|
1757
|
+
while (start > 0 && isWordChar(text[start - 1]))
|
|
1758
|
+
start--;
|
|
1759
|
+
while (end < text.length && isWordChar(text[end]))
|
|
1760
|
+
end++;
|
|
1761
|
+
if (start === end)
|
|
1762
|
+
return null;
|
|
1763
|
+
let word = text.slice(start, end);
|
|
1764
|
+
while (word.length && /^['’\-]/.test(word)) {
|
|
1765
|
+
word = word.slice(1);
|
|
1766
|
+
start++;
|
|
1767
|
+
}
|
|
1768
|
+
while (word.length && /['’\-]$/.test(word)) {
|
|
1769
|
+
word = word.slice(0, -1);
|
|
1770
|
+
end--;
|
|
1771
|
+
}
|
|
1772
|
+
if (!word)
|
|
1773
|
+
return null;
|
|
1774
|
+
const range = doc.createRange();
|
|
1775
|
+
range.setStart(caretNode, start);
|
|
1776
|
+
range.setEnd(caretNode, end);
|
|
1777
|
+
return { word, range };
|
|
1778
|
+
}
|
|
1779
|
+
function showSuggestionsMenu(parentDoc, x, y, items) {
|
|
1780
|
+
parentDoc.getElementById("mailx-spell-menu")?.remove();
|
|
1781
|
+
const menu = parentDoc.createElement("div");
|
|
1782
|
+
menu.id = "mailx-spell-menu";
|
|
1783
|
+
menu.style.cssText = `
|
|
1784
|
+
position: fixed;
|
|
1785
|
+
left: ${x}px; top: ${y}px;
|
|
1786
|
+
z-index: 10000;
|
|
1787
|
+
background: var(--color-bg, #fff);
|
|
1788
|
+
color: var(--color-text, #222);
|
|
1789
|
+
border: 1px solid var(--color-border, #ccc);
|
|
1790
|
+
border-radius: 6px;
|
|
1791
|
+
box-shadow: 0 4px 16px rgba(0,0,0,0.18);
|
|
1792
|
+
padding: 4px 0;
|
|
1793
|
+
font: 13px system-ui, sans-serif;
|
|
1794
|
+
min-width: 160px;
|
|
1795
|
+
max-width: 320px;
|
|
1796
|
+
`;
|
|
1797
|
+
for (const it of items) {
|
|
1798
|
+
if (it.label === "---") {
|
|
1799
|
+
const sep = parentDoc.createElement("div");
|
|
1800
|
+
sep.style.cssText = "border-top:1px solid var(--color-border,#ddd); margin: 4px 0;";
|
|
1801
|
+
menu.appendChild(sep);
|
|
1802
|
+
continue;
|
|
1803
|
+
}
|
|
1804
|
+
const btn = parentDoc.createElement("button");
|
|
1805
|
+
btn.type = "button";
|
|
1806
|
+
btn.textContent = it.label;
|
|
1807
|
+
btn.style.cssText = `
|
|
1808
|
+
display: block; width: 100%; text-align: left;
|
|
1809
|
+
padding: 5px 12px; border: none; background: none;
|
|
1810
|
+
color: inherit; cursor: pointer; font: inherit;
|
|
1811
|
+
${it.emphasized ? "font-weight: 600;" : ""}
|
|
1812
|
+
`;
|
|
1813
|
+
btn.addEventListener("mouseenter", () => {
|
|
1814
|
+
btn.style.background = "var(--color-bg-hover, #eef)";
|
|
1815
|
+
});
|
|
1816
|
+
btn.addEventListener("mouseleave", () => {
|
|
1817
|
+
btn.style.background = "none";
|
|
1818
|
+
});
|
|
1819
|
+
btn.addEventListener("click", () => {
|
|
1820
|
+
try {
|
|
1821
|
+
it.action();
|
|
1822
|
+
} finally {
|
|
1823
|
+
menu.remove();
|
|
1824
|
+
}
|
|
1825
|
+
});
|
|
1826
|
+
menu.appendChild(btn);
|
|
1827
|
+
}
|
|
1828
|
+
parentDoc.body.appendChild(menu);
|
|
1829
|
+
const r = menu.getBoundingClientRect();
|
|
1830
|
+
if (r.right > window.innerWidth)
|
|
1831
|
+
menu.style.left = `${Math.max(8, window.innerWidth - r.width - 8)}px`;
|
|
1832
|
+
if (r.bottom > window.innerHeight)
|
|
1833
|
+
menu.style.top = `${Math.max(8, window.innerHeight - r.height - 8)}px`;
|
|
1834
|
+
const dismiss2 = (e) => {
|
|
1835
|
+
if (e.type === "keydown" && e.key !== "Escape")
|
|
1836
|
+
return;
|
|
1837
|
+
if (e.type === "mousedown" && menu.contains(e.target))
|
|
1838
|
+
return;
|
|
1839
|
+
menu.remove();
|
|
1840
|
+
parentDoc.removeEventListener("mousedown", dismiss2, true);
|
|
1841
|
+
parentDoc.removeEventListener("keydown", dismiss2, true);
|
|
1842
|
+
};
|
|
1843
|
+
setTimeout(() => {
|
|
1844
|
+
parentDoc.addEventListener("mousedown", dismiss2, true);
|
|
1845
|
+
parentDoc.addEventListener("keydown", dismiss2, true);
|
|
1846
|
+
}, 0);
|
|
1847
|
+
}
|
|
1848
|
+
function replaceRange(doc, range, replacement) {
|
|
1849
|
+
const sel = doc.getSelection();
|
|
1850
|
+
if (!sel)
|
|
1851
|
+
return;
|
|
1852
|
+
sel.removeAllRanges();
|
|
1853
|
+
sel.addRange(range);
|
|
1854
|
+
try {
|
|
1855
|
+
if (!doc.execCommand("insertText", false, replacement)) {
|
|
1856
|
+
range.deleteContents();
|
|
1857
|
+
range.insertNode(doc.createTextNode(replacement));
|
|
1858
|
+
}
|
|
1859
|
+
} catch {
|
|
1860
|
+
range.deleteContents();
|
|
1861
|
+
range.insertNode(doc.createTextNode(replacement));
|
|
1862
|
+
}
|
|
1863
|
+
}
|
|
1864
|
+
function wireSpellcheck(editor2) {
|
|
1865
|
+
if (editor2.__mailxSpellWired)
|
|
1866
|
+
return;
|
|
1867
|
+
editor2.__mailxSpellWired = true;
|
|
1868
|
+
const iframeDoc = editor2.getDoc?.() || null;
|
|
1869
|
+
if (!iframeDoc)
|
|
1870
|
+
return;
|
|
1871
|
+
iframeDoc.addEventListener("contextmenu", (ev) => {
|
|
1872
|
+
const e = ev;
|
|
1873
|
+
const iframeEl = editor2.iframeElement;
|
|
1874
|
+
if (!iframeEl)
|
|
1875
|
+
return;
|
|
1876
|
+
const found = wordAtPoint(iframeDoc, e.clientX, e.clientY);
|
|
1877
|
+
if (!found)
|
|
1878
|
+
return;
|
|
1879
|
+
getSpell().then((sp) => {
|
|
1880
|
+
if (sp.correct(found.word))
|
|
1881
|
+
return;
|
|
1882
|
+
const sugs = sp.suggest(found.word).slice(0, 7);
|
|
1883
|
+
const iframeRect = iframeEl.getBoundingClientRect();
|
|
1884
|
+
const menuX = iframeRect.left + e.clientX;
|
|
1885
|
+
const menuY = iframeRect.top + e.clientY;
|
|
1886
|
+
const items = [];
|
|
1887
|
+
if (sugs.length === 0) {
|
|
1888
|
+
items.push({ label: "(no suggestions)", action: () => {
|
|
1889
|
+
} });
|
|
1890
|
+
} else {
|
|
1891
|
+
for (const s of sugs) {
|
|
1892
|
+
items.push({
|
|
1893
|
+
label: s,
|
|
1894
|
+
emphasized: true,
|
|
1895
|
+
action: () => replaceRange(iframeDoc, found.range, s)
|
|
1896
|
+
});
|
|
1897
|
+
}
|
|
1898
|
+
}
|
|
1899
|
+
items.push({ label: "---", action: () => {
|
|
1900
|
+
} });
|
|
1901
|
+
items.push({
|
|
1902
|
+
label: `Add "${found.word}" to dictionary`,
|
|
1903
|
+
action: () => addToUserDict(found.word, sp)
|
|
1904
|
+
});
|
|
1905
|
+
items.push({
|
|
1906
|
+
label: "Ignore (this session)",
|
|
1907
|
+
action: () => sp.add(found.word)
|
|
1908
|
+
});
|
|
1909
|
+
showSuggestionsMenu(document, menuX, menuY, items);
|
|
1910
|
+
}).catch((err) => {
|
|
1911
|
+
console.error("[spellcheck] dict load failed:", err);
|
|
1912
|
+
return;
|
|
1913
|
+
});
|
|
1914
|
+
e.preventDefault();
|
|
1915
|
+
e.stopPropagation();
|
|
1916
|
+
}, true);
|
|
1917
|
+
}
|
|
1918
|
+
var import_nspell, USER_DICT_KEY, spellPromise;
|
|
1919
|
+
var init_spellcheck = __esm({
|
|
1920
|
+
"client/compose/spellcheck.js"() {
|
|
1921
|
+
"use strict";
|
|
1922
|
+
import_nspell = __toESM(require_lib(), 1);
|
|
1923
|
+
USER_DICT_KEY = "mailx-user-dict";
|
|
1924
|
+
spellPromise = null;
|
|
1925
|
+
}
|
|
1926
|
+
});
|
|
1927
|
+
|
|
697
1928
|
// client/compose/ghost-text.js
|
|
698
1929
|
var ghost_text_exports = {};
|
|
699
1930
|
__export(ghost_text_exports, {
|
|
@@ -1714,7 +2945,16 @@ async function tryEditor(type) {
|
|
|
1714
2945
|
container.classList.remove("editor-tiptap", "editor-quill", "editor-tinymce");
|
|
1715
2946
|
container.classList.add(`editor-${type}`);
|
|
1716
2947
|
try {
|
|
1717
|
-
|
|
2948
|
+
const ed = await createEditor(container, type);
|
|
2949
|
+
if (type === "tinymce" && ed && ed.nativeEditor) {
|
|
2950
|
+
const native = ed.nativeEditor;
|
|
2951
|
+
const attach = () => {
|
|
2952
|
+
Promise.resolve().then(() => (init_spellcheck(), spellcheck_exports)).then((m) => m.wireSpellcheck(native)).catch((e) => console.error("[compose] spellcheck wire failed:", e));
|
|
2953
|
+
};
|
|
2954
|
+
if (native.initialized) attach();
|
|
2955
|
+
else native.on("init", attach);
|
|
2956
|
+
}
|
|
2957
|
+
return ed;
|
|
1718
2958
|
} catch (e) {
|
|
1719
2959
|
logClientEvent("compose-editor-create-failed", { type, error: String(e?.message || e) });
|
|
1720
2960
|
return null;
|
|
@@ -2873,4 +4113,14 @@ document.addEventListener("keydown", (e) => {
|
|
|
2873
4113
|
}
|
|
2874
4114
|
}
|
|
2875
4115
|
});
|
|
4116
|
+
/*! Bundled license information:
|
|
4117
|
+
|
|
4118
|
+
is-buffer/index.js:
|
|
4119
|
+
(*!
|
|
4120
|
+
* Determine if an object is a Buffer
|
|
4121
|
+
*
|
|
4122
|
+
* @author Feross Aboukhadijeh <https://feross.org>
|
|
4123
|
+
* @license MIT
|
|
4124
|
+
*)
|
|
4125
|
+
*/
|
|
2876
4126
|
//# sourceMappingURL=compose.bundle.js.map
|