@subconverter/core 0.1.0 → 0.2.1
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/LICENSE +674 -0
- package/README.md +69 -0
- package/dist/index.cjs +1442 -281
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +227 -2
- package/dist/index.d.ts +227 -2
- package/dist/index.js +1442 -281
- package/dist/index.js.map +1 -1
- package/package.json +24 -1
package/dist/index.js
CHANGED
|
@@ -31,6 +31,23 @@ function createProxyGroupConfig() {
|
|
|
31
31
|
usingProvider: []
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
|
+
function createSelectGroup(name) {
|
|
35
|
+
return {
|
|
36
|
+
disableUdp: void 0,
|
|
37
|
+
evaluateBeforeUse: void 0,
|
|
38
|
+
interval: 0,
|
|
39
|
+
lazy: void 0,
|
|
40
|
+
name,
|
|
41
|
+
persistent: void 0,
|
|
42
|
+
proxies: ["[]DIRECT", "!!TYPE=SS", "!!TYPE=SSR", "!!TYPE=VMESS", "!!TYPE=TROJAN"],
|
|
43
|
+
strategy: "consistent-hashing" /* ConsistentHashing */,
|
|
44
|
+
timeout: 0,
|
|
45
|
+
tolerance: 0,
|
|
46
|
+
type: "select" /* Select */,
|
|
47
|
+
url: "",
|
|
48
|
+
usingProvider: []
|
|
49
|
+
};
|
|
50
|
+
}
|
|
34
51
|
function parseProxyGroupType(value) {
|
|
35
52
|
const normalized = value.trim().toLowerCase();
|
|
36
53
|
switch (normalized) {
|
|
@@ -170,6 +187,7 @@ function createProxy() {
|
|
|
170
187
|
selfIp: "",
|
|
171
188
|
selfIpv6: "",
|
|
172
189
|
serverName: "",
|
|
190
|
+
shortId: "",
|
|
173
191
|
snellVersion: 0,
|
|
174
192
|
sni: "",
|
|
175
193
|
tcpFastOpen: void 0,
|
|
@@ -205,6 +223,7 @@ var TargetFormat = /* @__PURE__ */ ((TargetFormat2) => {
|
|
|
205
223
|
TargetFormat2["Clash"] = "clash";
|
|
206
224
|
TargetFormat2["ClashR"] = "clashr";
|
|
207
225
|
TargetFormat2["Surge"] = "surge";
|
|
226
|
+
TargetFormat2["Surfboard"] = "surfboard";
|
|
208
227
|
TargetFormat2["QuantumultX"] = "quanx";
|
|
209
228
|
TargetFormat2["Quantumult"] = "quan";
|
|
210
229
|
TargetFormat2["Loon"] = "loon";
|
|
@@ -213,6 +232,7 @@ var TargetFormat = /* @__PURE__ */ ((TargetFormat2) => {
|
|
|
213
232
|
TargetFormat2["Trojan"] = "trojan";
|
|
214
233
|
TargetFormat2["SSD"] = "ssd";
|
|
215
234
|
TargetFormat2["SSC"] = "ss";
|
|
235
|
+
TargetFormat2["SSSub"] = "sssub";
|
|
216
236
|
TargetFormat2["SSR"] = "ssr";
|
|
217
237
|
TargetFormat2["SingBox"] = "singbox";
|
|
218
238
|
TargetFormat2["Mixed"] = "mixed";
|
|
@@ -225,16 +245,21 @@ function createExtraSettings() {
|
|
|
225
245
|
addEmoji: false,
|
|
226
246
|
appendProxyType: false,
|
|
227
247
|
authorized: false,
|
|
248
|
+
autoCountry: false,
|
|
228
249
|
clashClassicalRuleset: false,
|
|
229
|
-
clashNewFieldName:
|
|
250
|
+
clashNewFieldName: true,
|
|
230
251
|
clashProxiesStyle: "flow",
|
|
231
252
|
clashProxyGroupsStyle: "flow",
|
|
232
253
|
clashScript: false,
|
|
254
|
+
countryLocale: "zh-CN",
|
|
255
|
+
countryResolver: void 0,
|
|
233
256
|
dedupe: false,
|
|
234
257
|
emojiArray: [],
|
|
235
258
|
enableRuleGenerator: true,
|
|
236
259
|
filterDeprecated: false,
|
|
237
260
|
managedConfigPrefix: "",
|
|
261
|
+
nameRegexArray: [],
|
|
262
|
+
nameRemove: [],
|
|
238
263
|
nodeList: false,
|
|
239
264
|
overwriteOriginalRules: true,
|
|
240
265
|
quanxDevId: "",
|
|
@@ -540,27 +565,35 @@ function urlEncode(input) {
|
|
|
540
565
|
(char) => `%${char.charCodeAt(0).toString(16).toUpperCase()}`
|
|
541
566
|
);
|
|
542
567
|
}
|
|
543
|
-
function
|
|
568
|
+
function normalizeQueryKey(key) {
|
|
569
|
+
return key.toLowerCase().replace(/_/g, "-");
|
|
570
|
+
}
|
|
571
|
+
function getAllUrlArgs(query, key) {
|
|
544
572
|
if (query === "") {
|
|
545
|
-
return
|
|
546
|
-
}
|
|
547
|
-
const
|
|
548
|
-
const
|
|
549
|
-
|
|
550
|
-
const
|
|
551
|
-
|
|
573
|
+
return [];
|
|
574
|
+
}
|
|
575
|
+
const hashCut = query.split("#", 1)[0];
|
|
576
|
+
const qIndex = hashCut.indexOf("?");
|
|
577
|
+
const rawQuery = qIndex >= 0 ? hashCut.slice(qIndex + 1) : hashCut;
|
|
578
|
+
const normalized = rawQuery.startsWith("?") ? rawQuery.slice(1) : rawQuery;
|
|
579
|
+
const values = [];
|
|
580
|
+
const target = normalizeQueryKey(key);
|
|
581
|
+
for (const part of normalized.split("&")) {
|
|
552
582
|
if (part === "") {
|
|
553
583
|
continue;
|
|
554
584
|
}
|
|
555
585
|
const eq = part.indexOf("=");
|
|
556
586
|
const rawKey = eq >= 0 ? part.slice(0, eq) : part;
|
|
557
|
-
if (rawKey
|
|
587
|
+
if (normalizeQueryKey(urlDecode(rawKey)) !== target) {
|
|
558
588
|
continue;
|
|
559
589
|
}
|
|
560
|
-
|
|
561
|
-
found = urlDecode(rawValue);
|
|
590
|
+
values.push(urlDecode(eq >= 0 ? part.slice(eq + 1) : ""));
|
|
562
591
|
}
|
|
563
|
-
return
|
|
592
|
+
return values;
|
|
593
|
+
}
|
|
594
|
+
function getUrlArg(query, key) {
|
|
595
|
+
const values = getAllUrlArgs(query, key);
|
|
596
|
+
return values.length > 0 ? values[values.length - 1].trim() : "";
|
|
564
597
|
}
|
|
565
598
|
function splitUrl(raw) {
|
|
566
599
|
const hashIndex = raw.indexOf("#");
|
|
@@ -636,7 +669,7 @@ function parseCustomProxyGroup(value) {
|
|
|
636
669
|
if (type === void 0) {
|
|
637
670
|
return void 0;
|
|
638
671
|
}
|
|
639
|
-
const
|
|
672
|
+
const group2 = {
|
|
640
673
|
disableUdp: void 0,
|
|
641
674
|
evaluateBeforeUse: void 0,
|
|
642
675
|
interval: 0,
|
|
@@ -657,29 +690,29 @@ function parseCustomProxyGroup(value) {
|
|
|
657
690
|
return void 0;
|
|
658
691
|
}
|
|
659
692
|
upperBound -= 2;
|
|
660
|
-
|
|
693
|
+
group2.url = parts[upperBound];
|
|
661
694
|
const times = parseGroupTimes(parts[upperBound + 1]);
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
695
|
+
group2.interval = times.interval;
|
|
696
|
+
group2.timeout = times.timeout;
|
|
697
|
+
group2.tolerance = times.tolerance;
|
|
665
698
|
}
|
|
666
699
|
for (let i = 2; i < upperBound; i += 1) {
|
|
667
700
|
const rule = parts[i];
|
|
668
701
|
if (startsWith(rule, "!!PROVIDER=")) {
|
|
669
|
-
|
|
702
|
+
group2.usingProvider.push(...rule.slice(11).split(","));
|
|
670
703
|
} else {
|
|
671
|
-
|
|
704
|
+
group2.proxies.push(rule);
|
|
672
705
|
}
|
|
673
706
|
}
|
|
674
|
-
return
|
|
707
|
+
return group2;
|
|
675
708
|
}
|
|
676
709
|
function parseRulesetConfig(value) {
|
|
677
710
|
const pos = value.indexOf(",");
|
|
678
711
|
if (pos === -1) {
|
|
679
712
|
return void 0;
|
|
680
713
|
}
|
|
681
|
-
const
|
|
682
|
-
const config = { group, interval: 86400, url: "" };
|
|
714
|
+
const group2 = value.slice(0, pos);
|
|
715
|
+
const config = { group: group2, interval: 86400, url: "" };
|
|
683
716
|
if (value.slice(pos + 1, pos + 3) === "[]") {
|
|
684
717
|
config.url = value.slice(pos + 1);
|
|
685
718
|
return config;
|
|
@@ -705,12 +738,15 @@ function parseRegexMatch(value, delimiter) {
|
|
|
705
738
|
function parseExternalConfig(content) {
|
|
706
739
|
const result = {
|
|
707
740
|
addEmoji: false,
|
|
741
|
+
autoCountry: false,
|
|
708
742
|
baseFiles: {},
|
|
709
743
|
emoji: [],
|
|
710
744
|
enableRuleGenerator: true,
|
|
711
745
|
excludeRemarks: [],
|
|
712
746
|
groups: [],
|
|
713
747
|
includeRemarks: [],
|
|
748
|
+
nameRegex: [],
|
|
749
|
+
nameRemove: [],
|
|
714
750
|
overwriteOriginalRules: true,
|
|
715
751
|
removeEmoji: false,
|
|
716
752
|
rename: [],
|
|
@@ -755,6 +791,17 @@ function parseExternalConfig(content) {
|
|
|
755
791
|
case "rename_node":
|
|
756
792
|
result.rename.push(parseRegexMatch(value, "@"));
|
|
757
793
|
break;
|
|
794
|
+
case "name_regex":
|
|
795
|
+
result.nameRegex.push(parseRegexMatch(value, "@"));
|
|
796
|
+
break;
|
|
797
|
+
case "name_remove":
|
|
798
|
+
for (const fragment of value.split(",")) {
|
|
799
|
+
const trimmed = fragment.trim();
|
|
800
|
+
if (trimmed !== "") {
|
|
801
|
+
result.nameRemove.push(trimmed);
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
break;
|
|
758
805
|
case "emoji":
|
|
759
806
|
case "emojis":
|
|
760
807
|
result.emoji.push(parseRegexMatch(value, ","));
|
|
@@ -774,6 +821,10 @@ function parseExternalConfig(content) {
|
|
|
774
821
|
case "add_emoji":
|
|
775
822
|
result.addEmoji = value.toLowerCase() === "true";
|
|
776
823
|
break;
|
|
824
|
+
case "auto_country":
|
|
825
|
+
case "country":
|
|
826
|
+
result.autoCountry = value.toLowerCase() === "true";
|
|
827
|
+
break;
|
|
777
828
|
case "remove_old_emoji":
|
|
778
829
|
case "remove_emoji":
|
|
779
830
|
result.removeEmoji = value.toLowerCase() === "true";
|
|
@@ -797,7 +848,13 @@ function parseExternalConfig(content) {
|
|
|
797
848
|
|
|
798
849
|
// src/settings/request-params.ts
|
|
799
850
|
var TARGETS = new Set(Object.values(TargetFormat));
|
|
851
|
+
function hasArg(query, key) {
|
|
852
|
+
return getAllUrlArgs(query, key).length > 0;
|
|
853
|
+
}
|
|
800
854
|
function boolArg(query, key) {
|
|
855
|
+
if (!hasArg(query, key)) {
|
|
856
|
+
return false;
|
|
857
|
+
}
|
|
801
858
|
const value = getUrlArg(query, key).toLowerCase();
|
|
802
859
|
return value === "true" || value === "1" || value === "";
|
|
803
860
|
}
|
|
@@ -809,13 +866,47 @@ function listArg(query, key) {
|
|
|
809
866
|
const value = getUrlArg(query, key);
|
|
810
867
|
return value === "" ? [] : value.split(",");
|
|
811
868
|
}
|
|
869
|
+
function resolveNewFieldName(query) {
|
|
870
|
+
if (boolArg(query, "legacy") || boolArg(query, "legacy_field_name") || boolArg(query, "legacy-field-name")) {
|
|
871
|
+
return false;
|
|
872
|
+
}
|
|
873
|
+
if (hasArg(query, "new_name") || hasArg(query, "new_field_name") || hasArg(query, "new-name") || hasArg(query, "new-field-name")) {
|
|
874
|
+
return boolArg(query, "new_name") || boolArg(query, "new_field_name") || boolArg(query, "new-name") || boolArg(query, "new-field-name");
|
|
875
|
+
}
|
|
876
|
+
return true;
|
|
877
|
+
}
|
|
878
|
+
function firstArg(query, ...keys) {
|
|
879
|
+
for (const key of keys) {
|
|
880
|
+
const value = getUrlArg(query, key);
|
|
881
|
+
if (value !== "") {
|
|
882
|
+
return value;
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
return "";
|
|
886
|
+
}
|
|
887
|
+
function queryBoolFlag(query, ...keys) {
|
|
888
|
+
let found = false;
|
|
889
|
+
let result = false;
|
|
890
|
+
for (const key of keys) {
|
|
891
|
+
for (const raw of getAllUrlArgs(query, key)) {
|
|
892
|
+
found = true;
|
|
893
|
+
const normalized = raw.trim().toLowerCase();
|
|
894
|
+
if (normalized === "" || normalized === "true" || normalized === "1") {
|
|
895
|
+
result = true;
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
return found ? result : void 0;
|
|
900
|
+
}
|
|
812
901
|
function createRequestSettings() {
|
|
813
902
|
return {
|
|
814
903
|
addEmoji: false,
|
|
815
904
|
appendType: false,
|
|
905
|
+
autoCountry: false,
|
|
816
906
|
autoExtract: false,
|
|
817
907
|
clashScript: false,
|
|
818
908
|
classicalRuleset: false,
|
|
909
|
+
dedupe: false,
|
|
819
910
|
emoji: [],
|
|
820
911
|
excludeRemarks: [],
|
|
821
912
|
filterDeprecated: false,
|
|
@@ -825,7 +916,9 @@ function createRequestSettings() {
|
|
|
825
916
|
interval: 0,
|
|
826
917
|
list: false,
|
|
827
918
|
mixin: "",
|
|
828
|
-
|
|
919
|
+
nameRegex: [],
|
|
920
|
+
nameRemove: [],
|
|
921
|
+
newFieldName: true,
|
|
829
922
|
nodeList: false,
|
|
830
923
|
proxiesStyle: "flow",
|
|
831
924
|
proxyGroupsStyle: "flow",
|
|
@@ -840,7 +933,9 @@ function createRequestSettings() {
|
|
|
840
933
|
tls13: void 0,
|
|
841
934
|
udp: void 0,
|
|
842
935
|
uploadPath: "",
|
|
843
|
-
url: ""
|
|
936
|
+
url: "",
|
|
937
|
+
userinfoProvider: "",
|
|
938
|
+
userinfoUrl: ""
|
|
844
939
|
};
|
|
845
940
|
}
|
|
846
941
|
function parseRequestSettings(query) {
|
|
@@ -852,11 +947,14 @@ function parseRequestSettings(query) {
|
|
|
852
947
|
settings.url = getUrlArg(query, "url");
|
|
853
948
|
settings.list = boolArg(query, "list");
|
|
854
949
|
settings.nodeList = settings.list;
|
|
950
|
+
settings.sort = queryBoolFlag(query, "sort", "sort_flag", "sort-flag") ?? false;
|
|
951
|
+
settings.dedupe = queryBoolFlag(query, "dedupe", "deduplicate") ?? false;
|
|
855
952
|
settings.addEmoji = boolArg(query, "add_emoji");
|
|
856
953
|
settings.removeEmoji = boolArg(query, "remove_emoji");
|
|
954
|
+
settings.autoCountry = boolArg(query, "auto_country");
|
|
857
955
|
settings.appendType = boolArg(query, "append_type");
|
|
858
956
|
settings.filterDeprecated = boolArg(query, "filter_deprecated");
|
|
859
|
-
settings.newFieldName =
|
|
957
|
+
settings.newFieldName = resolveNewFieldName(query);
|
|
860
958
|
settings.classicalRuleset = boolArg(query, "classical");
|
|
861
959
|
settings.insert = getUrlArg(query, "insert") !== "";
|
|
862
960
|
settings.clashScript = boolArg(query, "clash_script");
|
|
@@ -873,10 +971,20 @@ function parseRequestSettings(query) {
|
|
|
873
971
|
settings.proxyGroupsStyle = getUrlArg(query, "proxy_groups_style") || "flow";
|
|
874
972
|
settings.includeRemarks = listArg(query, "include");
|
|
875
973
|
settings.excludeRemarks = listArg(query, "exclude");
|
|
974
|
+
settings.userinfoUrl = firstArg(query, "userinfo_url", "userinfo-url", "userinfo");
|
|
975
|
+
settings.userinfoProvider = firstArg(
|
|
976
|
+
query,
|
|
977
|
+
"userinfo_provider",
|
|
978
|
+
"userinfo-provider",
|
|
979
|
+
"userinfo_type",
|
|
980
|
+
"userinfo-type"
|
|
981
|
+
);
|
|
876
982
|
const renameRaw = getUrlArg(query, "rename");
|
|
877
983
|
if (renameRaw !== "") {
|
|
878
984
|
settings.rename = [parseRegexMatch(renameRaw, "@")];
|
|
879
985
|
}
|
|
986
|
+
settings.nameRegex = getAllUrlArgs(query, "name_regex").flatMap((raw) => raw.split("\n")).map((raw) => raw.trim()).filter((raw) => raw !== "").map((raw) => parseRegexMatch(raw, "@"));
|
|
987
|
+
settings.nameRemove = getAllUrlArgs(query, "name_remove").flatMap((raw) => raw.split(",")).map((raw) => raw.trim()).filter((raw) => raw !== "");
|
|
880
988
|
const emojiRaw = getUrlArg(query, "emoji");
|
|
881
989
|
if (emojiRaw !== "") {
|
|
882
990
|
settings.emoji = [parseRegexMatch(emojiRaw, ",")];
|
|
@@ -884,6 +992,235 @@ function parseRequestSettings(query) {
|
|
|
884
992
|
return settings;
|
|
885
993
|
}
|
|
886
994
|
|
|
995
|
+
// src/userinfo.ts
|
|
996
|
+
var PROVIDER_ALIASES = {
|
|
997
|
+
auto: "auto",
|
|
998
|
+
clash: "subscription",
|
|
999
|
+
jms: "jms",
|
|
1000
|
+
"just-my-socks": "jms",
|
|
1001
|
+
justmysocks: "jms",
|
|
1002
|
+
raw: "subscription",
|
|
1003
|
+
sub: "subscription",
|
|
1004
|
+
subscription: "subscription",
|
|
1005
|
+
"subscription-userinfo": "subscription"
|
|
1006
|
+
};
|
|
1007
|
+
function normalizeUserinfoProvider(provider) {
|
|
1008
|
+
if (!provider) {
|
|
1009
|
+
return "auto";
|
|
1010
|
+
}
|
|
1011
|
+
const key = provider.trim().toLowerCase().replace(/_/g, "-");
|
|
1012
|
+
return PROVIDER_ALIASES[key] ?? "auto";
|
|
1013
|
+
}
|
|
1014
|
+
function inferUserinfoProviderFromUrl(url) {
|
|
1015
|
+
const squished = url.trim().toLowerCase().replace(/[-_]/g, "");
|
|
1016
|
+
if (squished.includes("justmysocks") || squished.includes("jmssub") || squished.includes("getbwcounter")) {
|
|
1017
|
+
return "jms";
|
|
1018
|
+
}
|
|
1019
|
+
return void 0;
|
|
1020
|
+
}
|
|
1021
|
+
function toNonNegativeNumber(value) {
|
|
1022
|
+
if (typeof value === "number") {
|
|
1023
|
+
return Number.isFinite(value) && value > 0 ? Math.trunc(value) : 0;
|
|
1024
|
+
}
|
|
1025
|
+
if (typeof value === "string") {
|
|
1026
|
+
const parsed = toInt(value);
|
|
1027
|
+
return parsed > 0 ? parsed : 0;
|
|
1028
|
+
}
|
|
1029
|
+
return 0;
|
|
1030
|
+
}
|
|
1031
|
+
function daysInUtcMonth(year, month) {
|
|
1032
|
+
return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
|
|
1033
|
+
}
|
|
1034
|
+
var DECIMAL_TO_BINARY = 1024 ** 3 / 1e3 ** 3;
|
|
1035
|
+
function scaleDecimalBytes(value) {
|
|
1036
|
+
return Math.round(value * DECIMAL_TO_BINARY);
|
|
1037
|
+
}
|
|
1038
|
+
function scaleUserinfoDecimal(data) {
|
|
1039
|
+
return {
|
|
1040
|
+
download: scaleDecimalBytes(data.download),
|
|
1041
|
+
expire: data.expire,
|
|
1042
|
+
total: scaleDecimalBytes(data.total),
|
|
1043
|
+
upload: scaleDecimalBytes(data.upload)
|
|
1044
|
+
};
|
|
1045
|
+
}
|
|
1046
|
+
function nextMonthlyResetTimestamp(resetDay, nowSec) {
|
|
1047
|
+
const day = Math.trunc(resetDay);
|
|
1048
|
+
if (!Number.isFinite(day) || day < 1 || day > 31) {
|
|
1049
|
+
return 0;
|
|
1050
|
+
}
|
|
1051
|
+
const now = nowSec && nowSec > 0 ? Math.trunc(nowSec) : Math.trunc(Date.now() / 1e3);
|
|
1052
|
+
const current = new Date(now * 1e3);
|
|
1053
|
+
const year = current.getUTCFullYear();
|
|
1054
|
+
const month = current.getUTCMonth();
|
|
1055
|
+
const today = current.getUTCDate();
|
|
1056
|
+
const useCurrentMonth = today < day;
|
|
1057
|
+
const targetYear = useCurrentMonth ? year : month === 11 ? year + 1 : year;
|
|
1058
|
+
const targetMonth = useCurrentMonth ? month : (month + 1) % 12;
|
|
1059
|
+
const clampedDay = Math.min(day, daysInUtcMonth(targetYear, targetMonth));
|
|
1060
|
+
return Math.trunc(Date.UTC(targetYear, targetMonth, clampedDay) / 1e3);
|
|
1061
|
+
}
|
|
1062
|
+
function parseJmsUserinfo(raw, nowSec) {
|
|
1063
|
+
let parsed;
|
|
1064
|
+
try {
|
|
1065
|
+
parsed = JSON.parse(raw);
|
|
1066
|
+
} catch {
|
|
1067
|
+
return void 0;
|
|
1068
|
+
}
|
|
1069
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
1070
|
+
return void 0;
|
|
1071
|
+
}
|
|
1072
|
+
const record = parsed;
|
|
1073
|
+
const hasJmsKeys = record["monthly_bw_limit_b"] !== void 0 || record["monthlyBwLimitB"] !== void 0 || record["bw_counter_b"] !== void 0 || record["bwCounterB"] !== void 0 || record["bw_reset_day_of_month"] !== void 0 || record["bwResetDayOfMonth"] !== void 0;
|
|
1074
|
+
if (!hasJmsKeys) {
|
|
1075
|
+
return void 0;
|
|
1076
|
+
}
|
|
1077
|
+
const limitRaw = record["monthly_bw_limit_b"] ?? record["monthlyBwLimitB"];
|
|
1078
|
+
const usedRaw = record["bw_counter_b"] ?? record["bwCounterB"];
|
|
1079
|
+
const resetRaw = record["bw_reset_day_of_month"] ?? record["bwResetDayOfMonth"] ?? record["reset_day"] ?? record["resetDay"];
|
|
1080
|
+
const payload = {
|
|
1081
|
+
bwCounterB: usedRaw,
|
|
1082
|
+
bwResetDayOfMonth: resetRaw,
|
|
1083
|
+
monthlyBwLimitB: limitRaw
|
|
1084
|
+
};
|
|
1085
|
+
const total = scaleDecimalBytes(toNonNegativeNumber(payload.monthlyBwLimitB));
|
|
1086
|
+
const download = scaleDecimalBytes(toNonNegativeNumber(payload.bwCounterB));
|
|
1087
|
+
const resetDay = toInt(
|
|
1088
|
+
typeof payload.bwResetDayOfMonth === "number" ? String(payload.bwResetDayOfMonth) : payload.bwResetDayOfMonth ?? ""
|
|
1089
|
+
);
|
|
1090
|
+
return {
|
|
1091
|
+
download,
|
|
1092
|
+
expire: resetDay > 0 ? nextMonthlyResetTimestamp(resetDay, nowSec) : 0,
|
|
1093
|
+
total,
|
|
1094
|
+
upload: 0
|
|
1095
|
+
};
|
|
1096
|
+
}
|
|
1097
|
+
function parseSubscriptionUserinfo(header) {
|
|
1098
|
+
if (!header || header.trim() === "") {
|
|
1099
|
+
return void 0;
|
|
1100
|
+
}
|
|
1101
|
+
const data = { download: 0, expire: 0, total: 0, upload: 0 };
|
|
1102
|
+
let found = false;
|
|
1103
|
+
for (const part of header.split(";")) {
|
|
1104
|
+
const eq = part.indexOf("=");
|
|
1105
|
+
if (eq === -1) {
|
|
1106
|
+
continue;
|
|
1107
|
+
}
|
|
1108
|
+
const key = part.slice(0, eq).trim().toLowerCase();
|
|
1109
|
+
const value = part.slice(eq + 1).trim();
|
|
1110
|
+
if (value === "") {
|
|
1111
|
+
continue;
|
|
1112
|
+
}
|
|
1113
|
+
switch (key) {
|
|
1114
|
+
case "download":
|
|
1115
|
+
case "down":
|
|
1116
|
+
data.download = toNonNegativeNumber(toInt(value));
|
|
1117
|
+
found = true;
|
|
1118
|
+
break;
|
|
1119
|
+
case "expire":
|
|
1120
|
+
case "expires":
|
|
1121
|
+
data.expire = toNonNegativeNumber(toInt(value));
|
|
1122
|
+
found = true;
|
|
1123
|
+
break;
|
|
1124
|
+
case "total":
|
|
1125
|
+
case "limit":
|
|
1126
|
+
data.total = toNonNegativeNumber(toInt(value));
|
|
1127
|
+
found = true;
|
|
1128
|
+
break;
|
|
1129
|
+
case "upload":
|
|
1130
|
+
case "up":
|
|
1131
|
+
data.upload = toNonNegativeNumber(toInt(value));
|
|
1132
|
+
found = true;
|
|
1133
|
+
break;
|
|
1134
|
+
default:
|
|
1135
|
+
break;
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
return found ? data : void 0;
|
|
1139
|
+
}
|
|
1140
|
+
function formatSubscriptionUserinfo(data) {
|
|
1141
|
+
const upload = toNonNegativeNumber(data.upload);
|
|
1142
|
+
const download = toNonNegativeNumber(data.download);
|
|
1143
|
+
const total = toNonNegativeNumber(data.total);
|
|
1144
|
+
const expire = toNonNegativeNumber(data.expire);
|
|
1145
|
+
return `upload=${upload}; download=${download}; total=${total}; expire=${expire}`;
|
|
1146
|
+
}
|
|
1147
|
+
function parseGenericJsonUserinfo(raw) {
|
|
1148
|
+
let parsed;
|
|
1149
|
+
try {
|
|
1150
|
+
parsed = JSON.parse(raw);
|
|
1151
|
+
} catch {
|
|
1152
|
+
return void 0;
|
|
1153
|
+
}
|
|
1154
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
1155
|
+
return void 0;
|
|
1156
|
+
}
|
|
1157
|
+
const record = parsed;
|
|
1158
|
+
const pick = (...keys) => {
|
|
1159
|
+
for (const key of keys) {
|
|
1160
|
+
if (record[key] !== void 0) {
|
|
1161
|
+
return record[key];
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
return void 0;
|
|
1165
|
+
};
|
|
1166
|
+
const uploadRaw = pick("upload", "upload_b", "up", "u");
|
|
1167
|
+
const downloadRaw = pick(
|
|
1168
|
+
"download",
|
|
1169
|
+
"download_b",
|
|
1170
|
+
"down",
|
|
1171
|
+
"d",
|
|
1172
|
+
"used",
|
|
1173
|
+
"bw_counter_b",
|
|
1174
|
+
"bwCounterB"
|
|
1175
|
+
);
|
|
1176
|
+
const totalRaw = pick(
|
|
1177
|
+
"total",
|
|
1178
|
+
"total_b",
|
|
1179
|
+
"limit",
|
|
1180
|
+
"bandwidth",
|
|
1181
|
+
"monthly_bw_limit_b",
|
|
1182
|
+
"monthlyBwLimitB"
|
|
1183
|
+
);
|
|
1184
|
+
const expireRaw = pick("expire", "expires", "expire_at", "expireAt", "reset");
|
|
1185
|
+
if (uploadRaw === void 0 && downloadRaw === void 0 && totalRaw === void 0) {
|
|
1186
|
+
return void 0;
|
|
1187
|
+
}
|
|
1188
|
+
return {
|
|
1189
|
+
download: toNonNegativeNumber(downloadRaw),
|
|
1190
|
+
expire: toNonNegativeNumber(expireRaw),
|
|
1191
|
+
total: toNonNegativeNumber(totalRaw),
|
|
1192
|
+
upload: toNonNegativeNumber(uploadRaw)
|
|
1193
|
+
};
|
|
1194
|
+
}
|
|
1195
|
+
function convertUserinfo(raw, provider, nowSec) {
|
|
1196
|
+
if (!raw || raw.trim() === "") {
|
|
1197
|
+
return void 0;
|
|
1198
|
+
}
|
|
1199
|
+
const normalized = normalizeUserinfoProvider(provider);
|
|
1200
|
+
if (normalized === "jms") {
|
|
1201
|
+
const jms2 = parseJmsUserinfo(raw, nowSec);
|
|
1202
|
+
if (jms2) {
|
|
1203
|
+
return formatSubscriptionUserinfo(jms2);
|
|
1204
|
+
}
|
|
1205
|
+
const generic2 = parseGenericJsonUserinfo(raw);
|
|
1206
|
+
return generic2 ? formatSubscriptionUserinfo(scaleUserinfoDecimal(generic2)) : void 0;
|
|
1207
|
+
}
|
|
1208
|
+
if (normalized === "subscription") {
|
|
1209
|
+
const parsed = parseSubscriptionUserinfo(raw) ?? parseGenericJsonUserinfo(raw);
|
|
1210
|
+
return parsed ? formatSubscriptionUserinfo(parsed) : void 0;
|
|
1211
|
+
}
|
|
1212
|
+
const jms = parseJmsUserinfo(raw, nowSec);
|
|
1213
|
+
if (jms) {
|
|
1214
|
+
return formatSubscriptionUserinfo(jms);
|
|
1215
|
+
}
|
|
1216
|
+
const generic = parseGenericJsonUserinfo(raw);
|
|
1217
|
+
if (generic) {
|
|
1218
|
+
return formatSubscriptionUserinfo(generic);
|
|
1219
|
+
}
|
|
1220
|
+
const header = parseSubscriptionUserinfo(raw);
|
|
1221
|
+
return header ? formatSubscriptionUserinfo(header) : void 0;
|
|
1222
|
+
}
|
|
1223
|
+
|
|
887
1224
|
// src/parser/ciphers.ts
|
|
888
1225
|
var SS_CIPHERS = [
|
|
889
1226
|
"2022-blake3-aes-128-gcm",
|
|
@@ -943,9 +1280,9 @@ function isFlattenableSsr(method, obfs, protocol) {
|
|
|
943
1280
|
}
|
|
944
1281
|
|
|
945
1282
|
// src/parser/construct.ts
|
|
946
|
-
function commonConstruct(node, type,
|
|
1283
|
+
function commonConstruct(node, type, group2, remark, server, port, udp, tfo, scv, tls13, underlyingProxy) {
|
|
947
1284
|
node.type = type;
|
|
948
|
-
node.group =
|
|
1285
|
+
node.group = group2;
|
|
949
1286
|
node.remark = remark;
|
|
950
1287
|
node.hostname = server;
|
|
951
1288
|
node.underlyingProxy = underlyingProxy;
|
|
@@ -961,7 +1298,7 @@ function vmessConstruct(node, options) {
|
|
|
961
1298
|
aid = 0,
|
|
962
1299
|
cipher = "",
|
|
963
1300
|
edge = "",
|
|
964
|
-
group,
|
|
1301
|
+
group: group2,
|
|
965
1302
|
host = "",
|
|
966
1303
|
id = "",
|
|
967
1304
|
net = "",
|
|
@@ -980,7 +1317,7 @@ function vmessConstruct(node, options) {
|
|
|
980
1317
|
commonConstruct(
|
|
981
1318
|
node,
|
|
982
1319
|
"vmess" /* VMess */,
|
|
983
|
-
|
|
1320
|
+
group2,
|
|
984
1321
|
remark,
|
|
985
1322
|
add,
|
|
986
1323
|
port,
|
|
@@ -1277,6 +1614,8 @@ function vlessConstruct(node, options) {
|
|
|
1277
1614
|
node.host = options.host ?? "";
|
|
1278
1615
|
node.path = options.path ?? "";
|
|
1279
1616
|
node.fingerprint = options.fingerprint ?? "";
|
|
1617
|
+
node.publicKey = options.publicKey ?? "";
|
|
1618
|
+
node.shortId = options.shortId ?? "";
|
|
1280
1619
|
if (options.alpn) {
|
|
1281
1620
|
node.alpn = options.alpn;
|
|
1282
1621
|
}
|
|
@@ -1326,7 +1665,7 @@ function explodeNetch(netch, node) {
|
|
|
1326
1665
|
return;
|
|
1327
1666
|
}
|
|
1328
1667
|
const type = str(data.Type);
|
|
1329
|
-
const
|
|
1668
|
+
const group2 = str(data.Group);
|
|
1330
1669
|
let remark = str(data.Remark);
|
|
1331
1670
|
const address = str(data.Hostname);
|
|
1332
1671
|
const udp = tri(data.EnableUDP);
|
|
@@ -1344,7 +1683,7 @@ function explodeNetch(netch, node) {
|
|
|
1344
1683
|
switch (type) {
|
|
1345
1684
|
case "SS":
|
|
1346
1685
|
ssConstruct(node, {
|
|
1347
|
-
group:
|
|
1686
|
+
group: group2 === "" ? DEFAULT_GROUPS.ss : group2,
|
|
1348
1687
|
method,
|
|
1349
1688
|
password,
|
|
1350
1689
|
plugin: str(data.Plugin),
|
|
@@ -1362,7 +1701,7 @@ function explodeNetch(netch, node) {
|
|
|
1362
1701
|
const obfs = str(data.OBFS);
|
|
1363
1702
|
if (isFlattenableSsr(method, obfs, protocol)) {
|
|
1364
1703
|
ssConstruct(node, {
|
|
1365
|
-
group:
|
|
1704
|
+
group: group2 === "" ? DEFAULT_GROUPS.ss : group2,
|
|
1366
1705
|
method,
|
|
1367
1706
|
password,
|
|
1368
1707
|
plugin: str(data.Plugin),
|
|
@@ -1376,7 +1715,7 @@ function explodeNetch(netch, node) {
|
|
|
1376
1715
|
});
|
|
1377
1716
|
} else {
|
|
1378
1717
|
ssrConstruct(node, {
|
|
1379
|
-
group:
|
|
1718
|
+
group: group2 === "" ? DEFAULT_GROUPS.ssr : group2,
|
|
1380
1719
|
method,
|
|
1381
1720
|
obfs,
|
|
1382
1721
|
obfsParam: str(data.OBFSParam),
|
|
@@ -1399,7 +1738,7 @@ function explodeNetch(netch, node) {
|
|
|
1399
1738
|
aid: str(data.AlterID),
|
|
1400
1739
|
cipher: method,
|
|
1401
1740
|
edge: str(data.Edge),
|
|
1402
|
-
group:
|
|
1741
|
+
group: group2 === "" ? DEFAULT_GROUPS.v2ray : group2,
|
|
1403
1742
|
host: str(data.Host),
|
|
1404
1743
|
id: str(data.UserID),
|
|
1405
1744
|
net: str(data.TransferProtocol),
|
|
@@ -1416,7 +1755,7 @@ function explodeNetch(netch, node) {
|
|
|
1416
1755
|
break;
|
|
1417
1756
|
case "Socks5":
|
|
1418
1757
|
socksConstruct(node, {
|
|
1419
|
-
group:
|
|
1758
|
+
group: group2 === "" ? DEFAULT_GROUPS.socks : group2,
|
|
1420
1759
|
password,
|
|
1421
1760
|
port,
|
|
1422
1761
|
remark,
|
|
@@ -1430,7 +1769,7 @@ function explodeNetch(netch, node) {
|
|
|
1430
1769
|
case "HTTP":
|
|
1431
1770
|
case "HTTPS":
|
|
1432
1771
|
httpConstruct(node, {
|
|
1433
|
-
group:
|
|
1772
|
+
group: group2 === "" ? DEFAULT_GROUPS.http : group2,
|
|
1434
1773
|
password,
|
|
1435
1774
|
port,
|
|
1436
1775
|
remark,
|
|
@@ -1442,7 +1781,7 @@ function explodeNetch(netch, node) {
|
|
|
1442
1781
|
break;
|
|
1443
1782
|
case "Trojan":
|
|
1444
1783
|
trojanConstruct(node, {
|
|
1445
|
-
group:
|
|
1784
|
+
group: group2 === "" ? DEFAULT_GROUPS.trojan : group2,
|
|
1446
1785
|
host: str(data.Host),
|
|
1447
1786
|
network: str(data.TransferProtocol),
|
|
1448
1787
|
password,
|
|
@@ -1458,7 +1797,7 @@ function explodeNetch(netch, node) {
|
|
|
1458
1797
|
break;
|
|
1459
1798
|
case "Snell":
|
|
1460
1799
|
snellConstruct(node, {
|
|
1461
|
-
group:
|
|
1800
|
+
group: group2 === "" ? DEFAULT_GROUPS.snell : group2,
|
|
1462
1801
|
host: str(data.Host),
|
|
1463
1802
|
obfs: str(data.OBFS),
|
|
1464
1803
|
password,
|
|
@@ -1522,10 +1861,10 @@ function explodeClash(root, nodes) {
|
|
|
1522
1861
|
const tfo = asTri(get(single, "fast-open"));
|
|
1523
1862
|
const scv = asTri(get(single, "skip-cert-verify"));
|
|
1524
1863
|
const node = createProxy();
|
|
1525
|
-
let
|
|
1864
|
+
let group2 = "";
|
|
1526
1865
|
switch (proxyType) {
|
|
1527
1866
|
case "vmess": {
|
|
1528
|
-
|
|
1867
|
+
group2 = DEFAULT_GROUPS.v2ray;
|
|
1529
1868
|
const id = asString(get(single, "uuid"));
|
|
1530
1869
|
const aid = asString(get(single, "alterId"));
|
|
1531
1870
|
const cipher = asString(get(single, "cipher"));
|
|
@@ -1571,7 +1910,7 @@ function explodeClash(root, nodes) {
|
|
|
1571
1910
|
aid,
|
|
1572
1911
|
cipher,
|
|
1573
1912
|
edge,
|
|
1574
|
-
group,
|
|
1913
|
+
group: group2,
|
|
1575
1914
|
host,
|
|
1576
1915
|
id,
|
|
1577
1916
|
net,
|
|
@@ -1589,7 +1928,7 @@ function explodeClash(root, nodes) {
|
|
|
1589
1928
|
break;
|
|
1590
1929
|
}
|
|
1591
1930
|
case "ss": {
|
|
1592
|
-
|
|
1931
|
+
group2 = DEFAULT_GROUPS.ss;
|
|
1593
1932
|
let cipher = asString(get(single, "cipher"));
|
|
1594
1933
|
const password = asString(get(single, "password"));
|
|
1595
1934
|
let plugin = "";
|
|
@@ -1640,7 +1979,7 @@ function explodeClash(root, nodes) {
|
|
|
1640
1979
|
cipher = cipher.replace(/AEAD_/g, "").replace(/_/g, "-").toLowerCase();
|
|
1641
1980
|
}
|
|
1642
1981
|
ssConstruct(node, {
|
|
1643
|
-
group,
|
|
1982
|
+
group: group2,
|
|
1644
1983
|
method: cipher,
|
|
1645
1984
|
password,
|
|
1646
1985
|
plugin,
|
|
@@ -1656,11 +1995,11 @@ function explodeClash(root, nodes) {
|
|
|
1656
1995
|
break;
|
|
1657
1996
|
}
|
|
1658
1997
|
case "socks5": {
|
|
1659
|
-
|
|
1998
|
+
group2 = DEFAULT_GROUPS.socks;
|
|
1660
1999
|
const user = asString(get(single, "username"));
|
|
1661
2000
|
const password = asString(get(single, "password"));
|
|
1662
2001
|
socksConstruct(node, {
|
|
1663
|
-
group,
|
|
2002
|
+
group: group2,
|
|
1664
2003
|
password,
|
|
1665
2004
|
port,
|
|
1666
2005
|
remark: ps,
|
|
@@ -1671,7 +2010,7 @@ function explodeClash(root, nodes) {
|
|
|
1671
2010
|
break;
|
|
1672
2011
|
}
|
|
1673
2012
|
case "ssr": {
|
|
1674
|
-
|
|
2013
|
+
group2 = DEFAULT_GROUPS.ssr;
|
|
1675
2014
|
let cipher = asString(get(single, "cipher"));
|
|
1676
2015
|
if (cipher === "dummy") {
|
|
1677
2016
|
cipher = "none";
|
|
@@ -1682,7 +2021,7 @@ function explodeClash(root, nodes) {
|
|
|
1682
2021
|
const protocolParam = get(single, "protocol-param") !== void 0 ? asString(get(single, "protocol-param")) : asString(get(single, "protocolparam"));
|
|
1683
2022
|
const obfsParam = get(single, "obfs-param") !== void 0 ? asString(get(single, "obfs-param")) : asString(get(single, "obfsparam"));
|
|
1684
2023
|
ssrConstruct(node, {
|
|
1685
|
-
group,
|
|
2024
|
+
group: group2,
|
|
1686
2025
|
method: cipher,
|
|
1687
2026
|
obfs,
|
|
1688
2027
|
obfsParam,
|
|
@@ -1700,12 +2039,12 @@ function explodeClash(root, nodes) {
|
|
|
1700
2039
|
break;
|
|
1701
2040
|
}
|
|
1702
2041
|
case "http": {
|
|
1703
|
-
|
|
2042
|
+
group2 = DEFAULT_GROUPS.http;
|
|
1704
2043
|
const user = asString(get(single, "username"));
|
|
1705
2044
|
const password = asString(get(single, "password"));
|
|
1706
2045
|
const tls = asString(get(single, "tls"));
|
|
1707
2046
|
httpConstruct(node, {
|
|
1708
|
-
group,
|
|
2047
|
+
group: group2,
|
|
1709
2048
|
password,
|
|
1710
2049
|
port,
|
|
1711
2050
|
remark: ps,
|
|
@@ -1719,7 +2058,7 @@ function explodeClash(root, nodes) {
|
|
|
1719
2058
|
break;
|
|
1720
2059
|
}
|
|
1721
2060
|
case "trojan": {
|
|
1722
|
-
|
|
2061
|
+
group2 = DEFAULT_GROUPS.trojan;
|
|
1723
2062
|
const password = asString(get(single, "password"));
|
|
1724
2063
|
const host = asString(get(single, "sni"));
|
|
1725
2064
|
let net = asString(get(single, "network"));
|
|
@@ -1737,7 +2076,7 @@ function explodeClash(root, nodes) {
|
|
|
1737
2076
|
break;
|
|
1738
2077
|
}
|
|
1739
2078
|
trojanConstruct(node, {
|
|
1740
|
-
group,
|
|
2079
|
+
group: group2,
|
|
1741
2080
|
host,
|
|
1742
2081
|
network: net,
|
|
1743
2082
|
password,
|
|
@@ -1754,13 +2093,13 @@ function explodeClash(root, nodes) {
|
|
|
1754
2093
|
break;
|
|
1755
2094
|
}
|
|
1756
2095
|
case "snell": {
|
|
1757
|
-
|
|
2096
|
+
group2 = DEFAULT_GROUPS.snell;
|
|
1758
2097
|
const password = asString(get(single, "psk"));
|
|
1759
2098
|
const obfs = asString(get(get(single, "obfs-opts"), "mode"));
|
|
1760
2099
|
const host = asString(get(get(single, "obfs-opts"), "host"));
|
|
1761
2100
|
const version = asString(get(single, "version"));
|
|
1762
2101
|
snellConstruct(node, {
|
|
1763
|
-
group,
|
|
2102
|
+
group: group2,
|
|
1764
2103
|
host,
|
|
1765
2104
|
obfs,
|
|
1766
2105
|
password,
|
|
@@ -1776,7 +2115,7 @@ function explodeClash(root, nodes) {
|
|
|
1776
2115
|
break;
|
|
1777
2116
|
}
|
|
1778
2117
|
case "wireguard": {
|
|
1779
|
-
|
|
2118
|
+
group2 = DEFAULT_GROUPS.wireguard;
|
|
1780
2119
|
const publicKey = asString(get(single, "public-key"));
|
|
1781
2120
|
const privateKey = asString(get(single, "private-key"));
|
|
1782
2121
|
const dns = get(single, "dns");
|
|
@@ -1787,7 +2126,7 @@ function explodeClash(root, nodes) {
|
|
|
1787
2126
|
const ipv6 = asString(get(single, "ipv6"));
|
|
1788
2127
|
wireGuardConstruct(node, {
|
|
1789
2128
|
dnsServers,
|
|
1790
|
-
group,
|
|
2129
|
+
group: group2,
|
|
1791
2130
|
keepAlive: "0",
|
|
1792
2131
|
mtu,
|
|
1793
2132
|
port,
|
|
@@ -1805,7 +2144,7 @@ function explodeClash(root, nodes) {
|
|
|
1805
2144
|
break;
|
|
1806
2145
|
}
|
|
1807
2146
|
case "hysteria": {
|
|
1808
|
-
|
|
2147
|
+
group2 = DEFAULT_GROUPS.hysteria;
|
|
1809
2148
|
const ports = asString(get(single, "ports"));
|
|
1810
2149
|
const protocol = asString(get(single, "protocol"));
|
|
1811
2150
|
const obfsProtocol = asString(get(single, "obfs-protocol"));
|
|
@@ -1842,7 +2181,7 @@ function explodeClash(root, nodes) {
|
|
|
1842
2181
|
down,
|
|
1843
2182
|
downSpeed,
|
|
1844
2183
|
fingerprint,
|
|
1845
|
-
group,
|
|
2184
|
+
group: group2,
|
|
1846
2185
|
hopInterval,
|
|
1847
2186
|
obfs,
|
|
1848
2187
|
obfsProtocol,
|
|
@@ -1863,7 +2202,7 @@ function explodeClash(root, nodes) {
|
|
|
1863
2202
|
break;
|
|
1864
2203
|
}
|
|
1865
2204
|
case "hysteria2": {
|
|
1866
|
-
|
|
2205
|
+
group2 = DEFAULT_GROUPS.hysteria2;
|
|
1867
2206
|
const ports = asString(get(single, "ports"));
|
|
1868
2207
|
const up = asString(get(single, "up"));
|
|
1869
2208
|
const down = asString(get(single, "down"));
|
|
@@ -1888,7 +2227,7 @@ function explodeClash(root, nodes) {
|
|
|
1888
2227
|
cwnd,
|
|
1889
2228
|
down,
|
|
1890
2229
|
fingerprint,
|
|
1891
|
-
group,
|
|
2230
|
+
group: group2,
|
|
1892
2231
|
hopInterval,
|
|
1893
2232
|
obfs,
|
|
1894
2233
|
obfsPassword,
|
|
@@ -1906,11 +2245,11 @@ function explodeClash(root, nodes) {
|
|
|
1906
2245
|
break;
|
|
1907
2246
|
}
|
|
1908
2247
|
case "anytls": {
|
|
1909
|
-
|
|
2248
|
+
group2 = DEFAULT_GROUPS.anytls;
|
|
1910
2249
|
const password = asString(get(single, "password"));
|
|
1911
2250
|
const sni = asString(get(single, "sni"));
|
|
1912
2251
|
anyTlsConstruct(node, {
|
|
1913
|
-
group,
|
|
2252
|
+
group: group2,
|
|
1914
2253
|
password,
|
|
1915
2254
|
port,
|
|
1916
2255
|
remark: ps,
|
|
@@ -1924,7 +2263,7 @@ function explodeClash(root, nodes) {
|
|
|
1924
2263
|
break;
|
|
1925
2264
|
}
|
|
1926
2265
|
case "vless": {
|
|
1927
|
-
|
|
2266
|
+
group2 = DEFAULT_GROUPS.v2ray;
|
|
1928
2267
|
const userId = asString(get(single, "uuid"));
|
|
1929
2268
|
const net = asString(get(single, "network"));
|
|
1930
2269
|
const tls = asString(get(single, "tls"));
|
|
@@ -1942,7 +2281,7 @@ function explodeClash(root, nodes) {
|
|
|
1942
2281
|
encryption: asString(get(single, "encryption")),
|
|
1943
2282
|
fingerprint: asString(get(single, "client-fingerprint")),
|
|
1944
2283
|
flow: asString(get(single, "flow")),
|
|
1945
|
-
group,
|
|
2284
|
+
group: group2,
|
|
1946
2285
|
host,
|
|
1947
2286
|
network: net,
|
|
1948
2287
|
path,
|
|
@@ -1960,12 +2299,12 @@ function explodeClash(root, nodes) {
|
|
|
1960
2299
|
break;
|
|
1961
2300
|
}
|
|
1962
2301
|
case "tuic": {
|
|
1963
|
-
|
|
2302
|
+
group2 = DEFAULT_GROUPS.v2ray;
|
|
1964
2303
|
const alpnValue = get(single, "alpn");
|
|
1965
2304
|
tuicConstruct(node, {
|
|
1966
2305
|
alpn: Array.isArray(alpnValue) ? alpnValue.map((a) => String(a)) : void 0,
|
|
1967
2306
|
congestionControl: asString(get(single, "congestion-controller")),
|
|
1968
|
-
group,
|
|
2307
|
+
group: group2,
|
|
1969
2308
|
password: asString(get(single, "password")),
|
|
1970
2309
|
port,
|
|
1971
2310
|
remark: ps,
|
|
@@ -2032,8 +2371,8 @@ function collectKeyValues(lines, startIndex, sink) {
|
|
|
2032
2371
|
sink[trim(line.slice(0, eq))] = trim(line.slice(eq + 1));
|
|
2033
2372
|
}
|
|
2034
2373
|
}
|
|
2035
|
-
function explodeSurge(
|
|
2036
|
-
let text =
|
|
2374
|
+
function explodeSurge(surge2, nodes) {
|
|
2375
|
+
let text = surge2;
|
|
2037
2376
|
if (text.includes("[Proxy]")) {
|
|
2038
2377
|
text = text.replace(/^[\s\S]*?\[/, "[");
|
|
2039
2378
|
}
|
|
@@ -2858,7 +3197,7 @@ function explodeSsConf(content, nodes) {
|
|
|
2858
3197
|
if (!(section in json)) {
|
|
2859
3198
|
return;
|
|
2860
3199
|
}
|
|
2861
|
-
const
|
|
3200
|
+
const group2 = asString(json.remarks);
|
|
2862
3201
|
const list = json[section];
|
|
2863
3202
|
if (!Array.isArray(list)) {
|
|
2864
3203
|
return;
|
|
@@ -2873,7 +3212,7 @@ function explodeSsConf(content, nodes) {
|
|
|
2873
3212
|
const server = asString(entry.server);
|
|
2874
3213
|
const node = createProxy();
|
|
2875
3214
|
ssConstruct(node, {
|
|
2876
|
-
group,
|
|
3215
|
+
group: group2,
|
|
2877
3216
|
method: asString(entry.method),
|
|
2878
3217
|
password: asString(entry.password),
|
|
2879
3218
|
plugin: asString(entry.plugin),
|
|
@@ -2978,7 +3317,7 @@ function explodeSsrConf(content, nodes) {
|
|
|
2978
3317
|
return;
|
|
2979
3318
|
}
|
|
2980
3319
|
for (const entry of list) {
|
|
2981
|
-
const
|
|
3320
|
+
const group2 = asString(entry.group) === "" ? DEFAULT_GROUPS.ssr : asString(entry.group);
|
|
2982
3321
|
const server = asString(entry.server);
|
|
2983
3322
|
const port = asString(entry.server_port);
|
|
2984
3323
|
if (port === "0" || port === "") {
|
|
@@ -2987,7 +3326,7 @@ function explodeSsrConf(content, nodes) {
|
|
|
2987
3326
|
const remark = asString(entry.remarks) === "" ? `${server}:${port}` : asString(entry.remarks);
|
|
2988
3327
|
const node = createProxy();
|
|
2989
3328
|
ssrConstruct(node, {
|
|
2990
|
-
group,
|
|
3329
|
+
group: group2,
|
|
2991
3330
|
method: asString(entry.method),
|
|
2992
3331
|
obfs: asString(entry.obfs),
|
|
2993
3332
|
obfsParam: asString(entry.obfsparam),
|
|
@@ -3092,9 +3431,9 @@ function explodeVmessConf(content, nodes) {
|
|
|
3092
3431
|
continue;
|
|
3093
3432
|
}
|
|
3094
3433
|
const subid = asString(entry.subid);
|
|
3095
|
-
let
|
|
3434
|
+
let group2 = "";
|
|
3096
3435
|
if (subid !== "") {
|
|
3097
|
-
|
|
3436
|
+
group2 = subdata.get(subid) ?? "";
|
|
3098
3437
|
}
|
|
3099
3438
|
if (ps === "") {
|
|
3100
3439
|
ps = `${add}:${port}`;
|
|
@@ -3107,7 +3446,7 @@ function explodeVmessConf(content, nodes) {
|
|
|
3107
3446
|
add,
|
|
3108
3447
|
aid: asString(entry.alterId),
|
|
3109
3448
|
cipher: asString(entry.security),
|
|
3110
|
-
group:
|
|
3449
|
+
group: group2 || DEFAULT_GROUPS.v2ray,
|
|
3111
3450
|
host: asString(entry.requestHost),
|
|
3112
3451
|
id: asString(entry.id),
|
|
3113
3452
|
net: asString(entry.network),
|
|
@@ -3121,7 +3460,7 @@ function explodeVmessConf(content, nodes) {
|
|
|
3121
3460
|
});
|
|
3122
3461
|
} else if (configType === 3) {
|
|
3123
3462
|
ssConstruct(node, {
|
|
3124
|
-
group:
|
|
3463
|
+
group: group2 || DEFAULT_GROUPS.ss,
|
|
3125
3464
|
method: asString(entry.security),
|
|
3126
3465
|
password: asString(entry.id),
|
|
3127
3466
|
port,
|
|
@@ -3131,7 +3470,7 @@ function explodeVmessConf(content, nodes) {
|
|
|
3131
3470
|
});
|
|
3132
3471
|
} else if (configType === 4) {
|
|
3133
3472
|
socksConstruct(node, {
|
|
3134
|
-
group:
|
|
3473
|
+
group: group2 || DEFAULT_GROUPS.socks,
|
|
3135
3474
|
port,
|
|
3136
3475
|
remark: ps,
|
|
3137
3476
|
scv,
|
|
@@ -3157,7 +3496,7 @@ function explodeSstap(content, nodes) {
|
|
|
3157
3496
|
}
|
|
3158
3497
|
let index = nodes.length;
|
|
3159
3498
|
for (const entry of json.configs) {
|
|
3160
|
-
const
|
|
3499
|
+
const group2 = asString(entry.group);
|
|
3161
3500
|
const server = asString(entry.server);
|
|
3162
3501
|
const port = asString(entry.server_port);
|
|
3163
3502
|
if (port === "0" || port === "") {
|
|
@@ -3169,7 +3508,7 @@ function explodeSstap(content, nodes) {
|
|
|
3169
3508
|
const configType = toInt(entry.type);
|
|
3170
3509
|
if (configType === 5) {
|
|
3171
3510
|
socksConstruct(node, {
|
|
3172
|
-
group,
|
|
3511
|
+
group: group2,
|
|
3173
3512
|
password,
|
|
3174
3513
|
port,
|
|
3175
3514
|
remark,
|
|
@@ -3181,10 +3520,10 @@ function explodeSstap(content, nodes) {
|
|
|
3181
3520
|
const obfs = asString(entry.obfs);
|
|
3182
3521
|
const method = asString(entry.method);
|
|
3183
3522
|
if (isFlattenableSsr(method, obfs, protocol)) {
|
|
3184
|
-
ssConstruct(node, { group, method, password, port, remark, server });
|
|
3523
|
+
ssConstruct(node, { group: group2, method, password, port, remark, server });
|
|
3185
3524
|
} else {
|
|
3186
3525
|
ssrConstruct(node, {
|
|
3187
|
-
group,
|
|
3526
|
+
group: group2,
|
|
3188
3527
|
method,
|
|
3189
3528
|
obfs,
|
|
3190
3529
|
obfsParam: asString(entry.obfsparam),
|
|
@@ -3490,7 +3829,7 @@ function explodeQuan(quan, node) {
|
|
|
3490
3829
|
}
|
|
3491
3830
|
const cipher = trim(configs[4]);
|
|
3492
3831
|
const id = trim(configs[5].replace(/"/g, ""));
|
|
3493
|
-
let
|
|
3832
|
+
let group2 = DEFAULT_GROUPS.v2ray;
|
|
3494
3833
|
let tls = "";
|
|
3495
3834
|
let host = "";
|
|
3496
3835
|
let path = "";
|
|
@@ -3505,7 +3844,7 @@ function explodeQuan(quan, node) {
|
|
|
3505
3844
|
const itemVal = trim(vArray.slice(1).join("="));
|
|
3506
3845
|
switch (itemName) {
|
|
3507
3846
|
case "group":
|
|
3508
|
-
|
|
3847
|
+
group2 = itemVal;
|
|
3509
3848
|
break;
|
|
3510
3849
|
case "over-tls":
|
|
3511
3850
|
tls = itemVal === "true" ? "tls" : "";
|
|
@@ -3544,7 +3883,7 @@ function explodeQuan(quan, node) {
|
|
|
3544
3883
|
aid: "0",
|
|
3545
3884
|
cipher,
|
|
3546
3885
|
edge,
|
|
3547
|
-
group,
|
|
3886
|
+
group: group2,
|
|
3548
3887
|
host,
|
|
3549
3888
|
id,
|
|
3550
3889
|
net,
|
|
@@ -3557,12 +3896,12 @@ function explodeQuan(quan, node) {
|
|
|
3557
3896
|
}
|
|
3558
3897
|
function explodeSs(ss, node) {
|
|
3559
3898
|
let body = ss.slice(5).replace(/\/\?/g, "?");
|
|
3560
|
-
const
|
|
3899
|
+
const group2 = DEFAULT_GROUPS.ss;
|
|
3561
3900
|
let remark = "";
|
|
3562
3901
|
let addition = "";
|
|
3563
3902
|
let plugin = "";
|
|
3564
3903
|
let pluginOption = "";
|
|
3565
|
-
let resolvedGroup =
|
|
3904
|
+
let resolvedGroup = group2;
|
|
3566
3905
|
const hashPos = body.indexOf("#");
|
|
3567
3906
|
if (hashPos !== -1) {
|
|
3568
3907
|
remark = urlDecode(body.slice(hashPos + 1));
|
|
@@ -3629,7 +3968,7 @@ function explodeSs(ss, node) {
|
|
|
3629
3968
|
function explodeSsr(ssr, node) {
|
|
3630
3969
|
let body = ssr.slice(6).replace(/\r/g, "");
|
|
3631
3970
|
body = urlSafeBase64Decode(body);
|
|
3632
|
-
let
|
|
3971
|
+
let group2 = "";
|
|
3633
3972
|
let remark = "";
|
|
3634
3973
|
let obfsParam = "";
|
|
3635
3974
|
let protocolParam = "";
|
|
@@ -3637,7 +3976,7 @@ function explodeSsr(ssr, node) {
|
|
|
3637
3976
|
if (obfsPos !== -1) {
|
|
3638
3977
|
const strobfs = body.slice(obfsPos + 2);
|
|
3639
3978
|
body = body.slice(0, obfsPos);
|
|
3640
|
-
|
|
3979
|
+
group2 = urlSafeBase64Decode(getUrlArg(strobfs, "group"));
|
|
3641
3980
|
remark = urlSafeBase64Decode(getUrlArg(strobfs, "remarks"));
|
|
3642
3981
|
obfsParam = urlSafeBase64Decode(getUrlArg(strobfs, "obfsparam")).replace(/\s/g, "");
|
|
3643
3982
|
protocolParam = urlSafeBase64Decode(getUrlArg(strobfs, "protoparam")).replace(/\s/g, "");
|
|
@@ -3655,7 +3994,7 @@ function explodeSsr(ssr, node) {
|
|
|
3655
3994
|
if (port === "0") {
|
|
3656
3995
|
return;
|
|
3657
3996
|
}
|
|
3658
|
-
const resolvedGroup =
|
|
3997
|
+
const resolvedGroup = group2 === "" ? DEFAULT_GROUPS.ssr : group2;
|
|
3659
3998
|
const resolvedRemark = remark === "" ? `${server}:${port}` : remark;
|
|
3660
3999
|
if (isFlattenableSsr(method, obfs, protocol)) {
|
|
3661
4000
|
ssConstruct(node, {
|
|
@@ -3693,7 +4032,7 @@ function explodeSsd(link, nodes) {
|
|
|
3693
4032
|
if (data === null || typeof data !== "object" || !("servers" in data)) {
|
|
3694
4033
|
return;
|
|
3695
4034
|
}
|
|
3696
|
-
const
|
|
4035
|
+
const group2 = String(data.airport ?? "");
|
|
3697
4036
|
const servers = data.servers;
|
|
3698
4037
|
let entries;
|
|
3699
4038
|
if (Array.isArray(servers)) {
|
|
@@ -3719,7 +4058,7 @@ function explodeSsd(link, nodes) {
|
|
|
3719
4058
|
const pluginOption = String(entry.plugin_options ?? data.plugin_options ?? "");
|
|
3720
4059
|
const node = createProxy();
|
|
3721
4060
|
ssConstruct(node, {
|
|
3722
|
-
group,
|
|
4061
|
+
group: group2,
|
|
3723
4062
|
method,
|
|
3724
4063
|
password,
|
|
3725
4064
|
plugin,
|
|
@@ -3734,7 +4073,7 @@ function explodeSsd(link, nodes) {
|
|
|
3734
4073
|
}
|
|
3735
4074
|
}
|
|
3736
4075
|
function explodeSocks(link, node) {
|
|
3737
|
-
let
|
|
4076
|
+
let group2 = "";
|
|
3738
4077
|
let remark = "";
|
|
3739
4078
|
let server = "";
|
|
3740
4079
|
let port = "";
|
|
@@ -3773,10 +4112,10 @@ function explodeSocks(link, node) {
|
|
|
3773
4112
|
username = urlDecode(getUrlArg(link, "user"));
|
|
3774
4113
|
password = urlDecode(getUrlArg(link, "pass"));
|
|
3775
4114
|
remark = urlDecode(getUrlArg(link, "remarks"));
|
|
3776
|
-
|
|
4115
|
+
group2 = urlDecode(getUrlArg(link, "group"));
|
|
3777
4116
|
}
|
|
3778
|
-
if (
|
|
3779
|
-
|
|
4117
|
+
if (group2 === "") {
|
|
4118
|
+
group2 = DEFAULT_GROUPS.socks;
|
|
3780
4119
|
}
|
|
3781
4120
|
if (remark === "") {
|
|
3782
4121
|
remark = `${server}:${port}`;
|
|
@@ -3784,7 +4123,7 @@ function explodeSocks(link, node) {
|
|
|
3784
4123
|
if (port === "0" || port === "") {
|
|
3785
4124
|
return;
|
|
3786
4125
|
}
|
|
3787
|
-
socksConstruct(node, { group, password, port, remark, server, username });
|
|
4126
|
+
socksConstruct(node, { group: group2, password, port, remark, server, username });
|
|
3788
4127
|
}
|
|
3789
4128
|
function explodeHttp(link, node) {
|
|
3790
4129
|
const server = getUrlArg(link, "server");
|
|
@@ -3792,9 +4131,9 @@ function explodeHttp(link, node) {
|
|
|
3792
4131
|
const username = urlDecode(getUrlArg(link, "user"));
|
|
3793
4132
|
const password = urlDecode(getUrlArg(link, "pass"));
|
|
3794
4133
|
let remark = urlDecode(getUrlArg(link, "remarks"));
|
|
3795
|
-
let
|
|
3796
|
-
if (
|
|
3797
|
-
|
|
4134
|
+
let group2 = urlDecode(getUrlArg(link, "group"));
|
|
4135
|
+
if (group2 === "") {
|
|
4136
|
+
group2 = DEFAULT_GROUPS.http;
|
|
3798
4137
|
}
|
|
3799
4138
|
if (remark === "") {
|
|
3800
4139
|
remark = `${server}:${port}`;
|
|
@@ -3803,7 +4142,7 @@ function explodeHttp(link, node) {
|
|
|
3803
4142
|
return;
|
|
3804
4143
|
}
|
|
3805
4144
|
httpConstruct(node, {
|
|
3806
|
-
group,
|
|
4145
|
+
group: group2,
|
|
3807
4146
|
password,
|
|
3808
4147
|
port,
|
|
3809
4148
|
remark,
|
|
@@ -3815,14 +4154,14 @@ function explodeHttp(link, node) {
|
|
|
3815
4154
|
function explodeHttpSub(link, node) {
|
|
3816
4155
|
let body = link;
|
|
3817
4156
|
let remarks = "";
|
|
3818
|
-
let
|
|
4157
|
+
let group2 = "";
|
|
3819
4158
|
const tls = body.includes("https://");
|
|
3820
4159
|
const qpos = body.indexOf("?");
|
|
3821
4160
|
if (qpos !== -1) {
|
|
3822
4161
|
const addition = body.slice(qpos + 1);
|
|
3823
4162
|
body = body.slice(0, qpos);
|
|
3824
4163
|
remarks = urlDecode(getUrlArg(addition, "remarks"));
|
|
3825
|
-
|
|
4164
|
+
group2 = urlDecode(getUrlArg(addition, "group"));
|
|
3826
4165
|
}
|
|
3827
4166
|
body = body.slice(body.indexOf("://") + 3);
|
|
3828
4167
|
body = urlSafeBase64Decode(body);
|
|
@@ -3847,8 +4186,8 @@ function explodeHttpSub(link, node) {
|
|
|
3847
4186
|
server = match[1];
|
|
3848
4187
|
port = match[2];
|
|
3849
4188
|
}
|
|
3850
|
-
if (
|
|
3851
|
-
|
|
4189
|
+
if (group2 === "") {
|
|
4190
|
+
group2 = DEFAULT_GROUPS.http;
|
|
3852
4191
|
}
|
|
3853
4192
|
if (remarks === "") {
|
|
3854
4193
|
remarks = `${server}:${port}`;
|
|
@@ -3857,7 +4196,7 @@ function explodeHttpSub(link, node) {
|
|
|
3857
4196
|
return;
|
|
3858
4197
|
}
|
|
3859
4198
|
httpConstruct(node, {
|
|
3860
|
-
group,
|
|
4199
|
+
group: group2,
|
|
3861
4200
|
password,
|
|
3862
4201
|
port,
|
|
3863
4202
|
remark: remarks,
|
|
@@ -3898,7 +4237,7 @@ function explodeTrojan(trojan, node) {
|
|
|
3898
4237
|
host = getUrlArg(addition, "peer");
|
|
3899
4238
|
}
|
|
3900
4239
|
const tfo = getUrlArg(addition, "tfo");
|
|
3901
|
-
const
|
|
4240
|
+
const group2 = urlDecode(getUrlArg(addition, "group"));
|
|
3902
4241
|
if (getUrlArg(addition, "ws") === "1") {
|
|
3903
4242
|
path = getUrlArg(addition, "wspath");
|
|
3904
4243
|
network = "ws";
|
|
@@ -3916,7 +4255,7 @@ function explodeTrojan(trojan, node) {
|
|
|
3916
4255
|
remark = `${server}:${port}`;
|
|
3917
4256
|
}
|
|
3918
4257
|
trojanConstruct(node, {
|
|
3919
|
-
group:
|
|
4258
|
+
group: group2 === "" ? DEFAULT_GROUPS.trojan : group2,
|
|
3920
4259
|
host,
|
|
3921
4260
|
network,
|
|
3922
4261
|
password,
|
|
@@ -4085,10 +4424,14 @@ function explodeVless(link, node) {
|
|
|
4085
4424
|
const network = getUrlArg(addition, "type");
|
|
4086
4425
|
const security = getUrlArg(addition, "security");
|
|
4087
4426
|
const host = getUrlArg(addition, "host");
|
|
4088
|
-
const
|
|
4427
|
+
const rawPath = urlDecode(getUrlArg(addition, "path"));
|
|
4428
|
+
const serviceName = urlDecode(getUrlArg(addition, "serviceName"));
|
|
4429
|
+
const path = rawPath !== "" ? rawPath : serviceName;
|
|
4089
4430
|
const sni = getUrlArg(addition, "sni");
|
|
4090
4431
|
const flow = getUrlArg(addition, "flow");
|
|
4091
4432
|
const fingerprint = getUrlArg(addition, "fp");
|
|
4433
|
+
const publicKey = getUrlArg(addition, "pbk");
|
|
4434
|
+
const shortId = getUrlArg(addition, "sid");
|
|
4092
4435
|
const alpn = getUrlArg(addition, "alpn");
|
|
4093
4436
|
if (remark === "") {
|
|
4094
4437
|
remark = `${server}:${port}`;
|
|
@@ -4102,9 +4445,11 @@ function explodeVless(link, node) {
|
|
|
4102
4445
|
network,
|
|
4103
4446
|
path,
|
|
4104
4447
|
port,
|
|
4448
|
+
publicKey,
|
|
4105
4449
|
remark,
|
|
4106
4450
|
scv: getUrlArg(addition, "allowInsecure") === "" ? void 0 : parseTri(getUrlArg(addition, "allowInsecure")),
|
|
4107
4451
|
server,
|
|
4452
|
+
shortId,
|
|
4108
4453
|
sni,
|
|
4109
4454
|
tls: security,
|
|
4110
4455
|
userId
|
|
@@ -4245,6 +4590,425 @@ function parseSubscription(content) {
|
|
|
4245
4590
|
// src/generator/clash.ts
|
|
4246
4591
|
import { stringify as yamlStringify } from "yaml";
|
|
4247
4592
|
|
|
4593
|
+
// src/utils/country.ts
|
|
4594
|
+
var REGION_CODES = [
|
|
4595
|
+
"AD",
|
|
4596
|
+
"AE",
|
|
4597
|
+
"AF",
|
|
4598
|
+
"AG",
|
|
4599
|
+
"AI",
|
|
4600
|
+
"AL",
|
|
4601
|
+
"AM",
|
|
4602
|
+
"AO",
|
|
4603
|
+
"AQ",
|
|
4604
|
+
"AR",
|
|
4605
|
+
"AS",
|
|
4606
|
+
"AT",
|
|
4607
|
+
"AU",
|
|
4608
|
+
"AW",
|
|
4609
|
+
"AX",
|
|
4610
|
+
"AZ",
|
|
4611
|
+
"BA",
|
|
4612
|
+
"BB",
|
|
4613
|
+
"BD",
|
|
4614
|
+
"BE",
|
|
4615
|
+
"BF",
|
|
4616
|
+
"BG",
|
|
4617
|
+
"BH",
|
|
4618
|
+
"BI",
|
|
4619
|
+
"BJ",
|
|
4620
|
+
"BL",
|
|
4621
|
+
"BM",
|
|
4622
|
+
"BN",
|
|
4623
|
+
"BO",
|
|
4624
|
+
"BQ",
|
|
4625
|
+
"BR",
|
|
4626
|
+
"BS",
|
|
4627
|
+
"BT",
|
|
4628
|
+
"BV",
|
|
4629
|
+
"BW",
|
|
4630
|
+
"BY",
|
|
4631
|
+
"BZ",
|
|
4632
|
+
"CA",
|
|
4633
|
+
"CC",
|
|
4634
|
+
"CD",
|
|
4635
|
+
"CF",
|
|
4636
|
+
"CG",
|
|
4637
|
+
"CH",
|
|
4638
|
+
"CI",
|
|
4639
|
+
"CK",
|
|
4640
|
+
"CL",
|
|
4641
|
+
"CM",
|
|
4642
|
+
"CN",
|
|
4643
|
+
"CO",
|
|
4644
|
+
"CR",
|
|
4645
|
+
"CU",
|
|
4646
|
+
"CV",
|
|
4647
|
+
"CW",
|
|
4648
|
+
"CX",
|
|
4649
|
+
"CY",
|
|
4650
|
+
"CZ",
|
|
4651
|
+
"DE",
|
|
4652
|
+
"DJ",
|
|
4653
|
+
"DK",
|
|
4654
|
+
"DM",
|
|
4655
|
+
"DO",
|
|
4656
|
+
"DZ",
|
|
4657
|
+
"EC",
|
|
4658
|
+
"EE",
|
|
4659
|
+
"EG",
|
|
4660
|
+
"EH",
|
|
4661
|
+
"ER",
|
|
4662
|
+
"ES",
|
|
4663
|
+
"ET",
|
|
4664
|
+
"FI",
|
|
4665
|
+
"FJ",
|
|
4666
|
+
"FK",
|
|
4667
|
+
"FM",
|
|
4668
|
+
"FO",
|
|
4669
|
+
"FR",
|
|
4670
|
+
"GA",
|
|
4671
|
+
"GB",
|
|
4672
|
+
"GD",
|
|
4673
|
+
"GE",
|
|
4674
|
+
"GF",
|
|
4675
|
+
"GG",
|
|
4676
|
+
"GH",
|
|
4677
|
+
"GI",
|
|
4678
|
+
"GL",
|
|
4679
|
+
"GM",
|
|
4680
|
+
"GN",
|
|
4681
|
+
"GP",
|
|
4682
|
+
"GQ",
|
|
4683
|
+
"GR",
|
|
4684
|
+
"GS",
|
|
4685
|
+
"GT",
|
|
4686
|
+
"GU",
|
|
4687
|
+
"GW",
|
|
4688
|
+
"GY",
|
|
4689
|
+
"HK",
|
|
4690
|
+
"HM",
|
|
4691
|
+
"HN",
|
|
4692
|
+
"HR",
|
|
4693
|
+
"HT",
|
|
4694
|
+
"HU",
|
|
4695
|
+
"ID",
|
|
4696
|
+
"IE",
|
|
4697
|
+
"IL",
|
|
4698
|
+
"IM",
|
|
4699
|
+
"IN",
|
|
4700
|
+
"IO",
|
|
4701
|
+
"IQ",
|
|
4702
|
+
"IR",
|
|
4703
|
+
"IS",
|
|
4704
|
+
"IT",
|
|
4705
|
+
"JE",
|
|
4706
|
+
"JM",
|
|
4707
|
+
"JO",
|
|
4708
|
+
"JP",
|
|
4709
|
+
"KE",
|
|
4710
|
+
"KG",
|
|
4711
|
+
"KH",
|
|
4712
|
+
"KI",
|
|
4713
|
+
"KM",
|
|
4714
|
+
"KN",
|
|
4715
|
+
"KP",
|
|
4716
|
+
"KR",
|
|
4717
|
+
"KW",
|
|
4718
|
+
"KY",
|
|
4719
|
+
"KZ",
|
|
4720
|
+
"LA",
|
|
4721
|
+
"LB",
|
|
4722
|
+
"LC",
|
|
4723
|
+
"LI",
|
|
4724
|
+
"LK",
|
|
4725
|
+
"LR",
|
|
4726
|
+
"LS",
|
|
4727
|
+
"LT",
|
|
4728
|
+
"LU",
|
|
4729
|
+
"LV",
|
|
4730
|
+
"LY",
|
|
4731
|
+
"MA",
|
|
4732
|
+
"MC",
|
|
4733
|
+
"MD",
|
|
4734
|
+
"ME",
|
|
4735
|
+
"MF",
|
|
4736
|
+
"MG",
|
|
4737
|
+
"MH",
|
|
4738
|
+
"MK",
|
|
4739
|
+
"ML",
|
|
4740
|
+
"MM",
|
|
4741
|
+
"MN",
|
|
4742
|
+
"MO",
|
|
4743
|
+
"MP",
|
|
4744
|
+
"MQ",
|
|
4745
|
+
"MR",
|
|
4746
|
+
"MS",
|
|
4747
|
+
"MT",
|
|
4748
|
+
"MU",
|
|
4749
|
+
"MV",
|
|
4750
|
+
"MW",
|
|
4751
|
+
"MX",
|
|
4752
|
+
"MY",
|
|
4753
|
+
"MZ",
|
|
4754
|
+
"NA",
|
|
4755
|
+
"NC",
|
|
4756
|
+
"NE",
|
|
4757
|
+
"NF",
|
|
4758
|
+
"NG",
|
|
4759
|
+
"NI",
|
|
4760
|
+
"NL",
|
|
4761
|
+
"NO",
|
|
4762
|
+
"NP",
|
|
4763
|
+
"NR",
|
|
4764
|
+
"NU",
|
|
4765
|
+
"NZ",
|
|
4766
|
+
"OM",
|
|
4767
|
+
"PA",
|
|
4768
|
+
"PE",
|
|
4769
|
+
"PF",
|
|
4770
|
+
"PG",
|
|
4771
|
+
"PH",
|
|
4772
|
+
"PK",
|
|
4773
|
+
"PL",
|
|
4774
|
+
"PM",
|
|
4775
|
+
"PN",
|
|
4776
|
+
"PR",
|
|
4777
|
+
"PS",
|
|
4778
|
+
"PT",
|
|
4779
|
+
"PW",
|
|
4780
|
+
"PY",
|
|
4781
|
+
"QA",
|
|
4782
|
+
"RE",
|
|
4783
|
+
"RO",
|
|
4784
|
+
"RS",
|
|
4785
|
+
"RU",
|
|
4786
|
+
"RW",
|
|
4787
|
+
"SA",
|
|
4788
|
+
"SB",
|
|
4789
|
+
"SC",
|
|
4790
|
+
"SD",
|
|
4791
|
+
"SE",
|
|
4792
|
+
"SG",
|
|
4793
|
+
"SH",
|
|
4794
|
+
"SI",
|
|
4795
|
+
"SJ",
|
|
4796
|
+
"SK",
|
|
4797
|
+
"SL",
|
|
4798
|
+
"SM",
|
|
4799
|
+
"SN",
|
|
4800
|
+
"SO",
|
|
4801
|
+
"SR",
|
|
4802
|
+
"SS",
|
|
4803
|
+
"ST",
|
|
4804
|
+
"SV",
|
|
4805
|
+
"SX",
|
|
4806
|
+
"SY",
|
|
4807
|
+
"SZ",
|
|
4808
|
+
"TC",
|
|
4809
|
+
"TD",
|
|
4810
|
+
"TF",
|
|
4811
|
+
"TG",
|
|
4812
|
+
"TH",
|
|
4813
|
+
"TJ",
|
|
4814
|
+
"TK",
|
|
4815
|
+
"TL",
|
|
4816
|
+
"TM",
|
|
4817
|
+
"TN",
|
|
4818
|
+
"TO",
|
|
4819
|
+
"TR",
|
|
4820
|
+
"TT",
|
|
4821
|
+
"TV",
|
|
4822
|
+
"TW",
|
|
4823
|
+
"TZ",
|
|
4824
|
+
"UA",
|
|
4825
|
+
"UG",
|
|
4826
|
+
"UM",
|
|
4827
|
+
"US",
|
|
4828
|
+
"UY",
|
|
4829
|
+
"UZ",
|
|
4830
|
+
"VA",
|
|
4831
|
+
"VC",
|
|
4832
|
+
"VE",
|
|
4833
|
+
"VG",
|
|
4834
|
+
"VI",
|
|
4835
|
+
"VN",
|
|
4836
|
+
"VU",
|
|
4837
|
+
"WF",
|
|
4838
|
+
"WS",
|
|
4839
|
+
"YE",
|
|
4840
|
+
"YT",
|
|
4841
|
+
"ZA",
|
|
4842
|
+
"ZM",
|
|
4843
|
+
"ZW"
|
|
4844
|
+
];
|
|
4845
|
+
var REGION_CODE_SET = new Set(REGION_CODES);
|
|
4846
|
+
var ZH_OVERRIDES = {
|
|
4847
|
+
AE: "\u963F\u8054\u914B",
|
|
4848
|
+
BN: "\u6587\u83B1",
|
|
4849
|
+
BO: "\u73BB\u5229\u7EF4\u4E9A",
|
|
4850
|
+
CD: "\u521A\u679C\uFF08\u91D1\uFF09",
|
|
4851
|
+
CG: "\u521A\u679C\uFF08\u5E03\uFF09",
|
|
4852
|
+
CV: "\u4F5B\u5F97\u89D2",
|
|
4853
|
+
CZ: "\u6377\u514B",
|
|
4854
|
+
DO: "\u591A\u7C73\u5C3C\u52A0",
|
|
4855
|
+
HK: "\u9999\u6E2F",
|
|
4856
|
+
KH: "\u67EC\u57D4\u5BE8",
|
|
4857
|
+
KP: "\u671D\u9C9C",
|
|
4858
|
+
KR: "\u97E9\u56FD",
|
|
4859
|
+
LA: "\u8001\u631D",
|
|
4860
|
+
MD: "\u6469\u5C14\u591A\u74E6",
|
|
4861
|
+
MK: "\u5317\u9A6C\u5176\u987F",
|
|
4862
|
+
MM: "\u7F05\u7538",
|
|
4863
|
+
MO: "\u6FB3\u95E8",
|
|
4864
|
+
NL: "\u8377\u5170",
|
|
4865
|
+
PS: "\u5DF4\u52D2\u65AF\u5766",
|
|
4866
|
+
RU: "\u4FC4\u7F57\u65AF",
|
|
4867
|
+
SY: "\u53D9\u5229\u4E9A",
|
|
4868
|
+
SZ: "\u65AF\u5A01\u58EB\u5170",
|
|
4869
|
+
TL: "\u4E1C\u5E1D\u6C76",
|
|
4870
|
+
TW: "\u53F0\u6E7E",
|
|
4871
|
+
TZ: "\u5766\u6851\u5C3C\u4E9A",
|
|
4872
|
+
VA: "\u68B5\u8482\u5188",
|
|
4873
|
+
VE: "\u59D4\u5185\u745E\u62C9"
|
|
4874
|
+
};
|
|
4875
|
+
var EN_OVERRIDES = {
|
|
4876
|
+
HK: "Hong Kong",
|
|
4877
|
+
MO: "Macau",
|
|
4878
|
+
PS: "Palestine",
|
|
4879
|
+
TW: "Taiwan"
|
|
4880
|
+
};
|
|
4881
|
+
var EXTRA_ALIASES = [
|
|
4882
|
+
"Burma",
|
|
4883
|
+
"Cape Verde",
|
|
4884
|
+
"Czechia",
|
|
4885
|
+
"East Timor",
|
|
4886
|
+
"Holland",
|
|
4887
|
+
"Hong Kong",
|
|
4888
|
+
"Macao",
|
|
4889
|
+
"Macau",
|
|
4890
|
+
"North Korea",
|
|
4891
|
+
"South Korea",
|
|
4892
|
+
"UAE",
|
|
4893
|
+
"UK",
|
|
4894
|
+
"USA",
|
|
4895
|
+
"United Kingdom",
|
|
4896
|
+
"United States"
|
|
4897
|
+
];
|
|
4898
|
+
function escapeRegExp(value) {
|
|
4899
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4900
|
+
}
|
|
4901
|
+
var displayNameCache = /* @__PURE__ */ new Map();
|
|
4902
|
+
function displayNames(locale) {
|
|
4903
|
+
const cached = displayNameCache.get(locale);
|
|
4904
|
+
if (cached) {
|
|
4905
|
+
return cached;
|
|
4906
|
+
}
|
|
4907
|
+
try {
|
|
4908
|
+
const created = new Intl.DisplayNames([locale], { fallback: "code", type: "region" });
|
|
4909
|
+
displayNameCache.set(locale, created);
|
|
4910
|
+
return created;
|
|
4911
|
+
} catch {
|
|
4912
|
+
return void 0;
|
|
4913
|
+
}
|
|
4914
|
+
}
|
|
4915
|
+
function normalizeRegionCode(code) {
|
|
4916
|
+
const upper = code.trim().toUpperCase();
|
|
4917
|
+
return /^[A-Z]{2}$/.test(upper) ? upper : "";
|
|
4918
|
+
}
|
|
4919
|
+
function regionDisplayName(code, locale = "zh-CN") {
|
|
4920
|
+
const upper = normalizeRegionCode(code);
|
|
4921
|
+
if (upper === "") {
|
|
4922
|
+
return code.trim();
|
|
4923
|
+
}
|
|
4924
|
+
if (locale.toLowerCase().startsWith("zh") && ZH_OVERRIDES[upper] !== void 0) {
|
|
4925
|
+
return ZH_OVERRIDES[upper];
|
|
4926
|
+
}
|
|
4927
|
+
if (locale.toLowerCase().startsWith("en") && EN_OVERRIDES[upper] !== void 0) {
|
|
4928
|
+
return EN_OVERRIDES[upper];
|
|
4929
|
+
}
|
|
4930
|
+
const names = displayNames(locale);
|
|
4931
|
+
return names?.of(upper) ?? upper;
|
|
4932
|
+
}
|
|
4933
|
+
function regionFlag(code) {
|
|
4934
|
+
const upper = normalizeRegionCode(code);
|
|
4935
|
+
if (upper === "") {
|
|
4936
|
+
return "";
|
|
4937
|
+
}
|
|
4938
|
+
const base = 127462;
|
|
4939
|
+
return String.fromCodePoint(base + upper.charCodeAt(0) - 65, base + upper.charCodeAt(1) - 65);
|
|
4940
|
+
}
|
|
4941
|
+
function isRegionCode(code) {
|
|
4942
|
+
return REGION_CODE_SET.has(normalizeRegionCode(code));
|
|
4943
|
+
}
|
|
4944
|
+
var aliasRegex;
|
|
4945
|
+
function buildAliasRegex() {
|
|
4946
|
+
const ascii = [];
|
|
4947
|
+
const other = [];
|
|
4948
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4949
|
+
const add = (alias) => {
|
|
4950
|
+
const trimmed = alias.trim();
|
|
4951
|
+
if (trimmed.length < 2 || seen.has(trimmed)) {
|
|
4952
|
+
return;
|
|
4953
|
+
}
|
|
4954
|
+
seen.add(trimmed);
|
|
4955
|
+
if (/^[\x20-\x7e]+$/.test(trimmed)) {
|
|
4956
|
+
ascii.push(escapeRegExp(trimmed));
|
|
4957
|
+
} else {
|
|
4958
|
+
other.push(escapeRegExp(trimmed));
|
|
4959
|
+
}
|
|
4960
|
+
};
|
|
4961
|
+
for (const code of REGION_CODES) {
|
|
4962
|
+
add(regionDisplayName(code, "zh-CN"));
|
|
4963
|
+
add(regionDisplayName(code, "en"));
|
|
4964
|
+
add(regionFlag(code));
|
|
4965
|
+
}
|
|
4966
|
+
for (const alias of EXTRA_ALIASES) {
|
|
4967
|
+
add(alias);
|
|
4968
|
+
}
|
|
4969
|
+
const parts = [];
|
|
4970
|
+
if (ascii.length > 0) {
|
|
4971
|
+
parts.push(`(?<![A-Za-z])(?:${ascii.join("|")})(?![A-Za-z])`);
|
|
4972
|
+
}
|
|
4973
|
+
if (other.length > 0) {
|
|
4974
|
+
parts.push(`(?:${other.join("|")})`);
|
|
4975
|
+
}
|
|
4976
|
+
return new RegExp(parts.join("|"), "iu");
|
|
4977
|
+
}
|
|
4978
|
+
function getAliasRegex() {
|
|
4979
|
+
aliasRegex ??= buildAliasRegex();
|
|
4980
|
+
return aliasRegex;
|
|
4981
|
+
}
|
|
4982
|
+
function hasRegionName(remark) {
|
|
4983
|
+
const text = remark.trim();
|
|
4984
|
+
if (text === "") {
|
|
4985
|
+
return false;
|
|
4986
|
+
}
|
|
4987
|
+
if (getAliasRegex().test(text)) {
|
|
4988
|
+
return true;
|
|
4989
|
+
}
|
|
4990
|
+
for (const token of text.split(/[^\p{L}\p{N}]+/u)) {
|
|
4991
|
+
if (token === "") {
|
|
4992
|
+
continue;
|
|
4993
|
+
}
|
|
4994
|
+
if (/^\p{Lu}{2}$/u.test(token) && isRegionCode(token)) {
|
|
4995
|
+
return true;
|
|
4996
|
+
}
|
|
4997
|
+
if (/^[A-Za-z]{2}\d{2}/.test(token) && isRegionCode(token.slice(0, 2))) {
|
|
4998
|
+
return true;
|
|
4999
|
+
}
|
|
5000
|
+
}
|
|
5001
|
+
return false;
|
|
5002
|
+
}
|
|
5003
|
+
function formatCountryRemark(remark, code, locale = "zh-CN") {
|
|
5004
|
+
const name = regionDisplayName(code, locale);
|
|
5005
|
+
const trimmed = remark.trim();
|
|
5006
|
+
if (name === "") {
|
|
5007
|
+
return trimmed;
|
|
5008
|
+
}
|
|
5009
|
+
return trimmed === "" ? name : `${name}-${trimmed}`;
|
|
5010
|
+
}
|
|
5011
|
+
|
|
4248
5012
|
// src/generator/nodes.ts
|
|
4249
5013
|
function toRegex(pattern) {
|
|
4250
5014
|
try {
|
|
@@ -4453,6 +5217,39 @@ function addEmoji(node, emojiArray) {
|
|
|
4453
5217
|
}
|
|
4454
5218
|
return node.remark;
|
|
4455
5219
|
}
|
|
5220
|
+
function nodeNameRegex(node, rules) {
|
|
5221
|
+
const original = node.remark;
|
|
5222
|
+
for (const rule of rules) {
|
|
5223
|
+
if (rule.script !== "" || rule.match === "") {
|
|
5224
|
+
continue;
|
|
5225
|
+
}
|
|
5226
|
+
try {
|
|
5227
|
+
node.remark = node.remark.replace(new RegExp(rule.match, "g"), rule.replace);
|
|
5228
|
+
} catch {
|
|
5229
|
+
}
|
|
5230
|
+
}
|
|
5231
|
+
if (node.remark === "") {
|
|
5232
|
+
node.remark = original;
|
|
5233
|
+
}
|
|
5234
|
+
}
|
|
5235
|
+
var NAME_SEPARATOR_EDGES = /^[-_.\s]+|[-_.\s]+$/g;
|
|
5236
|
+
var NAME_SEPARATOR_RUN = /([-_.\s])[-_.\s]+/g;
|
|
5237
|
+
function nodeNameRemove(node, removeList) {
|
|
5238
|
+
const original = node.remark;
|
|
5239
|
+
let remark = node.remark;
|
|
5240
|
+
let removed = false;
|
|
5241
|
+
for (const fragment of removeList) {
|
|
5242
|
+
if (fragment === "" || !remark.includes(fragment)) {
|
|
5243
|
+
continue;
|
|
5244
|
+
}
|
|
5245
|
+
remark = remark.split(fragment).join("");
|
|
5246
|
+
removed = true;
|
|
5247
|
+
}
|
|
5248
|
+
if (removed) {
|
|
5249
|
+
remark = remark.replace(NAME_SEPARATOR_EDGES, "").replace(NAME_SEPARATOR_RUN, "$1");
|
|
5250
|
+
}
|
|
5251
|
+
node.remark = remark === "" ? original : remark;
|
|
5252
|
+
}
|
|
4456
5253
|
function nodeRename(node, renameArray) {
|
|
4457
5254
|
const original = node.remark;
|
|
4458
5255
|
for (const rule of renameArray) {
|
|
@@ -4468,15 +5265,39 @@ function nodeRename(node, renameArray) {
|
|
|
4468
5265
|
node.remark = original;
|
|
4469
5266
|
}
|
|
4470
5267
|
}
|
|
5268
|
+
function addCountryPrefix(node, resolve, locale = "zh-CN") {
|
|
5269
|
+
const remark = node.remark.trim();
|
|
5270
|
+
if (hasRegionName(remark)) {
|
|
5271
|
+
return node.remark;
|
|
5272
|
+
}
|
|
5273
|
+
const code = resolve(node);
|
|
5274
|
+
if (code === void 0 || code === "") {
|
|
5275
|
+
return node.remark;
|
|
5276
|
+
}
|
|
5277
|
+
return formatCountryRemark(remark, code, locale);
|
|
5278
|
+
}
|
|
4471
5279
|
function preprocessNodes(nodes, options) {
|
|
4472
5280
|
for (const node of nodes) {
|
|
4473
5281
|
if (options.removeEmoji) {
|
|
4474
5282
|
node.remark = removeEmoji(node.remark).trim();
|
|
4475
5283
|
}
|
|
5284
|
+
if (options.nameRegexArray && options.nameRegexArray.length > 0) {
|
|
5285
|
+
nodeNameRegex(node, options.nameRegexArray);
|
|
5286
|
+
}
|
|
5287
|
+
if (options.nameRemove && options.nameRemove.length > 0) {
|
|
5288
|
+
nodeNameRemove(node, options.nameRemove);
|
|
5289
|
+
}
|
|
4476
5290
|
nodeRename(node, options.renameArray);
|
|
4477
5291
|
if (options.addEmoji) {
|
|
4478
5292
|
node.remark = addEmoji(node, options.emojiArray);
|
|
4479
5293
|
}
|
|
5294
|
+
if (options.autoCountry && options.countryResolver) {
|
|
5295
|
+
node.remark = addCountryPrefix(
|
|
5296
|
+
node,
|
|
5297
|
+
options.countryResolver,
|
|
5298
|
+
options.countryLocale ?? "zh-CN"
|
|
5299
|
+
);
|
|
5300
|
+
}
|
|
4480
5301
|
}
|
|
4481
5302
|
if (options.sortFlag) {
|
|
4482
5303
|
nodes.sort((a, b) => a.remark < b.remark ? -1 : a.remark > b.remark ? 1 : 0);
|
|
@@ -4886,6 +5707,14 @@ function buildClashProxy(x, settings, clashR, remark, skipCertVerify, tfo) {
|
|
|
4886
5707
|
if (x.fingerprint !== "") {
|
|
4887
5708
|
proxy["client-fingerprint"] = x.fingerprint;
|
|
4888
5709
|
}
|
|
5710
|
+
if (x.publicKey !== "" || x.shortId !== "") {
|
|
5711
|
+
const realityOpts = {};
|
|
5712
|
+
if (x.publicKey !== "") {
|
|
5713
|
+
realityOpts["public-key"] = x.publicKey;
|
|
5714
|
+
}
|
|
5715
|
+
realityOpts["short-id"] = x.shortId;
|
|
5716
|
+
proxy["reality-opts"] = realityOpts;
|
|
5717
|
+
}
|
|
4889
5718
|
if (x.alpn.length > 0) {
|
|
4890
5719
|
proxy.alpn = x.alpn;
|
|
4891
5720
|
}
|
|
@@ -4969,60 +5798,60 @@ function buildClash(nodes, extraProxyGroup, settings, clashR = false) {
|
|
|
4969
5798
|
return { doc: { proxies }, nodeList };
|
|
4970
5799
|
}
|
|
4971
5800
|
const groups = [];
|
|
4972
|
-
for (const
|
|
5801
|
+
for (const group2 of extraProxyGroup) {
|
|
4973
5802
|
const singlegroup = {
|
|
4974
|
-
name:
|
|
4975
|
-
type:
|
|
5803
|
+
name: group2.name,
|
|
5804
|
+
type: group2.type === "smart" ? "url-test" : group2.type
|
|
4976
5805
|
};
|
|
4977
|
-
switch (
|
|
5806
|
+
switch (group2.type) {
|
|
4978
5807
|
case "select":
|
|
4979
5808
|
case "relay":
|
|
4980
5809
|
break;
|
|
4981
5810
|
case "load-balance":
|
|
4982
|
-
singlegroup.strategy =
|
|
4983
|
-
singlegroup.lazy =
|
|
4984
|
-
singlegroup.url =
|
|
4985
|
-
if (
|
|
4986
|
-
singlegroup.interval =
|
|
5811
|
+
singlegroup.strategy = group2.strategy;
|
|
5812
|
+
singlegroup.lazy = group2.lazy;
|
|
5813
|
+
singlegroup.url = group2.url;
|
|
5814
|
+
if (group2.interval > 0) {
|
|
5815
|
+
singlegroup.interval = group2.interval;
|
|
4987
5816
|
}
|
|
4988
|
-
if (
|
|
4989
|
-
singlegroup.tolerance =
|
|
5817
|
+
if (group2.tolerance > 0) {
|
|
5818
|
+
singlegroup.tolerance = group2.tolerance;
|
|
4990
5819
|
}
|
|
4991
5820
|
break;
|
|
4992
5821
|
case "smart":
|
|
4993
5822
|
case "url-test":
|
|
4994
|
-
if (
|
|
4995
|
-
singlegroup.lazy =
|
|
5823
|
+
if (group2.lazy !== void 0) {
|
|
5824
|
+
singlegroup.lazy = group2.lazy;
|
|
4996
5825
|
}
|
|
4997
|
-
singlegroup.url =
|
|
4998
|
-
if (
|
|
4999
|
-
singlegroup.interval =
|
|
5826
|
+
singlegroup.url = group2.url;
|
|
5827
|
+
if (group2.interval > 0) {
|
|
5828
|
+
singlegroup.interval = group2.interval;
|
|
5000
5829
|
}
|
|
5001
|
-
if (
|
|
5002
|
-
singlegroup.tolerance =
|
|
5830
|
+
if (group2.tolerance > 0) {
|
|
5831
|
+
singlegroup.tolerance = group2.tolerance;
|
|
5003
5832
|
}
|
|
5004
5833
|
break;
|
|
5005
5834
|
case "fallback":
|
|
5006
|
-
singlegroup.url =
|
|
5007
|
-
if (
|
|
5008
|
-
singlegroup.interval =
|
|
5835
|
+
singlegroup.url = group2.url;
|
|
5836
|
+
if (group2.interval > 0) {
|
|
5837
|
+
singlegroup.interval = group2.interval;
|
|
5009
5838
|
}
|
|
5010
|
-
if (
|
|
5011
|
-
singlegroup.tolerance =
|
|
5839
|
+
if (group2.tolerance > 0) {
|
|
5840
|
+
singlegroup.tolerance = group2.tolerance;
|
|
5012
5841
|
}
|
|
5013
5842
|
break;
|
|
5014
5843
|
default:
|
|
5015
5844
|
continue;
|
|
5016
5845
|
}
|
|
5017
|
-
if (
|
|
5018
|
-
singlegroup["disable-udp"] =
|
|
5846
|
+
if (group2.disableUdp !== void 0) {
|
|
5847
|
+
singlegroup["disable-udp"] = group2.disableUdp;
|
|
5019
5848
|
}
|
|
5020
5849
|
const filtered = [];
|
|
5021
|
-
for (const rule of
|
|
5850
|
+
for (const rule of group2.proxies) {
|
|
5022
5851
|
groupGenerate(rule, nodeList, filtered, true);
|
|
5023
5852
|
}
|
|
5024
|
-
if (
|
|
5025
|
-
singlegroup.use =
|
|
5853
|
+
if (group2.usingProvider.length > 0) {
|
|
5854
|
+
singlegroup.use = group2.usingProvider;
|
|
5026
5855
|
} else {
|
|
5027
5856
|
if (filtered.length === 0) {
|
|
5028
5857
|
filtered.push("DIRECT");
|
|
@@ -5056,6 +5885,162 @@ function toClash(nodes, extraProxyGroup, settings, clashR = false) {
|
|
|
5056
5885
|
return stringifyClash(doc);
|
|
5057
5886
|
}
|
|
5058
5887
|
|
|
5888
|
+
// src/generator/default-profile.ts
|
|
5889
|
+
var TEST_URL = "http://www.gstatic.com/generate_204";
|
|
5890
|
+
function group(name, type, proxies, extra = {}) {
|
|
5891
|
+
return {
|
|
5892
|
+
disableUdp: void 0,
|
|
5893
|
+
evaluateBeforeUse: void 0,
|
|
5894
|
+
interval: 0,
|
|
5895
|
+
lazy: void 0,
|
|
5896
|
+
name,
|
|
5897
|
+
persistent: void 0,
|
|
5898
|
+
proxies: [...proxies],
|
|
5899
|
+
strategy: "consistent-hashing" /* ConsistentHashing */,
|
|
5900
|
+
timeout: 5,
|
|
5901
|
+
tolerance: 0,
|
|
5902
|
+
type,
|
|
5903
|
+
url: "",
|
|
5904
|
+
usingProvider: [],
|
|
5905
|
+
...extra
|
|
5906
|
+
};
|
|
5907
|
+
}
|
|
5908
|
+
function getDefaultProxyGroups() {
|
|
5909
|
+
return [
|
|
5910
|
+
group("\u{1F680} \u8282\u70B9\u9009\u62E9", "select" /* Select */, ["[]\u267B\uFE0F \u81EA\u52A8\u9009\u62E9", "[]DIRECT", ".*"]),
|
|
5911
|
+
group("\u267B\uFE0F \u81EA\u52A8\u9009\u62E9", "url-test" /* URLTest */, [".*"], {
|
|
5912
|
+
interval: 300,
|
|
5913
|
+
tolerance: 50,
|
|
5914
|
+
url: TEST_URL
|
|
5915
|
+
}),
|
|
5916
|
+
group("\u{1F30D} \u56FD\u5916\u5A92\u4F53", "select" /* Select */, [
|
|
5917
|
+
"[]\u{1F680} \u8282\u70B9\u9009\u62E9",
|
|
5918
|
+
"[]\u267B\uFE0F \u81EA\u52A8\u9009\u62E9",
|
|
5919
|
+
"[]\u{1F3AF} \u5168\u7403\u76F4\u8FDE",
|
|
5920
|
+
".*"
|
|
5921
|
+
]),
|
|
5922
|
+
group("\u{1F4F2} \u7535\u62A5\u4FE1\u606F", "select" /* Select */, ["[]\u{1F680} \u8282\u70B9\u9009\u62E9", "[]\u{1F3AF} \u5168\u7403\u76F4\u8FDE", ".*"]),
|
|
5923
|
+
group("\u24C2\uFE0F \u5FAE\u8F6F\u670D\u52A1", "select" /* Select */, ["[]\u{1F3AF} \u5168\u7403\u76F4\u8FDE", "[]\u{1F680} \u8282\u70B9\u9009\u62E9", ".*"]),
|
|
5924
|
+
group("\u{1F34E} \u82F9\u679C\u670D\u52A1", "select" /* Select */, ["[]\u{1F680} \u8282\u70B9\u9009\u62E9", "[]\u{1F3AF} \u5168\u7403\u76F4\u8FDE", ".*"]),
|
|
5925
|
+
group("\u{1F3AF} \u5168\u7403\u76F4\u8FDE", "select" /* Select */, ["[]DIRECT", "[]\u{1F680} \u8282\u70B9\u9009\u62E9", "[]\u267B\uFE0F \u81EA\u52A8\u9009\u62E9"]),
|
|
5926
|
+
group("\u{1F6D1} \u5168\u7403\u62E6\u622A", "select" /* Select */, ["[]REJECT", "[]DIRECT"]),
|
|
5927
|
+
group("\u{1F343} \u5E94\u7528\u51C0\u5316", "select" /* Select */, ["[]REJECT", "[]DIRECT"]),
|
|
5928
|
+
group("\u{1F41F} \u6F0F\u7F51\u4E4B\u9C7C", "select" /* Select */, [
|
|
5929
|
+
"[]\u{1F680} \u8282\u70B9\u9009\u62E9",
|
|
5930
|
+
"[]\u{1F3AF} \u5168\u7403\u76F4\u8FDE",
|
|
5931
|
+
"[]\u267B\uFE0F \u81EA\u52A8\u9009\u62E9",
|
|
5932
|
+
".*"
|
|
5933
|
+
])
|
|
5934
|
+
];
|
|
5935
|
+
}
|
|
5936
|
+
function inline(group2, rule) {
|
|
5937
|
+
return {
|
|
5938
|
+
content: `[]${rule}`,
|
|
5939
|
+
ruleGroup: group2,
|
|
5940
|
+
rulePath: "",
|
|
5941
|
+
rulePathTyped: "",
|
|
5942
|
+
ruleType: "surge" /* Surge */,
|
|
5943
|
+
updateInterval: 86400
|
|
5944
|
+
};
|
|
5945
|
+
}
|
|
5946
|
+
function surge(group2, lines) {
|
|
5947
|
+
return {
|
|
5948
|
+
content: lines.join("\n"),
|
|
5949
|
+
ruleGroup: group2,
|
|
5950
|
+
rulePath: "",
|
|
5951
|
+
rulePathTyped: "",
|
|
5952
|
+
ruleType: "surge" /* Surge */,
|
|
5953
|
+
updateInterval: 86400
|
|
5954
|
+
};
|
|
5955
|
+
}
|
|
5956
|
+
function getDefaultRulesets() {
|
|
5957
|
+
return [
|
|
5958
|
+
surge("\u{1F3AF} \u5168\u7403\u76F4\u8FDE", [
|
|
5959
|
+
"DOMAIN-SUFFIX,localhost",
|
|
5960
|
+
"DOMAIN,localhost",
|
|
5961
|
+
"IP-CIDR,127.0.0.0/8",
|
|
5962
|
+
"IP-CIDR,10.0.0.0/8",
|
|
5963
|
+
"IP-CIDR,172.16.0.0/12",
|
|
5964
|
+
"IP-CIDR,192.168.0.0/16",
|
|
5965
|
+
"IP-CIDR,224.0.0.0/4",
|
|
5966
|
+
"DOMAIN-SUFFIX,cn",
|
|
5967
|
+
"DOMAIN-SUFFIX,126.com",
|
|
5968
|
+
"DOMAIN-SUFFIX,163.com",
|
|
5969
|
+
"DOMAIN-SUFFIX,qq.com",
|
|
5970
|
+
"DOMAIN-SUFFIX,baidu.com",
|
|
5971
|
+
"DOMAIN-SUFFIX,alibaba.com",
|
|
5972
|
+
"DOMAIN-SUFFIX,taobao.com"
|
|
5973
|
+
]),
|
|
5974
|
+
surge("\u{1F6D1} \u5168\u7403\u62E6\u622A", [
|
|
5975
|
+
"DOMAIN-SUFFIX,doubleclick.net",
|
|
5976
|
+
"DOMAIN-SUFFIX,googlesyndication.com",
|
|
5977
|
+
"DOMAIN-SUFFIX,googleadservices.com",
|
|
5978
|
+
"DOMAIN-SUFFIX,ads.yahoo.com",
|
|
5979
|
+
"DOMAIN-KEYWORD,adservice",
|
|
5980
|
+
"DOMAIN-KEYWORD,advertising"
|
|
5981
|
+
]),
|
|
5982
|
+
surge("\u{1F343} \u5E94\u7528\u51C0\u5316", [
|
|
5983
|
+
"DOMAIN-SUFFIX,app-measurement.com",
|
|
5984
|
+
"DOMAIN-SUFFIX,crashlytics.com",
|
|
5985
|
+
"DOMAIN-KEYWORD,analytics",
|
|
5986
|
+
"DOMAIN-KEYWORD,tracking"
|
|
5987
|
+
]),
|
|
5988
|
+
surge("\u{1F30D} \u56FD\u5916\u5A92\u4F53", [
|
|
5989
|
+
"DOMAIN-SUFFIX,netflix.com",
|
|
5990
|
+
"DOMAIN-SUFFIX,nflxvideo.net",
|
|
5991
|
+
"DOMAIN-SUFFIX,youtube.com",
|
|
5992
|
+
"DOMAIN-SUFFIX,googlevideo.com",
|
|
5993
|
+
"DOMAIN-SUFFIX,disneyplus.com",
|
|
5994
|
+
"DOMAIN-SUFFIX,spotify.com",
|
|
5995
|
+
"DOMAIN-SUFFIX,tiktok.com"
|
|
5996
|
+
]),
|
|
5997
|
+
surge("\u{1F4F2} \u7535\u62A5\u4FE1\u606F", [
|
|
5998
|
+
"DOMAIN-SUFFIX,telegram.org",
|
|
5999
|
+
"DOMAIN-SUFFIX,t.me",
|
|
6000
|
+
"DOMAIN-SUFFIX,telegram.me",
|
|
6001
|
+
"IP-CIDR,149.154.160.0/20",
|
|
6002
|
+
"IP-CIDR,91.108.4.0/22"
|
|
6003
|
+
]),
|
|
6004
|
+
surge("\u24C2\uFE0F \u5FAE\u8F6F\u670D\u52A1", [
|
|
6005
|
+
"DOMAIN-SUFFIX,microsoft.com",
|
|
6006
|
+
"DOMAIN-SUFFIX,windows.com",
|
|
6007
|
+
"DOMAIN-SUFFIX,office.com",
|
|
6008
|
+
"DOMAIN-SUFFIX,live.com"
|
|
6009
|
+
]),
|
|
6010
|
+
surge("\u{1F34E} \u82F9\u679C\u670D\u52A1", [
|
|
6011
|
+
"DOMAIN-SUFFIX,apple.com",
|
|
6012
|
+
"DOMAIN-SUFFIX,icloud.com",
|
|
6013
|
+
"DOMAIN-SUFFIX,apple-cloudkit.com"
|
|
6014
|
+
]),
|
|
6015
|
+
surge("\u{1F680} \u8282\u70B9\u9009\u62E9", ["DOMAIN-SUFFIX,google.com", "DOMAIN-SUFFIX,github.com"]),
|
|
6016
|
+
inline("\u{1F3AF} \u5168\u7403\u76F4\u8FDE", "GEOIP,CN"),
|
|
6017
|
+
inline("\u{1F41F} \u6F0F\u7F51\u4E4B\u9C7C", "FINAL")
|
|
6018
|
+
];
|
|
6019
|
+
}
|
|
6020
|
+
function getDefaultRulesetConfigs() {
|
|
6021
|
+
const base = "https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash";
|
|
6022
|
+
const list = (group2, file) => ({
|
|
6023
|
+
group: group2,
|
|
6024
|
+
interval: 86400,
|
|
6025
|
+
url: `${base}/${file}`
|
|
6026
|
+
});
|
|
6027
|
+
return [
|
|
6028
|
+
list("\u{1F3AF} \u5168\u7403\u76F4\u8FDE", "LocalAreaNetwork.list"),
|
|
6029
|
+
list("\u{1F6D1} \u5168\u7403\u62E6\u622A", "BanAD.list"),
|
|
6030
|
+
list("\u{1F343} \u5E94\u7528\u51C0\u5316", "BanProgramAD.list"),
|
|
6031
|
+
list("\u{1F3AF} \u5168\u7403\u76F4\u8FDE", "GoogleCN.list"),
|
|
6032
|
+
list("\u24C2\uFE0F \u5FAE\u8F6F\u670D\u52A1", "Microsoft.list"),
|
|
6033
|
+
list("\u{1F34E} \u82F9\u679C\u670D\u52A1", "Apple.list"),
|
|
6034
|
+
list("\u{1F30D} \u56FD\u5916\u5A92\u4F53", "ProxyMedia.list"),
|
|
6035
|
+
list("\u{1F4F2} \u7535\u62A5\u4FE1\u606F", "Telegram.list"),
|
|
6036
|
+
list("\u{1F680} \u8282\u70B9\u9009\u62E9", "ProxyLite.list"),
|
|
6037
|
+
list("\u{1F3AF} \u5168\u7403\u76F4\u8FDE", "ChinaDomain.list"),
|
|
6038
|
+
list("\u{1F3AF} \u5168\u7403\u76F4\u8FDE", "ChinaCompanyIp.list"),
|
|
6039
|
+
{ group: "\u{1F3AF} \u5168\u7403\u76F4\u8FDE", interval: 86400, url: "[]GEOIP,CN" },
|
|
6040
|
+
{ group: "\u{1F41F} \u6F0F\u7F51\u4E4B\u9C7C", interval: 86400, url: "[]FINAL" }
|
|
6041
|
+
];
|
|
6042
|
+
}
|
|
6043
|
+
|
|
5059
6044
|
// src/generator/links.ts
|
|
5060
6045
|
function vmessLinkConstruct(remarks, add, port, type, id, aid, net, path, host, tls) {
|
|
5061
6046
|
return JSON.stringify({
|
|
@@ -5081,8 +6066,8 @@ function ssLinkConstruct(proxy) {
|
|
|
5081
6066
|
link += `#${urlEncode(proxy.remark)}`;
|
|
5082
6067
|
return link;
|
|
5083
6068
|
}
|
|
5084
|
-
function ssrLinkConstruct(hostname, port, protocol, method, obfs, password,
|
|
5085
|
-
const payload = `${hostname}:${port}:${protocol}:${method}:${obfs}:${urlSafeBase64Encode(password)}/?group=${urlSafeBase64Encode(
|
|
6069
|
+
function ssrLinkConstruct(hostname, port, protocol, method, obfs, password, group2, remark, obfsParam = "", protocolParam = "") {
|
|
6070
|
+
const payload = `${hostname}:${port}:${protocol}:${method}:${obfs}:${urlSafeBase64Encode(password)}/?group=${urlSafeBase64Encode(group2)}&remarks=${urlSafeBase64Encode(remark)}&obfsparam=${urlSafeBase64Encode(obfsParam)}&protoparam=${urlSafeBase64Encode(protocolParam)}`;
|
|
5086
6071
|
return `ssr://${urlSafeBase64Encode(payload)}`;
|
|
5087
6072
|
}
|
|
5088
6073
|
function trojanLinkConstruct(proxy) {
|
|
@@ -5229,8 +6214,8 @@ function proxyToSsSub(nodes, baseConf) {
|
|
|
5229
6214
|
}
|
|
5230
6215
|
return JSON.stringify(proxies);
|
|
5231
6216
|
}
|
|
5232
|
-
function proxyToSsd(nodes,
|
|
5233
|
-
const resolvedGroup =
|
|
6217
|
+
function proxyToSsd(nodes, group2, userinfo) {
|
|
6218
|
+
const resolvedGroup = group2 === "" ? "SSD" : group2;
|
|
5234
6219
|
const doc = {
|
|
5235
6220
|
airport: resolvedGroup,
|
|
5236
6221
|
encryption: "aes-128-gcm",
|
|
@@ -5243,7 +6228,7 @@ function proxyToSsd(nodes, group, userinfo) {
|
|
|
5243
6228
|
const download = getUrlArg(data, "download");
|
|
5244
6229
|
const total = getUrlArg(data, "total");
|
|
5245
6230
|
const expiry = getUrlArg(data, "expire");
|
|
5246
|
-
const gb =
|
|
6231
|
+
const gb = 1e3 ** 3;
|
|
5247
6232
|
doc.traffic_used = (Number(upload || 0) + Number(download || 0)) / gb;
|
|
5248
6233
|
doc.traffic_total = Number(total || 0) / gb;
|
|
5249
6234
|
if (expiry !== "") {
|
|
@@ -5482,6 +6467,14 @@ function buildSurge(nodes, extraProxyGroup, settings, options) {
|
|
|
5482
6467
|
if (x.host !== "") {
|
|
5483
6468
|
proxy += `, sni=${x.host}`;
|
|
5484
6469
|
}
|
|
6470
|
+
if (x.transferProtocol === "ws") {
|
|
6471
|
+
proxy += ", ws=true";
|
|
6472
|
+
if (x.path !== "") {
|
|
6473
|
+
proxy += `, ws-path=${x.path}`;
|
|
6474
|
+
}
|
|
6475
|
+
const wsHost = x.host !== "" ? x.host : x.hostname;
|
|
6476
|
+
proxy += `, ws-headers=Host:"${wsHost}"`;
|
|
6477
|
+
}
|
|
5485
6478
|
if (scv !== void 0) {
|
|
5486
6479
|
proxy += `, skip-cert-verify=${triStr(scv)}`;
|
|
5487
6480
|
}
|
|
@@ -5527,7 +6520,7 @@ function buildSurge(nodes, extraProxyGroup, settings, options) {
|
|
|
5527
6520
|
if (surgeVer < 4) {
|
|
5528
6521
|
continue;
|
|
5529
6522
|
}
|
|
5530
|
-
proxy = `
|
|
6523
|
+
proxy = `hysteria2, ${x.hostname}, ${x.port}, password=${x.password}`;
|
|
5531
6524
|
if (x.downSpeed) {
|
|
5532
6525
|
proxy += `, download-bandwidth=${x.downSpeed}`;
|
|
5533
6526
|
}
|
|
@@ -5570,10 +6563,10 @@ function buildSurge(nodes, extraProxyGroup, settings, options) {
|
|
|
5570
6563
|
return { extraSections, groups: [], proxies, sectionOrder };
|
|
5571
6564
|
}
|
|
5572
6565
|
const groups = [];
|
|
5573
|
-
for (const
|
|
6566
|
+
for (const group2 of extraProxyGroup) {
|
|
5574
6567
|
const filtered = [];
|
|
5575
6568
|
let groupLine = "";
|
|
5576
|
-
switch (
|
|
6569
|
+
switch (group2.type) {
|
|
5577
6570
|
case "select":
|
|
5578
6571
|
case "smart":
|
|
5579
6572
|
case "url-test":
|
|
@@ -5585,15 +6578,15 @@ function buildSurge(nodes, extraProxyGroup, settings, options) {
|
|
|
5585
6578
|
}
|
|
5586
6579
|
break;
|
|
5587
6580
|
case "ssid": {
|
|
5588
|
-
const rest =
|
|
5589
|
-
const line = `${
|
|
5590
|
-
groups.push(`${
|
|
6581
|
+
const rest = group2.proxies.slice(1).join(",");
|
|
6582
|
+
const line = `${group2.type},default=${group2.proxies[0] ?? ""},${rest}`;
|
|
6583
|
+
groups.push(`${group2.name} = ${line}`);
|
|
5591
6584
|
continue;
|
|
5592
6585
|
}
|
|
5593
6586
|
default:
|
|
5594
6587
|
continue;
|
|
5595
6588
|
}
|
|
5596
|
-
for (const rule of
|
|
6589
|
+
for (const rule of group2.proxies) {
|
|
5597
6590
|
groupGenerate(rule, nodelist, filtered, true);
|
|
5598
6591
|
}
|
|
5599
6592
|
if (filtered.length === 0) {
|
|
@@ -5602,27 +6595,27 @@ function buildSurge(nodes, extraProxyGroup, settings, options) {
|
|
|
5602
6595
|
if (filtered.length === 1) {
|
|
5603
6596
|
const single = filtered[0].toLowerCase();
|
|
5604
6597
|
if (single === "direct" || single === "reject" || single === "reject-tinygif") {
|
|
5605
|
-
proxies.push(`${
|
|
6598
|
+
proxies.push(`${group2.name} = ${single}`);
|
|
5606
6599
|
continue;
|
|
5607
6600
|
}
|
|
5608
6601
|
}
|
|
5609
|
-
groupLine = `${
|
|
5610
|
-
if (
|
|
5611
|
-
groupLine += `,url=${
|
|
5612
|
-
if (
|
|
5613
|
-
groupLine += `,tolerance=${
|
|
6602
|
+
groupLine = `${group2.type},${filtered.join(",")}`;
|
|
6603
|
+
if (group2.type === "url-test" || group2.type === "fallback" || group2.type === "load-balance") {
|
|
6604
|
+
groupLine += `,url=${group2.url},interval=${group2.interval}`;
|
|
6605
|
+
if (group2.tolerance > 0) {
|
|
6606
|
+
groupLine += `,tolerance=${group2.tolerance}`;
|
|
5614
6607
|
}
|
|
5615
|
-
if (
|
|
5616
|
-
groupLine += `,timeout=${
|
|
6608
|
+
if (group2.timeout > 0) {
|
|
6609
|
+
groupLine += `,timeout=${group2.timeout}`;
|
|
5617
6610
|
}
|
|
5618
|
-
if (
|
|
5619
|
-
groupLine += `,persistent=${triStr(
|
|
6611
|
+
if (group2.persistent !== void 0) {
|
|
6612
|
+
groupLine += `,persistent=${triStr(group2.persistent)}`;
|
|
5620
6613
|
}
|
|
5621
|
-
if (
|
|
5622
|
-
groupLine += `,evaluate-before-use=${triStr(
|
|
6614
|
+
if (group2.evaluateBeforeUse !== void 0) {
|
|
6615
|
+
groupLine += `,evaluate-before-use=${triStr(group2.evaluateBeforeUse)}`;
|
|
5623
6616
|
}
|
|
5624
6617
|
}
|
|
5625
|
-
groups.push(`${
|
|
6618
|
+
groups.push(`${group2.name} = ${groupLine}`);
|
|
5626
6619
|
}
|
|
5627
6620
|
return { extraSections, groups, proxies, sectionOrder };
|
|
5628
6621
|
}
|
|
@@ -5722,11 +6715,47 @@ function buildLoonNode(x, settings, remark) {
|
|
|
5722
6715
|
proxy += `,skip-cert-verify=${scv ? "true" : "false"}`;
|
|
5723
6716
|
}
|
|
5724
6717
|
break;
|
|
6718
|
+
case "vless" /* VLESS */:
|
|
6719
|
+
if (x.transferProtocol !== "" && x.transferProtocol !== "tcp" && x.transferProtocol !== "ws") {
|
|
6720
|
+
return void 0;
|
|
6721
|
+
}
|
|
6722
|
+
proxy = `VLESS,${hostname},${port},"${x.userId}"`;
|
|
6723
|
+
if (x.flow !== "") {
|
|
6724
|
+
proxy += `,flow=${x.flow}`;
|
|
6725
|
+
}
|
|
6726
|
+
if (x.publicKey !== "") {
|
|
6727
|
+
proxy += `,public-key="${x.publicKey}"`;
|
|
6728
|
+
}
|
|
6729
|
+
if (x.shortId !== "") {
|
|
6730
|
+
proxy += `,short-id=${x.shortId}`;
|
|
6731
|
+
}
|
|
6732
|
+
if (x.transferProtocol === "ws") {
|
|
6733
|
+
proxy += `,path=${x.path},host=${x.host}`;
|
|
6734
|
+
}
|
|
6735
|
+
proxy += `,transport=${x.transferProtocol === "ws" ? "ws" : "tcp"}`;
|
|
6736
|
+
if (x.udp !== void 0) {
|
|
6737
|
+
proxy += `,udp=${x.udp ? "true" : "false"}`;
|
|
6738
|
+
} else {
|
|
6739
|
+
proxy += ",udp=false";
|
|
6740
|
+
}
|
|
6741
|
+
proxy += `,over-tls=${x.tlsSecure ? "true" : "false"}`;
|
|
6742
|
+
if (x.tlsSecure && x.serverName !== "") {
|
|
6743
|
+
proxy += `,sni=${x.serverName}`;
|
|
6744
|
+
}
|
|
6745
|
+
if (scv !== void 0) {
|
|
6746
|
+
proxy += `,skip-cert-verify=${scv ? "true" : "false"}`;
|
|
6747
|
+
}
|
|
6748
|
+
break;
|
|
5725
6749
|
case "trojan" /* Trojan */:
|
|
5726
6750
|
proxy = `trojan,${hostname},${port},"${x.password}"`;
|
|
5727
6751
|
if (x.host !== "") {
|
|
5728
6752
|
proxy += `,tls-name=${x.host}`;
|
|
5729
6753
|
}
|
|
6754
|
+
if (x.transferProtocol === "ws") {
|
|
6755
|
+
proxy += `,transport=ws,path=${x.path},host=${x.host}`;
|
|
6756
|
+
} else {
|
|
6757
|
+
proxy += ",transport=tcp";
|
|
6758
|
+
}
|
|
5730
6759
|
if (scv !== void 0) {
|
|
5731
6760
|
proxy += `,skip-cert-verify=${scv ? "true" : "false"}`;
|
|
5732
6761
|
}
|
|
@@ -5768,26 +6797,22 @@ function buildLoonNode(x, settings, remark) {
|
|
|
5768
6797
|
proxy += `, peers=[{${generatePeer(x, true)}}]`;
|
|
5769
6798
|
break;
|
|
5770
6799
|
case "hysteria2" /* Hysteria2 */:
|
|
5771
|
-
proxy = `
|
|
5772
|
-
if (scv !== void 0) {
|
|
5773
|
-
proxy += `,skip-cert-verify=${scv ? "true" : "false"}`;
|
|
5774
|
-
}
|
|
5775
|
-
if (x.fingerprint !== "") {
|
|
5776
|
-
proxy += `,tls-cert-sha256=${x.fingerprint}`;
|
|
5777
|
-
}
|
|
6800
|
+
proxy = `Hysteria2,${hostname},${port},"${x.password}"`;
|
|
5778
6801
|
if (x.sni !== "") {
|
|
5779
6802
|
proxy += `,sni=${x.sni}`;
|
|
5780
6803
|
}
|
|
5781
|
-
|
|
5782
|
-
|
|
5783
|
-
proxy = `anytls,${hostname},${port},"${x.password}"`;
|
|
5784
|
-
if (x.sni !== "") {
|
|
5785
|
-
proxy += `,sni=${x.sni}`;
|
|
6804
|
+
if (x.downSpeed > 0) {
|
|
6805
|
+
proxy += `,download-bandwidth=${x.downSpeed}`;
|
|
5786
6806
|
}
|
|
5787
6807
|
if (scv !== void 0) {
|
|
5788
6808
|
proxy += `,skip-cert-verify=${scv ? "true" : "false"}`;
|
|
5789
6809
|
}
|
|
6810
|
+
if (x.fingerprint !== "") {
|
|
6811
|
+
proxy += `,tls-cert-sha256=${x.fingerprint}`;
|
|
6812
|
+
}
|
|
5790
6813
|
break;
|
|
6814
|
+
// Loon has no AnyTLS/TUIC mapping — keep the drop instead of
|
|
6815
|
+
// emitting non-standard lines.
|
|
5791
6816
|
default:
|
|
5792
6817
|
return void 0;
|
|
5793
6818
|
}
|
|
@@ -5802,48 +6827,48 @@ function buildLoonNode(x, settings, remark) {
|
|
|
5802
6827
|
}
|
|
5803
6828
|
function buildLoonGroups(extraProxyGroup, nodelist) {
|
|
5804
6829
|
const lines = [];
|
|
5805
|
-
for (const
|
|
6830
|
+
for (const group2 of extraProxyGroup) {
|
|
5806
6831
|
const filtered = [];
|
|
5807
|
-
switch (
|
|
6832
|
+
switch (group2.type) {
|
|
5808
6833
|
case "select":
|
|
5809
6834
|
case "load-balance":
|
|
5810
6835
|
case "url-test":
|
|
5811
6836
|
case "fallback":
|
|
5812
6837
|
break;
|
|
5813
6838
|
case "ssid":
|
|
5814
|
-
if (
|
|
6839
|
+
if (group2.proxies.length < 2) {
|
|
5815
6840
|
continue;
|
|
5816
6841
|
}
|
|
5817
6842
|
lines.push(
|
|
5818
|
-
`${
|
|
6843
|
+
`${group2.name} = ssid,default=${group2.proxies[0]},${group2.proxies.slice(1).join(",")}`
|
|
5819
6844
|
);
|
|
5820
6845
|
continue;
|
|
5821
6846
|
default:
|
|
5822
6847
|
continue;
|
|
5823
6848
|
}
|
|
5824
|
-
for (const rule of
|
|
6849
|
+
for (const rule of group2.proxies) {
|
|
5825
6850
|
groupGenerate(rule, nodelist, filtered, true);
|
|
5826
6851
|
}
|
|
5827
6852
|
if (filtered.length === 0) {
|
|
5828
6853
|
filtered.push("DIRECT");
|
|
5829
6854
|
}
|
|
5830
|
-
let groupLine = `${
|
|
5831
|
-
if (
|
|
5832
|
-
groupLine += `,url=${
|
|
5833
|
-
if (
|
|
5834
|
-
groupLine += `,algorithm=${
|
|
5835
|
-
if (
|
|
5836
|
-
groupLine += `,max-timeout=${
|
|
6855
|
+
let groupLine = `${group2.type},${filtered.join(",")}`;
|
|
6856
|
+
if (group2.type !== "select") {
|
|
6857
|
+
groupLine += `,url=${group2.url},interval=${group2.interval}`;
|
|
6858
|
+
if (group2.type === "load-balance") {
|
|
6859
|
+
groupLine += `,algorithm=${group2.strategy === "round-robin" ? "round-robin" : "pcc"}`;
|
|
6860
|
+
if (group2.timeout > 0) {
|
|
6861
|
+
groupLine += `,max-timeout=${group2.timeout}`;
|
|
5837
6862
|
}
|
|
5838
6863
|
}
|
|
5839
|
-
if (
|
|
5840
|
-
groupLine += `,tolerance=${
|
|
6864
|
+
if (group2.type === "url-test" && group2.tolerance > 0) {
|
|
6865
|
+
groupLine += `,tolerance=${group2.tolerance}`;
|
|
5841
6866
|
}
|
|
5842
|
-
if (
|
|
5843
|
-
groupLine += `,max-timeout=${
|
|
6867
|
+
if (group2.type === "fallback") {
|
|
6868
|
+
groupLine += `,max-timeout=${group2.timeout}`;
|
|
5844
6869
|
}
|
|
5845
6870
|
}
|
|
5846
|
-
lines.push(`${
|
|
6871
|
+
lines.push(`${group2.name} = ${groupLine}`);
|
|
5847
6872
|
}
|
|
5848
6873
|
return lines;
|
|
5849
6874
|
}
|
|
@@ -5874,6 +6899,9 @@ function toLoon(nodes, extraProxyGroup, settings, options) {
|
|
|
5874
6899
|
if (groupLines.length > 0) {
|
|
5875
6900
|
setRawSection(sections, "Proxy Group", groupLines);
|
|
5876
6901
|
}
|
|
6902
|
+
if (options.rules && options.rules.lines.length > 0) {
|
|
6903
|
+
setRawSection(sections, options.rules.section, options.rules.lines);
|
|
6904
|
+
}
|
|
5877
6905
|
return renderRawIni(sections);
|
|
5878
6906
|
}
|
|
5879
6907
|
|
|
@@ -6004,12 +7032,12 @@ function convertRuleset(content, type) {
|
|
|
6004
7032
|
}
|
|
6005
7033
|
return lines.join("\n");
|
|
6006
7034
|
}
|
|
6007
|
-
function transformRuleToCommon(input,
|
|
7035
|
+
function transformRuleToCommon(input, group2, noResolveOnly = false) {
|
|
6008
7036
|
const parts = input.split(",");
|
|
6009
7037
|
if (parts.length < 2) {
|
|
6010
|
-
return `${parts[0] ?? ""},${
|
|
7038
|
+
return `${parts[0] ?? ""},${group2}`;
|
|
6011
7039
|
}
|
|
6012
|
-
let line = `${parts[0]},${parts[1]},${
|
|
7040
|
+
let line = `${parts[0]},${parts[1]},${group2}`;
|
|
6013
7041
|
if (parts.length > 2 && (!noResolveOnly || parts[2] === "no-resolve")) {
|
|
6014
7042
|
line += `,${parts[2]}`;
|
|
6015
7043
|
}
|
|
@@ -6018,7 +7046,7 @@ function transformRuleToCommon(input, group, noResolveOnly = false) {
|
|
|
6018
7046
|
function startsWithAny(line, types) {
|
|
6019
7047
|
return types.some((type) => line.startsWith(type));
|
|
6020
7048
|
}
|
|
6021
|
-
function collectRuleLines(content,
|
|
7049
|
+
function collectRuleLines(content, group2, noResolveOnly) {
|
|
6022
7050
|
const converted = convertRuleset(content, "surge" /* Surge */);
|
|
6023
7051
|
const out = [];
|
|
6024
7052
|
for (const rawLine of converted.split(/\r?\n/)) {
|
|
@@ -6032,7 +7060,7 @@ function collectRuleLines(content, group, noResolveOnly) {
|
|
|
6032
7060
|
if (line === "") {
|
|
6033
7061
|
continue;
|
|
6034
7062
|
}
|
|
6035
|
-
out.push(transformRuleToCommon(line,
|
|
7063
|
+
out.push(transformRuleToCommon(line, group2, noResolveOnly));
|
|
6036
7064
|
}
|
|
6037
7065
|
return out;
|
|
6038
7066
|
}
|
|
@@ -6043,13 +7071,13 @@ function rulesetToClashRules(rulesets) {
|
|
|
6043
7071
|
if (content === "") {
|
|
6044
7072
|
continue;
|
|
6045
7073
|
}
|
|
6046
|
-
const
|
|
7074
|
+
const group2 = ruleset.ruleGroup;
|
|
6047
7075
|
if (content.startsWith("[]")) {
|
|
6048
7076
|
let line = content.slice(2);
|
|
6049
7077
|
if (line.startsWith("FINAL")) {
|
|
6050
7078
|
line = `MATCH${line.slice(5)}`;
|
|
6051
7079
|
}
|
|
6052
|
-
rules.push(transformRuleToCommon(line,
|
|
7080
|
+
rules.push(transformRuleToCommon(line, group2));
|
|
6053
7081
|
continue;
|
|
6054
7082
|
}
|
|
6055
7083
|
const converted = convertRuleset(content, ruleset.ruleType);
|
|
@@ -6064,7 +7092,7 @@ function rulesetToClashRules(rulesets) {
|
|
|
6064
7092
|
if (line.includes("//")) {
|
|
6065
7093
|
line = stripComment(line);
|
|
6066
7094
|
}
|
|
6067
|
-
rules.push(transformRuleToCommon(line,
|
|
7095
|
+
rules.push(transformRuleToCommon(line, group2));
|
|
6068
7096
|
}
|
|
6069
7097
|
}
|
|
6070
7098
|
return rules;
|
|
@@ -6106,21 +7134,21 @@ function rulesetToSurgeRules(rulesets, surgeVersion) {
|
|
|
6106
7134
|
if (ruleset.content === "") {
|
|
6107
7135
|
continue;
|
|
6108
7136
|
}
|
|
6109
|
-
const
|
|
7137
|
+
const group2 = ruleset.ruleGroup;
|
|
6110
7138
|
if (ruleset.content.startsWith("[]")) {
|
|
6111
7139
|
let line = ruleset.content.slice(2);
|
|
6112
7140
|
if (line === "MATCH") {
|
|
6113
7141
|
line = "FINAL";
|
|
6114
7142
|
}
|
|
6115
7143
|
if (surgeVersion === -1 || surgeVersion === -2) {
|
|
6116
|
-
line = transformRuleToCommon(line,
|
|
7144
|
+
line = transformRuleToCommon(line, group2, true);
|
|
6117
7145
|
} else if (!line.startsWith("AND") && !line.startsWith("OR") && !line.startsWith("NOT")) {
|
|
6118
|
-
line = transformRuleToCommon(line,
|
|
7146
|
+
line = transformRuleToCommon(line, group2);
|
|
6119
7147
|
}
|
|
6120
7148
|
lines.push(line.replace(/,,/g, ","));
|
|
6121
7149
|
continue;
|
|
6122
7150
|
}
|
|
6123
|
-
for (const rawLine of collectRuleLines(ruleset.content,
|
|
7151
|
+
for (const rawLine of collectRuleLines(ruleset.content, group2, noResolveOnly)) {
|
|
6124
7152
|
if (surgeVersion === -2 && rawLine.startsWith("IP-CIDR6")) {
|
|
6125
7153
|
continue;
|
|
6126
7154
|
}
|
|
@@ -6163,11 +7191,11 @@ function rulesetToSingBoxRules(rulesets) {
|
|
|
6163
7191
|
if (content === "") {
|
|
6164
7192
|
continue;
|
|
6165
7193
|
}
|
|
6166
|
-
const
|
|
7194
|
+
const group2 = ruleset.ruleGroup;
|
|
6167
7195
|
if (content.startsWith("[]")) {
|
|
6168
7196
|
const line = content.slice(2);
|
|
6169
7197
|
if (line.startsWith("FINAL") || line.startsWith("MATCH")) {
|
|
6170
|
-
final =
|
|
7198
|
+
final = group2;
|
|
6171
7199
|
continue;
|
|
6172
7200
|
}
|
|
6173
7201
|
const parts = line.split(",");
|
|
@@ -6179,7 +7207,7 @@ function rulesetToSingBoxRules(rulesets) {
|
|
|
6179
7207
|
if (type === "match" || type === "final") {
|
|
6180
7208
|
rules.push({ outbound: value });
|
|
6181
7209
|
} else {
|
|
6182
|
-
rules.push({ outbound:
|
|
7210
|
+
rules.push({ outbound: group2, [type]: value });
|
|
6183
7211
|
}
|
|
6184
7212
|
continue;
|
|
6185
7213
|
}
|
|
@@ -6210,7 +7238,7 @@ function rulesetToSingBoxRules(rulesets) {
|
|
|
6210
7238
|
if (Object.keys(rule).length === 0) {
|
|
6211
7239
|
continue;
|
|
6212
7240
|
}
|
|
6213
|
-
rule.outbound =
|
|
7241
|
+
rule.outbound = group2;
|
|
6214
7242
|
rules.push(rule);
|
|
6215
7243
|
}
|
|
6216
7244
|
return { final, rules };
|
|
@@ -6271,8 +7299,8 @@ function buildMellowEndpoint(x, remark) {
|
|
|
6271
7299
|
}
|
|
6272
7300
|
function buildMellowGroups(extraProxyGroup, nodelist, remarks) {
|
|
6273
7301
|
const lines = [];
|
|
6274
|
-
for (const
|
|
6275
|
-
switch (
|
|
7302
|
+
for (const group2 of extraProxyGroup) {
|
|
7303
|
+
switch (group2.type) {
|
|
6276
7304
|
case "select":
|
|
6277
7305
|
case "url-test":
|
|
6278
7306
|
case "fallback":
|
|
@@ -6282,7 +7310,7 @@ function buildMellowGroups(extraProxyGroup, nodelist, remarks) {
|
|
|
6282
7310
|
continue;
|
|
6283
7311
|
}
|
|
6284
7312
|
const filtered = [];
|
|
6285
|
-
for (const rule of
|
|
7313
|
+
for (const rule of group2.proxies) {
|
|
6286
7314
|
groupGenerate(rule, nodelist, filtered, false);
|
|
6287
7315
|
}
|
|
6288
7316
|
if (filtered.length === 0) {
|
|
@@ -6292,7 +7320,7 @@ function buildMellowGroups(extraProxyGroup, nodelist, remarks) {
|
|
|
6292
7320
|
filtered.push(...remarks);
|
|
6293
7321
|
}
|
|
6294
7322
|
}
|
|
6295
|
-
lines.push(`${
|
|
7323
|
+
lines.push(`${group2.name}, ${filtered.join(":")}, latency, interval=300, timeout=6`);
|
|
6296
7324
|
}
|
|
6297
7325
|
return lines;
|
|
6298
7326
|
}
|
|
@@ -6342,7 +7370,7 @@ function toMellow(nodes, extraProxyGroup, settings, options) {
|
|
|
6342
7370
|
function buildQuanNode(x, settings, remark, nodeList) {
|
|
6343
7371
|
const hostname = x.hostname;
|
|
6344
7372
|
const port = String(x.port);
|
|
6345
|
-
const
|
|
7373
|
+
const group2 = x.group;
|
|
6346
7374
|
let method = x.encryptMethod;
|
|
6347
7375
|
const scv = x.allowInsecure !== void 0 ? x.allowInsecure : settings.skipCertVerify;
|
|
6348
7376
|
let proxyStr;
|
|
@@ -6351,7 +7379,7 @@ function buildQuanNode(x, settings, remark, nodeList) {
|
|
|
6351
7379
|
if (method === "auto") {
|
|
6352
7380
|
method = "chacha20-ietf-poly1305";
|
|
6353
7381
|
}
|
|
6354
|
-
proxyStr = `${remark} = vmess, ${hostname}, ${port}, ${method}, "${x.userId}", group=${
|
|
7382
|
+
proxyStr = `${remark} = vmess, ${hostname}, ${port}, ${method}, "${x.userId}", group=${group2}`;
|
|
6355
7383
|
if (x.tlsSecure) {
|
|
6356
7384
|
proxyStr += `, over-tls=true, tls-host=${x.host}`;
|
|
6357
7385
|
if (scv !== void 0) {
|
|
@@ -6372,10 +7400,10 @@ function buildQuanNode(x, settings, remark, nodeList) {
|
|
|
6372
7400
|
case "ssr" /* ShadowsocksR */:
|
|
6373
7401
|
if (nodeList) {
|
|
6374
7402
|
proxyStr = `ssr://${urlSafeBase64Encode(
|
|
6375
|
-
`${hostname}:${port}:${x.protocol}:${method}:${x.obfs}:${urlSafeBase64Encode(x.password)}/?group=${urlSafeBase64Encode(
|
|
7403
|
+
`${hostname}:${port}:${x.protocol}:${method}:${x.obfs}:${urlSafeBase64Encode(x.password)}/?group=${urlSafeBase64Encode(group2)}&remarks=${urlSafeBase64Encode(remark)}&obfsparam=${urlSafeBase64Encode(x.obfsParam)}&protoparam=${urlSafeBase64Encode(x.protocolParam)}`
|
|
6376
7404
|
)}`;
|
|
6377
7405
|
} else {
|
|
6378
|
-
proxyStr = `${remark} = shadowsocksr, ${hostname}, ${port}, ${method}, "${x.password}", group=${
|
|
7406
|
+
proxyStr = `${remark} = shadowsocksr, ${hostname}, ${port}, ${method}, "${x.password}", group=${group2}, protocol=${x.protocol}, obfs=${x.obfs}`;
|
|
6379
7407
|
if (x.protocolParam !== "") {
|
|
6380
7408
|
proxyStr += `, protocol_param=${x.protocolParam}`;
|
|
6381
7409
|
}
|
|
@@ -6390,9 +7418,9 @@ function buildQuanNode(x, settings, remark, nodeList) {
|
|
|
6390
7418
|
if (x.plugin !== "" && x.pluginOption !== "") {
|
|
6391
7419
|
proxyStr += `/?plugin=${urlEncode(`${x.plugin};${x.pluginOption}`)}`;
|
|
6392
7420
|
}
|
|
6393
|
-
proxyStr += `&group=${urlSafeBase64Encode(
|
|
7421
|
+
proxyStr += `&group=${urlSafeBase64Encode(group2)}#${urlEncode(remark)}`;
|
|
6394
7422
|
} else {
|
|
6395
|
-
proxyStr = `${remark} = shadowsocks, ${hostname}, ${port}, ${method}, "${x.password}", group=${
|
|
7423
|
+
proxyStr = `${remark} = shadowsocks, ${hostname}, ${port}, ${method}, "${x.password}", group=${group2}`;
|
|
6396
7424
|
if (x.plugin === "obfs-local" && x.pluginOption !== "") {
|
|
6397
7425
|
proxyStr += `, ${x.pluginOption.replace(/;/g, ", ")}`;
|
|
6398
7426
|
}
|
|
@@ -6400,7 +7428,7 @@ function buildQuanNode(x, settings, remark, nodeList) {
|
|
|
6400
7428
|
break;
|
|
6401
7429
|
case "http" /* HTTP */:
|
|
6402
7430
|
case "https" /* HTTPS */:
|
|
6403
|
-
proxyStr = `${remark} = http, upstream-proxy-address=${hostname}, upstream-proxy-port=${port}, group=${
|
|
7431
|
+
proxyStr = `${remark} = http, upstream-proxy-address=${hostname}, upstream-proxy-port=${port}, group=${group2}`;
|
|
6404
7432
|
if (x.username !== "" && x.password !== "") {
|
|
6405
7433
|
proxyStr += `, upstream-proxy-auth=true, upstream-proxy-username=${x.username}, upstream-proxy-password=${x.password}`;
|
|
6406
7434
|
} else {
|
|
@@ -6420,7 +7448,7 @@ function buildQuanNode(x, settings, remark, nodeList) {
|
|
|
6420
7448
|
}
|
|
6421
7449
|
break;
|
|
6422
7450
|
case "socks5" /* SOCKS5 */:
|
|
6423
|
-
proxyStr = `${remark} = socks, upstream-proxy-address=${hostname}, upstream-proxy-port=${port}, group=${
|
|
7451
|
+
proxyStr = `${remark} = socks, upstream-proxy-address=${hostname}, upstream-proxy-port=${port}, group=${group2}`;
|
|
6424
7452
|
if (x.username !== "" && x.password !== "") {
|
|
6425
7453
|
proxyStr += `, upstream-proxy-auth=true, upstream-proxy-username=${x.username}, upstream-proxy-password=${x.password}`;
|
|
6426
7454
|
} else {
|
|
@@ -6446,9 +7474,9 @@ function buildQuanNode(x, settings, remark, nodeList) {
|
|
|
6446
7474
|
}
|
|
6447
7475
|
function buildQuanGroups(extraProxyGroup, nodelist) {
|
|
6448
7476
|
const lines = [];
|
|
6449
|
-
for (const
|
|
7477
|
+
for (const group2 of extraProxyGroup) {
|
|
6450
7478
|
let type;
|
|
6451
|
-
switch (
|
|
7479
|
+
switch (group2.type) {
|
|
6452
7480
|
case "select":
|
|
6453
7481
|
case "fallback":
|
|
6454
7482
|
type = "static";
|
|
@@ -6460,10 +7488,10 @@ function buildQuanGroups(extraProxyGroup, nodelist) {
|
|
|
6460
7488
|
type = "balance, round-robin";
|
|
6461
7489
|
break;
|
|
6462
7490
|
case "ssid": {
|
|
6463
|
-
let singlegroup2 = `${
|
|
7491
|
+
let singlegroup2 = `${group2.name} : wifi = ${group2.proxies[0] ?? ""}`;
|
|
6464
7492
|
let content = "";
|
|
6465
7493
|
let celluar = "";
|
|
6466
|
-
for (const proxy of
|
|
7494
|
+
for (const proxy of group2.proxies.slice(1)) {
|
|
6467
7495
|
const m = /^(.*?),?celluar\s?=\s?(.*?)(,.*)$/.exec(proxy);
|
|
6468
7496
|
if (!m) {
|
|
6469
7497
|
content += `${proxy}
|
|
@@ -6486,7 +7514,7 @@ ${content.trim().replace(/^,|,$/g, "").replace(/,/g, "\n")}`;
|
|
|
6486
7514
|
continue;
|
|
6487
7515
|
}
|
|
6488
7516
|
const filtered = [];
|
|
6489
|
-
for (const rule of
|
|
7517
|
+
for (const rule of group2.proxies) {
|
|
6490
7518
|
groupGenerate(rule, nodelist, filtered, true);
|
|
6491
7519
|
}
|
|
6492
7520
|
if (filtered.length === 0) {
|
|
@@ -6496,7 +7524,7 @@ ${content.trim().replace(/^,|,$/g, "").replace(/,/g, "\n")}`;
|
|
|
6496
7524
|
type = "static";
|
|
6497
7525
|
}
|
|
6498
7526
|
const proxies = filtered.join("\n");
|
|
6499
|
-
let singlegroup = `${
|
|
7527
|
+
let singlegroup = `${group2.name} : ${type}`;
|
|
6500
7528
|
if (type === "static") {
|
|
6501
7529
|
singlegroup += `, ${filtered[0]}`;
|
|
6502
7530
|
}
|
|
@@ -6534,6 +7562,9 @@ function toQuan(nodes, extraProxyGroup, settings, options) {
|
|
|
6534
7562
|
if (groupLines.length > 0) {
|
|
6535
7563
|
setRawSection(sections, "POLICY", groupLines);
|
|
6536
7564
|
}
|
|
7565
|
+
if (options.rules && options.rules.lines.length > 0) {
|
|
7566
|
+
setRawSection(sections, options.rules.section, options.rules.lines);
|
|
7567
|
+
}
|
|
6537
7568
|
return renderRawIni(sections);
|
|
6538
7569
|
}
|
|
6539
7570
|
|
|
@@ -6652,12 +7683,32 @@ function buildQuanxNode(x, settings, remark) {
|
|
|
6652
7683
|
}
|
|
6653
7684
|
}
|
|
6654
7685
|
break;
|
|
6655
|
-
case "
|
|
6656
|
-
|
|
6657
|
-
|
|
6658
|
-
|
|
7686
|
+
case "vless" /* VLESS */: {
|
|
7687
|
+
const vmethod = method === "" ? "none" : method;
|
|
7688
|
+
proxyStr = `vless = ${hostname}:${port}, method=${vmethod}, password=${x.userId}`;
|
|
7689
|
+
if (tlsSecure && tls13 !== void 0) {
|
|
7690
|
+
proxyStr += `, tls13=${triStr2(tls13)}`;
|
|
7691
|
+
}
|
|
7692
|
+
const obfsHost = host !== "" ? host : x.serverName !== "" ? x.serverName : x.sni;
|
|
7693
|
+
if (x.transferProtocol === "ws") {
|
|
7694
|
+
proxyStr += tlsSecure ? ", obfs=wss" : ", obfs=ws";
|
|
7695
|
+
proxyStr += `, obfs-host=${obfsHost}, obfs-uri=${path}`;
|
|
7696
|
+
} else if (tlsSecure) {
|
|
7697
|
+
proxyStr += `, obfs=over-tls, obfs-host=${obfsHost}`;
|
|
7698
|
+
}
|
|
7699
|
+
if (x.publicKey !== "") {
|
|
7700
|
+
proxyStr += `, reality-base64-pubkey=${x.publicKey}`;
|
|
7701
|
+
}
|
|
7702
|
+
if (x.shortId !== "") {
|
|
7703
|
+
proxyStr += `, reality-hex-shortid=${x.shortId}`;
|
|
7704
|
+
}
|
|
7705
|
+
if (x.flow !== "") {
|
|
7706
|
+
proxyStr += `, vless-flow=${x.flow}`;
|
|
6659
7707
|
}
|
|
6660
7708
|
break;
|
|
7709
|
+
}
|
|
7710
|
+
// Quantumult X has no AnyTLS/Hysteria2/TUIC mapping — drop them instead
|
|
7711
|
+
// of emitting non-standard lines.
|
|
6661
7712
|
default:
|
|
6662
7713
|
return void 0;
|
|
6663
7714
|
}
|
|
@@ -6675,10 +7726,10 @@ function buildQuanxNode(x, settings, remark) {
|
|
|
6675
7726
|
}
|
|
6676
7727
|
function buildQuanxGroups(extraProxyGroup, nodelist) {
|
|
6677
7728
|
const lines = [];
|
|
6678
|
-
for (const
|
|
7729
|
+
for (const group2 of extraProxyGroup) {
|
|
6679
7730
|
let type;
|
|
6680
7731
|
const filtered = [];
|
|
6681
|
-
switch (
|
|
7732
|
+
switch (group2.type) {
|
|
6682
7733
|
case "select":
|
|
6683
7734
|
type = "static";
|
|
6684
7735
|
break;
|
|
@@ -6693,15 +7744,15 @@ function buildQuanxGroups(extraProxyGroup, nodelist) {
|
|
|
6693
7744
|
break;
|
|
6694
7745
|
case "ssid":
|
|
6695
7746
|
type = "ssid";
|
|
6696
|
-
for (const proxy of
|
|
7747
|
+
for (const proxy of group2.proxies) {
|
|
6697
7748
|
filtered.push(proxy.replace(/=/g, ":"));
|
|
6698
7749
|
}
|
|
6699
7750
|
break;
|
|
6700
7751
|
default:
|
|
6701
7752
|
continue;
|
|
6702
7753
|
}
|
|
6703
|
-
if (
|
|
6704
|
-
for (const rule of
|
|
7754
|
+
if (group2.type !== "ssid") {
|
|
7755
|
+
for (const rule of group2.proxies) {
|
|
6705
7756
|
groupGenerate(rule, nodelist, filtered, true);
|
|
6706
7757
|
}
|
|
6707
7758
|
if (filtered.length === 0) {
|
|
@@ -6712,11 +7763,11 @@ function buildQuanxGroups(extraProxyGroup, nodelist) {
|
|
|
6712
7763
|
}
|
|
6713
7764
|
}
|
|
6714
7765
|
const proxies = filtered.join(", ");
|
|
6715
|
-
let line = `${type}=${
|
|
6716
|
-
if (
|
|
6717
|
-
line += `, check-interval=${
|
|
6718
|
-
if (
|
|
6719
|
-
line += `, tolerance=${
|
|
7766
|
+
let line = `${type}=${group2.name}, ${proxies}`;
|
|
7767
|
+
if (group2.type !== "select" && group2.type !== "ssid") {
|
|
7768
|
+
line += `, check-interval=${group2.interval}`;
|
|
7769
|
+
if (group2.tolerance > 0) {
|
|
7770
|
+
line += `, tolerance=${group2.tolerance}`;
|
|
6720
7771
|
}
|
|
6721
7772
|
}
|
|
6722
7773
|
lines.push(line);
|
|
@@ -6750,6 +7801,9 @@ function toQuanX(nodes, extraProxyGroup, settings, options) {
|
|
|
6750
7801
|
if (groupLines.length > 0) {
|
|
6751
7802
|
setRawSection(sections, "policy", groupLines);
|
|
6752
7803
|
}
|
|
7804
|
+
if (options.rules && options.rules.lines.length > 0) {
|
|
7805
|
+
setRawSection(sections, options.rules.section, options.rules.lines);
|
|
7806
|
+
}
|
|
6753
7807
|
return renderRawIni(sections);
|
|
6754
7808
|
}
|
|
6755
7809
|
|
|
@@ -6845,18 +7899,9 @@ function buildOutbound(x, settings, remark) {
|
|
|
6845
7899
|
proxy = out;
|
|
6846
7900
|
break;
|
|
6847
7901
|
}
|
|
7902
|
+
// sing-box has no SSR support — drop such nodes.
|
|
6848
7903
|
case "ssr" /* ShadowsocksR */:
|
|
6849
|
-
|
|
6850
|
-
...common,
|
|
6851
|
-
method: x.encryptMethod,
|
|
6852
|
-
obfs: x.obfs,
|
|
6853
|
-
obfs_param: x.obfsParam,
|
|
6854
|
-
password: x.password,
|
|
6855
|
-
protocol: x.protocol,
|
|
6856
|
-
protocol_param: x.protocolParam,
|
|
6857
|
-
type: "shadowsocksr"
|
|
6858
|
-
};
|
|
6859
|
-
break;
|
|
7904
|
+
return void 0;
|
|
6860
7905
|
case "vmess" /* VMess */: {
|
|
6861
7906
|
const out = {
|
|
6862
7907
|
...common,
|
|
@@ -6872,6 +7917,18 @@ function buildOutbound(x, settings, remark) {
|
|
|
6872
7917
|
proxy = out;
|
|
6873
7918
|
break;
|
|
6874
7919
|
}
|
|
7920
|
+
case "vless" /* VLESS */: {
|
|
7921
|
+
const out = { ...common, type: "vless", uuid: x.userId };
|
|
7922
|
+
if (x.flow !== "") {
|
|
7923
|
+
out.flow = x.flow;
|
|
7924
|
+
}
|
|
7925
|
+
const transport = buildTransport(x);
|
|
7926
|
+
if (transport) {
|
|
7927
|
+
out.transport = transport;
|
|
7928
|
+
}
|
|
7929
|
+
proxy = out;
|
|
7930
|
+
break;
|
|
7931
|
+
}
|
|
6875
7932
|
case "trojan" /* Trojan */: {
|
|
6876
7933
|
const out = { ...common, password: x.password, type: "trojan" };
|
|
6877
7934
|
const transport = buildTransport(x);
|
|
@@ -6881,6 +7938,20 @@ function buildOutbound(x, settings, remark) {
|
|
|
6881
7938
|
proxy = out;
|
|
6882
7939
|
break;
|
|
6883
7940
|
}
|
|
7941
|
+
case "tuic" /* TUIC */: {
|
|
7942
|
+
const out = {
|
|
7943
|
+
...common,
|
|
7944
|
+
password: x.password,
|
|
7945
|
+
type: "tuic",
|
|
7946
|
+
udp_relay_mode: "native",
|
|
7947
|
+
uuid: x.userId
|
|
7948
|
+
};
|
|
7949
|
+
if (x.congestionControl !== "") {
|
|
7950
|
+
out.congestion_control = x.congestionControl;
|
|
7951
|
+
}
|
|
7952
|
+
proxy = out;
|
|
7953
|
+
break;
|
|
7954
|
+
}
|
|
6884
7955
|
case "wireguard" /* WireGuard */: {
|
|
6885
7956
|
const addresses = [x.selfIp];
|
|
6886
7957
|
if (x.selfIpv6 !== "") {
|
|
@@ -6993,6 +8064,17 @@ function buildOutbound(x, settings, remark) {
|
|
|
6993
8064
|
}
|
|
6994
8065
|
const tls = buildTls(x, scv);
|
|
6995
8066
|
if (tls) {
|
|
8067
|
+
if (x.type === "vless" /* VLESS */ && (x.publicKey !== "" || x.shortId !== "")) {
|
|
8068
|
+
const tlsRec = tls;
|
|
8069
|
+
if (x.fingerprint !== "") {
|
|
8070
|
+
tlsRec.utls = { enabled: true, fingerprint: x.fingerprint };
|
|
8071
|
+
}
|
|
8072
|
+
tlsRec.reality = {
|
|
8073
|
+
enabled: true,
|
|
8074
|
+
public_key: x.publicKey,
|
|
8075
|
+
short_id: x.shortId
|
|
8076
|
+
};
|
|
8077
|
+
}
|
|
6996
8078
|
proxy.tls = tls;
|
|
6997
8079
|
}
|
|
6998
8080
|
if (udp !== void 0 && !udp) {
|
|
@@ -7037,9 +8119,9 @@ function toSingBox(nodes, extraProxyGroup, settings, options) {
|
|
|
7037
8119
|
remarksList.push(remark);
|
|
7038
8120
|
}
|
|
7039
8121
|
if (!options.nodeList) {
|
|
7040
|
-
for (const
|
|
8122
|
+
for (const group2 of extraProxyGroup) {
|
|
7041
8123
|
let type;
|
|
7042
|
-
switch (
|
|
8124
|
+
switch (group2.type) {
|
|
7043
8125
|
case "select":
|
|
7044
8126
|
type = "selector";
|
|
7045
8127
|
break;
|
|
@@ -7052,18 +8134,18 @@ function toSingBox(nodes, extraProxyGroup, settings, options) {
|
|
|
7052
8134
|
continue;
|
|
7053
8135
|
}
|
|
7054
8136
|
const filtered = [];
|
|
7055
|
-
for (const rule of
|
|
8137
|
+
for (const rule of group2.proxies) {
|
|
7056
8138
|
groupGenerate(rule, nodelist, filtered, true);
|
|
7057
8139
|
}
|
|
7058
8140
|
if (filtered.length === 0) {
|
|
7059
8141
|
filtered.push("DIRECT");
|
|
7060
8142
|
}
|
|
7061
|
-
const entry = { outbounds: filtered, tag:
|
|
7062
|
-
if (
|
|
7063
|
-
entry.url =
|
|
7064
|
-
entry.interval = formatSingBoxInterval(
|
|
7065
|
-
if (
|
|
7066
|
-
entry.tolerance =
|
|
8143
|
+
const entry = { outbounds: filtered, tag: group2.name, type };
|
|
8144
|
+
if (group2.type === "url-test") {
|
|
8145
|
+
entry.url = group2.url;
|
|
8146
|
+
entry.interval = formatSingBoxInterval(group2.interval);
|
|
8147
|
+
if (group2.tolerance > 0) {
|
|
8148
|
+
entry.tolerance = group2.tolerance;
|
|
7067
8149
|
}
|
|
7068
8150
|
}
|
|
7069
8151
|
outbounds.push(entry);
|
|
@@ -7083,12 +8165,30 @@ function toSingBox(nodes, extraProxyGroup, settings, options) {
|
|
|
7083
8165
|
return JSON.stringify(doc, null, 2);
|
|
7084
8166
|
}
|
|
7085
8167
|
|
|
8168
|
+
// src/generator/surfboard.ts
|
|
8169
|
+
function toSurfboard(nodes, extraProxyGroup, settings, options) {
|
|
8170
|
+
const filtered = nodes.filter(
|
|
8171
|
+
(n) => n.type !== "hysteria2" /* Hysteria2 */ && n.type !== "anytls" /* AnyTLS */
|
|
8172
|
+
);
|
|
8173
|
+
return toSurge(filtered, extraProxyGroup, settings, {
|
|
8174
|
+
baseConf: options.baseConf,
|
|
8175
|
+
nodeList: options.nodeList,
|
|
8176
|
+
rules: options.rules,
|
|
8177
|
+
version: 5
|
|
8178
|
+
});
|
|
8179
|
+
}
|
|
8180
|
+
|
|
7086
8181
|
// src/engine.ts
|
|
7087
8182
|
var V2RAY_TYPE_MASK = 1 | 2 | 4 | 8;
|
|
7088
8183
|
function runPreprocess(nodes, settings) {
|
|
7089
8184
|
preprocessNodes(nodes, {
|
|
7090
8185
|
addEmoji: settings.addEmoji,
|
|
8186
|
+
autoCountry: settings.autoCountry,
|
|
8187
|
+
countryLocale: settings.countryLocale,
|
|
8188
|
+
countryResolver: settings.countryResolver,
|
|
7091
8189
|
emojiArray: settings.emojiArray,
|
|
8190
|
+
nameRegexArray: settings.nameRegexArray,
|
|
8191
|
+
nameRemove: settings.nameRemove,
|
|
7092
8192
|
removeEmoji: settings.removeEmoji,
|
|
7093
8193
|
renameArray: settings.renameArray,
|
|
7094
8194
|
sortFlag: settings.sortFlag
|
|
@@ -7100,56 +8200,62 @@ function runPreprocess(nodes, settings) {
|
|
|
7100
8200
|
function generate(nodes, options) {
|
|
7101
8201
|
const settings = { ...createExtraSettings(), ...options.settings };
|
|
7102
8202
|
runPreprocess(nodes, settings);
|
|
8203
|
+
const groups = resolveGroups(options);
|
|
8204
|
+
const rulesets = resolveRulesets(options, settings);
|
|
7103
8205
|
switch (options.target) {
|
|
7104
8206
|
case "clash" /* Clash */:
|
|
7105
8207
|
case "clashr" /* ClashR */: {
|
|
7106
|
-
const { doc } = buildClash(
|
|
7107
|
-
|
|
7108
|
-
options.groups ?? [],
|
|
7109
|
-
settings,
|
|
7110
|
-
options.target === "clashr" /* ClashR */
|
|
7111
|
-
);
|
|
7112
|
-
attachClashRules(doc, settings, options.rulesets);
|
|
8208
|
+
const { doc } = buildClash(nodes, groups, settings, options.target === "clashr" /* ClashR */);
|
|
8209
|
+
attachClashRules(doc, settings, rulesets);
|
|
7113
8210
|
return stringifyClash(doc);
|
|
7114
8211
|
}
|
|
7115
8212
|
case "surge" /* Surge */: {
|
|
7116
|
-
const surgeVersion = options.surgeVersion ??
|
|
7117
|
-
const rules =
|
|
7118
|
-
return toSurge(nodes,
|
|
8213
|
+
const surgeVersion = options.surgeVersion ?? 5;
|
|
8214
|
+
const rules = rulesets ? rulesetToSurgeRules(rulesets, surgeVersion) : void 0;
|
|
8215
|
+
return toSurge(nodes, groups, settings, {
|
|
7119
8216
|
baseConf: options.baseConf ?? "",
|
|
7120
8217
|
nodeList: settings.nodeList,
|
|
7121
8218
|
rules,
|
|
7122
8219
|
version: surgeVersion
|
|
7123
8220
|
});
|
|
7124
8221
|
}
|
|
7125
|
-
case "quanx" /* QuantumultX */:
|
|
7126
|
-
|
|
8222
|
+
case "quanx" /* QuantumultX */: {
|
|
8223
|
+
const rules = rulesets ? rulesetToSurgeRules(rulesets, -1) : void 0;
|
|
8224
|
+
return toQuanX(nodes, groups, settings, {
|
|
7127
8225
|
baseConf: options.baseConf ?? "",
|
|
7128
|
-
nodeList: settings.nodeList
|
|
8226
|
+
nodeList: settings.nodeList,
|
|
8227
|
+
rules
|
|
7129
8228
|
});
|
|
7130
|
-
|
|
7131
|
-
|
|
8229
|
+
}
|
|
8230
|
+
case "quan" /* Quantumult */: {
|
|
8231
|
+
const rules = rulesets ? rulesetToSurgeRules(rulesets, -2) : void 0;
|
|
8232
|
+
return toQuan(nodes, groups, settings, {
|
|
7132
8233
|
baseConf: options.baseConf ?? "",
|
|
7133
|
-
nodeList: settings.nodeList
|
|
8234
|
+
nodeList: settings.nodeList,
|
|
8235
|
+
rules
|
|
7134
8236
|
});
|
|
7135
|
-
|
|
7136
|
-
|
|
8237
|
+
}
|
|
8238
|
+
case "loon" /* Loon */: {
|
|
8239
|
+
const rules = rulesets ? rulesetToSurgeRules(rulesets, -4) : void 0;
|
|
8240
|
+
return toLoon(nodes, groups, settings, {
|
|
7137
8241
|
baseConf: options.baseConf ?? "",
|
|
7138
|
-
nodeList: settings.nodeList
|
|
8242
|
+
nodeList: settings.nodeList,
|
|
8243
|
+
rules
|
|
7139
8244
|
});
|
|
8245
|
+
}
|
|
7140
8246
|
case "singbox" /* SingBox */:
|
|
7141
|
-
return toSingBox(nodes,
|
|
8247
|
+
return toSingBox(nodes, groups, settings, {
|
|
7142
8248
|
baseConf: options.baseConf ?? "",
|
|
7143
8249
|
nodeList: settings.nodeList,
|
|
7144
8250
|
overwriteOriginalRules: settings.overwriteOriginalRules,
|
|
7145
|
-
rulesets
|
|
8251
|
+
rulesets
|
|
7146
8252
|
});
|
|
7147
8253
|
case "mellow" /* Mellow */:
|
|
7148
|
-
return toMellow(nodes,
|
|
8254
|
+
return toMellow(nodes, groups, settings, {
|
|
7149
8255
|
baseConf: options.baseConf ?? "",
|
|
7150
8256
|
nodeList: settings.nodeList,
|
|
7151
8257
|
overwriteOriginalRules: settings.overwriteOriginalRules,
|
|
7152
|
-
rulesets
|
|
8258
|
+
rulesets
|
|
7153
8259
|
});
|
|
7154
8260
|
case "v2ray" /* V2Ray */:
|
|
7155
8261
|
return proxyToSingle(nodes, 4, settings);
|
|
@@ -7163,6 +8269,16 @@ function generate(nodes, options) {
|
|
|
7163
8269
|
return proxyToSingle(nodes, 2, settings);
|
|
7164
8270
|
case "ssd" /* SSD */:
|
|
7165
8271
|
return proxyToSsd(nodes, "", "");
|
|
8272
|
+
case "sssub" /* SSSub */:
|
|
8273
|
+
return proxyToSsSub(nodes, options.baseConf ?? "");
|
|
8274
|
+
case "surfboard" /* Surfboard */: {
|
|
8275
|
+
const rules = rulesets ? rulesetToSurgeRules(rulesets, options.surgeVersion ?? 5) : void 0;
|
|
8276
|
+
return toSurfboard(nodes, groups, settings, {
|
|
8277
|
+
baseConf: options.baseConf ?? "",
|
|
8278
|
+
nodeList: settings.nodeList,
|
|
8279
|
+
rules
|
|
8280
|
+
});
|
|
8281
|
+
}
|
|
7166
8282
|
case "nodelist" /* NodeList */: {
|
|
7167
8283
|
settings.nodeList = true;
|
|
7168
8284
|
return proxyToSingle(nodes, V2RAY_TYPE_MASK, settings);
|
|
@@ -7174,7 +8290,28 @@ function generate(nodes, options) {
|
|
|
7174
8290
|
function toSip008(nodes, baseConf = "") {
|
|
7175
8291
|
return proxyToSsSub(nodes, baseConf);
|
|
7176
8292
|
}
|
|
8293
|
+
function resolveGroups(options) {
|
|
8294
|
+
if (options.includeRules !== false && (!options.groups || options.groups.length === 0)) {
|
|
8295
|
+
return getDefaultProxyGroups();
|
|
8296
|
+
}
|
|
8297
|
+
return options.groups ?? [];
|
|
8298
|
+
}
|
|
8299
|
+
function resolveRulesets(options, settings) {
|
|
8300
|
+
if (options.includeRules === false) {
|
|
8301
|
+
return void 0;
|
|
8302
|
+
}
|
|
8303
|
+
if (!settings.enableRuleGenerator || settings.nodeList) {
|
|
8304
|
+
return void 0;
|
|
8305
|
+
}
|
|
8306
|
+
if (options.rulesets && options.rulesets.length > 0) {
|
|
8307
|
+
return options.rulesets;
|
|
8308
|
+
}
|
|
8309
|
+
return getDefaultRulesets();
|
|
8310
|
+
}
|
|
7177
8311
|
function attachClashRules(doc, settings, rulesets) {
|
|
8312
|
+
if (!settings.enableRuleGenerator || settings.nodeList) {
|
|
8313
|
+
return;
|
|
8314
|
+
}
|
|
7178
8315
|
if (!rulesets || rulesets.length === 0) {
|
|
7179
8316
|
return;
|
|
7180
8317
|
}
|
|
@@ -7205,6 +8342,7 @@ export {
|
|
|
7205
8342
|
SURGE2_RULE_TYPES,
|
|
7206
8343
|
SURGE_RULE_TYPES,
|
|
7207
8344
|
TargetFormat,
|
|
8345
|
+
addCountryPrefix,
|
|
7208
8346
|
addEmoji,
|
|
7209
8347
|
anyTlsConstruct,
|
|
7210
8348
|
applyMatcher,
|
|
@@ -7213,12 +8351,14 @@ export {
|
|
|
7213
8351
|
buildClash,
|
|
7214
8352
|
checkIgnore,
|
|
7215
8353
|
convertRuleset,
|
|
8354
|
+
convertUserinfo,
|
|
7216
8355
|
countOccurrences,
|
|
7217
8356
|
createExtraSettings,
|
|
7218
8357
|
createProxy,
|
|
7219
8358
|
createProxyGroupConfig,
|
|
7220
8359
|
createRequestSettings,
|
|
7221
8360
|
createRulesetConfig,
|
|
8361
|
+
createSelectGroup,
|
|
7222
8362
|
dedupeNodes,
|
|
7223
8363
|
explode,
|
|
7224
8364
|
explodeAnyTls,
|
|
@@ -7251,25 +8391,39 @@ export {
|
|
|
7251
8391
|
findSection,
|
|
7252
8392
|
fnv1a64,
|
|
7253
8393
|
fnv1a64Hex,
|
|
8394
|
+
formatCountryRemark,
|
|
7254
8395
|
formatSingBoxInterval,
|
|
8396
|
+
formatSubscriptionUserinfo,
|
|
7255
8397
|
generate,
|
|
7256
8398
|
generatePeer,
|
|
8399
|
+
getAllUrlArgs,
|
|
8400
|
+
getDefaultProxyGroups,
|
|
8401
|
+
getDefaultRulesetConfigs,
|
|
8402
|
+
getDefaultRulesets,
|
|
7257
8403
|
getSectionItems,
|
|
7258
8404
|
getUrlArg,
|
|
7259
8405
|
groupGenerate,
|
|
8406
|
+
hasRegionName,
|
|
7260
8407
|
hasTemplatePlaceholders,
|
|
7261
8408
|
httpConstruct,
|
|
7262
8409
|
hysteria2Construct,
|
|
7263
8410
|
hysteriaConstruct,
|
|
8411
|
+
inferUserinfoProviderFromUrl,
|
|
7264
8412
|
isBlank,
|
|
7265
8413
|
isFlattenableSsr,
|
|
7266
8414
|
isIp,
|
|
7267
8415
|
isIpv4,
|
|
7268
8416
|
isIpv6,
|
|
7269
8417
|
isLink,
|
|
8418
|
+
isRegionCode,
|
|
7270
8419
|
isSsCipher,
|
|
7271
8420
|
matchRange,
|
|
8421
|
+
nextMonthlyResetTimestamp,
|
|
8422
|
+
nodeNameRegex,
|
|
8423
|
+
nodeNameRemove,
|
|
7272
8424
|
nodeRename,
|
|
8425
|
+
normalizeQueryKey,
|
|
8426
|
+
normalizeUserinfoProvider,
|
|
7273
8427
|
pad2,
|
|
7274
8428
|
parseClashText,
|
|
7275
8429
|
parseConfContent,
|
|
@@ -7277,6 +8431,7 @@ export {
|
|
|
7277
8431
|
parseExternalConfig,
|
|
7278
8432
|
parseGroupTimes,
|
|
7279
8433
|
parseIni,
|
|
8434
|
+
parseJmsUserinfo,
|
|
7280
8435
|
parseLink,
|
|
7281
8436
|
parsePeers,
|
|
7282
8437
|
parseProxyGroupType,
|
|
@@ -7285,6 +8440,7 @@ export {
|
|
|
7285
8440
|
parseRequestSettings,
|
|
7286
8441
|
parseRulesetConfig,
|
|
7287
8442
|
parseSubscription,
|
|
8443
|
+
parseSubscriptionUserinfo,
|
|
7288
8444
|
parseTriBool,
|
|
7289
8445
|
preprocessNodes,
|
|
7290
8446
|
processRemark,
|
|
@@ -7292,12 +8448,16 @@ export {
|
|
|
7292
8448
|
proxyToSsSub,
|
|
7293
8449
|
proxyToSsd,
|
|
7294
8450
|
proxyTypeName,
|
|
8451
|
+
queryBoolFlag,
|
|
7295
8452
|
regMatch,
|
|
7296
8453
|
regReplace,
|
|
8454
|
+
regionDisplayName,
|
|
8455
|
+
regionFlag,
|
|
7297
8456
|
removeEmoji,
|
|
7298
8457
|
renderRawIni,
|
|
7299
8458
|
renderTemplate,
|
|
7300
8459
|
replaceAllDistinct,
|
|
8460
|
+
resolveNewFieldName,
|
|
7301
8461
|
rulesetToClashRules,
|
|
7302
8462
|
rulesetToSingBoxRules,
|
|
7303
8463
|
rulesetToSurgeRules,
|
|
@@ -7325,6 +8485,7 @@ export {
|
|
|
7325
8485
|
toQuanX,
|
|
7326
8486
|
toSingBox,
|
|
7327
8487
|
toSip008,
|
|
8488
|
+
toSurfboard,
|
|
7328
8489
|
toSurge,
|
|
7329
8490
|
transformRuleToCommon,
|
|
7330
8491
|
triBoolOr,
|