@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.cjs
CHANGED
|
@@ -33,6 +33,7 @@ __export(index_exports, {
|
|
|
33
33
|
SURGE2_RULE_TYPES: () => SURGE2_RULE_TYPES,
|
|
34
34
|
SURGE_RULE_TYPES: () => SURGE_RULE_TYPES,
|
|
35
35
|
TargetFormat: () => TargetFormat,
|
|
36
|
+
addCountryPrefix: () => addCountryPrefix,
|
|
36
37
|
addEmoji: () => addEmoji,
|
|
37
38
|
anyTlsConstruct: () => anyTlsConstruct,
|
|
38
39
|
applyMatcher: () => applyMatcher,
|
|
@@ -41,12 +42,14 @@ __export(index_exports, {
|
|
|
41
42
|
buildClash: () => buildClash,
|
|
42
43
|
checkIgnore: () => checkIgnore,
|
|
43
44
|
convertRuleset: () => convertRuleset,
|
|
45
|
+
convertUserinfo: () => convertUserinfo,
|
|
44
46
|
countOccurrences: () => countOccurrences,
|
|
45
47
|
createExtraSettings: () => createExtraSettings,
|
|
46
48
|
createProxy: () => createProxy,
|
|
47
49
|
createProxyGroupConfig: () => createProxyGroupConfig,
|
|
48
50
|
createRequestSettings: () => createRequestSettings,
|
|
49
51
|
createRulesetConfig: () => createRulesetConfig,
|
|
52
|
+
createSelectGroup: () => createSelectGroup,
|
|
50
53
|
dedupeNodes: () => dedupeNodes,
|
|
51
54
|
explode: () => explode,
|
|
52
55
|
explodeAnyTls: () => explodeAnyTls,
|
|
@@ -79,25 +82,39 @@ __export(index_exports, {
|
|
|
79
82
|
findSection: () => findSection,
|
|
80
83
|
fnv1a64: () => fnv1a64,
|
|
81
84
|
fnv1a64Hex: () => fnv1a64Hex,
|
|
85
|
+
formatCountryRemark: () => formatCountryRemark,
|
|
82
86
|
formatSingBoxInterval: () => formatSingBoxInterval,
|
|
87
|
+
formatSubscriptionUserinfo: () => formatSubscriptionUserinfo,
|
|
83
88
|
generate: () => generate,
|
|
84
89
|
generatePeer: () => generatePeer,
|
|
90
|
+
getAllUrlArgs: () => getAllUrlArgs,
|
|
91
|
+
getDefaultProxyGroups: () => getDefaultProxyGroups,
|
|
92
|
+
getDefaultRulesetConfigs: () => getDefaultRulesetConfigs,
|
|
93
|
+
getDefaultRulesets: () => getDefaultRulesets,
|
|
85
94
|
getSectionItems: () => getSectionItems,
|
|
86
95
|
getUrlArg: () => getUrlArg,
|
|
87
96
|
groupGenerate: () => groupGenerate,
|
|
97
|
+
hasRegionName: () => hasRegionName,
|
|
88
98
|
hasTemplatePlaceholders: () => hasTemplatePlaceholders,
|
|
89
99
|
httpConstruct: () => httpConstruct,
|
|
90
100
|
hysteria2Construct: () => hysteria2Construct,
|
|
91
101
|
hysteriaConstruct: () => hysteriaConstruct,
|
|
102
|
+
inferUserinfoProviderFromUrl: () => inferUserinfoProviderFromUrl,
|
|
92
103
|
isBlank: () => isBlank,
|
|
93
104
|
isFlattenableSsr: () => isFlattenableSsr,
|
|
94
105
|
isIp: () => isIp,
|
|
95
106
|
isIpv4: () => isIpv4,
|
|
96
107
|
isIpv6: () => isIpv6,
|
|
97
108
|
isLink: () => isLink,
|
|
109
|
+
isRegionCode: () => isRegionCode,
|
|
98
110
|
isSsCipher: () => isSsCipher,
|
|
99
111
|
matchRange: () => matchRange,
|
|
112
|
+
nextMonthlyResetTimestamp: () => nextMonthlyResetTimestamp,
|
|
113
|
+
nodeNameRegex: () => nodeNameRegex,
|
|
114
|
+
nodeNameRemove: () => nodeNameRemove,
|
|
100
115
|
nodeRename: () => nodeRename,
|
|
116
|
+
normalizeQueryKey: () => normalizeQueryKey,
|
|
117
|
+
normalizeUserinfoProvider: () => normalizeUserinfoProvider,
|
|
101
118
|
pad2: () => pad2,
|
|
102
119
|
parseClashText: () => parseClashText,
|
|
103
120
|
parseConfContent: () => parseConfContent,
|
|
@@ -105,6 +122,7 @@ __export(index_exports, {
|
|
|
105
122
|
parseExternalConfig: () => parseExternalConfig,
|
|
106
123
|
parseGroupTimes: () => parseGroupTimes,
|
|
107
124
|
parseIni: () => parseIni,
|
|
125
|
+
parseJmsUserinfo: () => parseJmsUserinfo,
|
|
108
126
|
parseLink: () => parseLink,
|
|
109
127
|
parsePeers: () => parsePeers,
|
|
110
128
|
parseProxyGroupType: () => parseProxyGroupType,
|
|
@@ -113,6 +131,7 @@ __export(index_exports, {
|
|
|
113
131
|
parseRequestSettings: () => parseRequestSettings,
|
|
114
132
|
parseRulesetConfig: () => parseRulesetConfig,
|
|
115
133
|
parseSubscription: () => parseSubscription,
|
|
134
|
+
parseSubscriptionUserinfo: () => parseSubscriptionUserinfo,
|
|
116
135
|
parseTriBool: () => parseTriBool,
|
|
117
136
|
preprocessNodes: () => preprocessNodes,
|
|
118
137
|
processRemark: () => processRemark,
|
|
@@ -120,12 +139,16 @@ __export(index_exports, {
|
|
|
120
139
|
proxyToSsSub: () => proxyToSsSub,
|
|
121
140
|
proxyToSsd: () => proxyToSsd,
|
|
122
141
|
proxyTypeName: () => proxyTypeName,
|
|
142
|
+
queryBoolFlag: () => queryBoolFlag,
|
|
123
143
|
regMatch: () => regMatch,
|
|
124
144
|
regReplace: () => regReplace,
|
|
145
|
+
regionDisplayName: () => regionDisplayName,
|
|
146
|
+
regionFlag: () => regionFlag,
|
|
125
147
|
removeEmoji: () => removeEmoji,
|
|
126
148
|
renderRawIni: () => renderRawIni,
|
|
127
149
|
renderTemplate: () => renderTemplate,
|
|
128
150
|
replaceAllDistinct: () => replaceAllDistinct,
|
|
151
|
+
resolveNewFieldName: () => resolveNewFieldName,
|
|
129
152
|
rulesetToClashRules: () => rulesetToClashRules,
|
|
130
153
|
rulesetToSingBoxRules: () => rulesetToSingBoxRules,
|
|
131
154
|
rulesetToSurgeRules: () => rulesetToSurgeRules,
|
|
@@ -153,6 +176,7 @@ __export(index_exports, {
|
|
|
153
176
|
toQuanX: () => toQuanX,
|
|
154
177
|
toSingBox: () => toSingBox,
|
|
155
178
|
toSip008: () => toSip008,
|
|
179
|
+
toSurfboard: () => toSurfboard,
|
|
156
180
|
toSurge: () => toSurge,
|
|
157
181
|
transformRuleToCommon: () => transformRuleToCommon,
|
|
158
182
|
triBoolOr: () => triBoolOr,
|
|
@@ -208,6 +232,23 @@ function createProxyGroupConfig() {
|
|
|
208
232
|
usingProvider: []
|
|
209
233
|
};
|
|
210
234
|
}
|
|
235
|
+
function createSelectGroup(name) {
|
|
236
|
+
return {
|
|
237
|
+
disableUdp: void 0,
|
|
238
|
+
evaluateBeforeUse: void 0,
|
|
239
|
+
interval: 0,
|
|
240
|
+
lazy: void 0,
|
|
241
|
+
name,
|
|
242
|
+
persistent: void 0,
|
|
243
|
+
proxies: ["[]DIRECT", "!!TYPE=SS", "!!TYPE=SSR", "!!TYPE=VMESS", "!!TYPE=TROJAN"],
|
|
244
|
+
strategy: "consistent-hashing" /* ConsistentHashing */,
|
|
245
|
+
timeout: 0,
|
|
246
|
+
tolerance: 0,
|
|
247
|
+
type: "select" /* Select */,
|
|
248
|
+
url: "",
|
|
249
|
+
usingProvider: []
|
|
250
|
+
};
|
|
251
|
+
}
|
|
211
252
|
function parseProxyGroupType(value) {
|
|
212
253
|
const normalized = value.trim().toLowerCase();
|
|
213
254
|
switch (normalized) {
|
|
@@ -347,6 +388,7 @@ function createProxy() {
|
|
|
347
388
|
selfIp: "",
|
|
348
389
|
selfIpv6: "",
|
|
349
390
|
serverName: "",
|
|
391
|
+
shortId: "",
|
|
350
392
|
snellVersion: 0,
|
|
351
393
|
sni: "",
|
|
352
394
|
tcpFastOpen: void 0,
|
|
@@ -382,6 +424,7 @@ var TargetFormat = /* @__PURE__ */ ((TargetFormat2) => {
|
|
|
382
424
|
TargetFormat2["Clash"] = "clash";
|
|
383
425
|
TargetFormat2["ClashR"] = "clashr";
|
|
384
426
|
TargetFormat2["Surge"] = "surge";
|
|
427
|
+
TargetFormat2["Surfboard"] = "surfboard";
|
|
385
428
|
TargetFormat2["QuantumultX"] = "quanx";
|
|
386
429
|
TargetFormat2["Quantumult"] = "quan";
|
|
387
430
|
TargetFormat2["Loon"] = "loon";
|
|
@@ -390,6 +433,7 @@ var TargetFormat = /* @__PURE__ */ ((TargetFormat2) => {
|
|
|
390
433
|
TargetFormat2["Trojan"] = "trojan";
|
|
391
434
|
TargetFormat2["SSD"] = "ssd";
|
|
392
435
|
TargetFormat2["SSC"] = "ss";
|
|
436
|
+
TargetFormat2["SSSub"] = "sssub";
|
|
393
437
|
TargetFormat2["SSR"] = "ssr";
|
|
394
438
|
TargetFormat2["SingBox"] = "singbox";
|
|
395
439
|
TargetFormat2["Mixed"] = "mixed";
|
|
@@ -402,16 +446,21 @@ function createExtraSettings() {
|
|
|
402
446
|
addEmoji: false,
|
|
403
447
|
appendProxyType: false,
|
|
404
448
|
authorized: false,
|
|
449
|
+
autoCountry: false,
|
|
405
450
|
clashClassicalRuleset: false,
|
|
406
|
-
clashNewFieldName:
|
|
451
|
+
clashNewFieldName: true,
|
|
407
452
|
clashProxiesStyle: "flow",
|
|
408
453
|
clashProxyGroupsStyle: "flow",
|
|
409
454
|
clashScript: false,
|
|
455
|
+
countryLocale: "zh-CN",
|
|
456
|
+
countryResolver: void 0,
|
|
410
457
|
dedupe: false,
|
|
411
458
|
emojiArray: [],
|
|
412
459
|
enableRuleGenerator: true,
|
|
413
460
|
filterDeprecated: false,
|
|
414
461
|
managedConfigPrefix: "",
|
|
462
|
+
nameRegexArray: [],
|
|
463
|
+
nameRemove: [],
|
|
415
464
|
nodeList: false,
|
|
416
465
|
overwriteOriginalRules: true,
|
|
417
466
|
quanxDevId: "",
|
|
@@ -717,27 +766,35 @@ function urlEncode(input) {
|
|
|
717
766
|
(char) => `%${char.charCodeAt(0).toString(16).toUpperCase()}`
|
|
718
767
|
);
|
|
719
768
|
}
|
|
720
|
-
function
|
|
769
|
+
function normalizeQueryKey(key) {
|
|
770
|
+
return key.toLowerCase().replace(/_/g, "-");
|
|
771
|
+
}
|
|
772
|
+
function getAllUrlArgs(query, key) {
|
|
721
773
|
if (query === "") {
|
|
722
|
-
return
|
|
723
|
-
}
|
|
724
|
-
const
|
|
725
|
-
const
|
|
726
|
-
|
|
727
|
-
const
|
|
728
|
-
|
|
774
|
+
return [];
|
|
775
|
+
}
|
|
776
|
+
const hashCut = query.split("#", 1)[0];
|
|
777
|
+
const qIndex = hashCut.indexOf("?");
|
|
778
|
+
const rawQuery = qIndex >= 0 ? hashCut.slice(qIndex + 1) : hashCut;
|
|
779
|
+
const normalized = rawQuery.startsWith("?") ? rawQuery.slice(1) : rawQuery;
|
|
780
|
+
const values = [];
|
|
781
|
+
const target = normalizeQueryKey(key);
|
|
782
|
+
for (const part of normalized.split("&")) {
|
|
729
783
|
if (part === "") {
|
|
730
784
|
continue;
|
|
731
785
|
}
|
|
732
786
|
const eq = part.indexOf("=");
|
|
733
787
|
const rawKey = eq >= 0 ? part.slice(0, eq) : part;
|
|
734
|
-
if (rawKey
|
|
788
|
+
if (normalizeQueryKey(urlDecode(rawKey)) !== target) {
|
|
735
789
|
continue;
|
|
736
790
|
}
|
|
737
|
-
|
|
738
|
-
found = urlDecode(rawValue);
|
|
791
|
+
values.push(urlDecode(eq >= 0 ? part.slice(eq + 1) : ""));
|
|
739
792
|
}
|
|
740
|
-
return
|
|
793
|
+
return values;
|
|
794
|
+
}
|
|
795
|
+
function getUrlArg(query, key) {
|
|
796
|
+
const values = getAllUrlArgs(query, key);
|
|
797
|
+
return values.length > 0 ? values[values.length - 1].trim() : "";
|
|
741
798
|
}
|
|
742
799
|
function splitUrl(raw) {
|
|
743
800
|
const hashIndex = raw.indexOf("#");
|
|
@@ -813,7 +870,7 @@ function parseCustomProxyGroup(value) {
|
|
|
813
870
|
if (type === void 0) {
|
|
814
871
|
return void 0;
|
|
815
872
|
}
|
|
816
|
-
const
|
|
873
|
+
const group2 = {
|
|
817
874
|
disableUdp: void 0,
|
|
818
875
|
evaluateBeforeUse: void 0,
|
|
819
876
|
interval: 0,
|
|
@@ -834,29 +891,29 @@ function parseCustomProxyGroup(value) {
|
|
|
834
891
|
return void 0;
|
|
835
892
|
}
|
|
836
893
|
upperBound -= 2;
|
|
837
|
-
|
|
894
|
+
group2.url = parts[upperBound];
|
|
838
895
|
const times = parseGroupTimes(parts[upperBound + 1]);
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
896
|
+
group2.interval = times.interval;
|
|
897
|
+
group2.timeout = times.timeout;
|
|
898
|
+
group2.tolerance = times.tolerance;
|
|
842
899
|
}
|
|
843
900
|
for (let i = 2; i < upperBound; i += 1) {
|
|
844
901
|
const rule = parts[i];
|
|
845
902
|
if (startsWith(rule, "!!PROVIDER=")) {
|
|
846
|
-
|
|
903
|
+
group2.usingProvider.push(...rule.slice(11).split(","));
|
|
847
904
|
} else {
|
|
848
|
-
|
|
905
|
+
group2.proxies.push(rule);
|
|
849
906
|
}
|
|
850
907
|
}
|
|
851
|
-
return
|
|
908
|
+
return group2;
|
|
852
909
|
}
|
|
853
910
|
function parseRulesetConfig(value) {
|
|
854
911
|
const pos = value.indexOf(",");
|
|
855
912
|
if (pos === -1) {
|
|
856
913
|
return void 0;
|
|
857
914
|
}
|
|
858
|
-
const
|
|
859
|
-
const config = { group, interval: 86400, url: "" };
|
|
915
|
+
const group2 = value.slice(0, pos);
|
|
916
|
+
const config = { group: group2, interval: 86400, url: "" };
|
|
860
917
|
if (value.slice(pos + 1, pos + 3) === "[]") {
|
|
861
918
|
config.url = value.slice(pos + 1);
|
|
862
919
|
return config;
|
|
@@ -882,12 +939,15 @@ function parseRegexMatch(value, delimiter) {
|
|
|
882
939
|
function parseExternalConfig(content) {
|
|
883
940
|
const result = {
|
|
884
941
|
addEmoji: false,
|
|
942
|
+
autoCountry: false,
|
|
885
943
|
baseFiles: {},
|
|
886
944
|
emoji: [],
|
|
887
945
|
enableRuleGenerator: true,
|
|
888
946
|
excludeRemarks: [],
|
|
889
947
|
groups: [],
|
|
890
948
|
includeRemarks: [],
|
|
949
|
+
nameRegex: [],
|
|
950
|
+
nameRemove: [],
|
|
891
951
|
overwriteOriginalRules: true,
|
|
892
952
|
removeEmoji: false,
|
|
893
953
|
rename: [],
|
|
@@ -932,6 +992,17 @@ function parseExternalConfig(content) {
|
|
|
932
992
|
case "rename_node":
|
|
933
993
|
result.rename.push(parseRegexMatch(value, "@"));
|
|
934
994
|
break;
|
|
995
|
+
case "name_regex":
|
|
996
|
+
result.nameRegex.push(parseRegexMatch(value, "@"));
|
|
997
|
+
break;
|
|
998
|
+
case "name_remove":
|
|
999
|
+
for (const fragment of value.split(",")) {
|
|
1000
|
+
const trimmed = fragment.trim();
|
|
1001
|
+
if (trimmed !== "") {
|
|
1002
|
+
result.nameRemove.push(trimmed);
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
break;
|
|
935
1006
|
case "emoji":
|
|
936
1007
|
case "emojis":
|
|
937
1008
|
result.emoji.push(parseRegexMatch(value, ","));
|
|
@@ -951,6 +1022,10 @@ function parseExternalConfig(content) {
|
|
|
951
1022
|
case "add_emoji":
|
|
952
1023
|
result.addEmoji = value.toLowerCase() === "true";
|
|
953
1024
|
break;
|
|
1025
|
+
case "auto_country":
|
|
1026
|
+
case "country":
|
|
1027
|
+
result.autoCountry = value.toLowerCase() === "true";
|
|
1028
|
+
break;
|
|
954
1029
|
case "remove_old_emoji":
|
|
955
1030
|
case "remove_emoji":
|
|
956
1031
|
result.removeEmoji = value.toLowerCase() === "true";
|
|
@@ -974,7 +1049,13 @@ function parseExternalConfig(content) {
|
|
|
974
1049
|
|
|
975
1050
|
// src/settings/request-params.ts
|
|
976
1051
|
var TARGETS = new Set(Object.values(TargetFormat));
|
|
1052
|
+
function hasArg(query, key) {
|
|
1053
|
+
return getAllUrlArgs(query, key).length > 0;
|
|
1054
|
+
}
|
|
977
1055
|
function boolArg(query, key) {
|
|
1056
|
+
if (!hasArg(query, key)) {
|
|
1057
|
+
return false;
|
|
1058
|
+
}
|
|
978
1059
|
const value = getUrlArg(query, key).toLowerCase();
|
|
979
1060
|
return value === "true" || value === "1" || value === "";
|
|
980
1061
|
}
|
|
@@ -986,13 +1067,47 @@ function listArg(query, key) {
|
|
|
986
1067
|
const value = getUrlArg(query, key);
|
|
987
1068
|
return value === "" ? [] : value.split(",");
|
|
988
1069
|
}
|
|
1070
|
+
function resolveNewFieldName(query) {
|
|
1071
|
+
if (boolArg(query, "legacy") || boolArg(query, "legacy_field_name") || boolArg(query, "legacy-field-name")) {
|
|
1072
|
+
return false;
|
|
1073
|
+
}
|
|
1074
|
+
if (hasArg(query, "new_name") || hasArg(query, "new_field_name") || hasArg(query, "new-name") || hasArg(query, "new-field-name")) {
|
|
1075
|
+
return boolArg(query, "new_name") || boolArg(query, "new_field_name") || boolArg(query, "new-name") || boolArg(query, "new-field-name");
|
|
1076
|
+
}
|
|
1077
|
+
return true;
|
|
1078
|
+
}
|
|
1079
|
+
function firstArg(query, ...keys) {
|
|
1080
|
+
for (const key of keys) {
|
|
1081
|
+
const value = getUrlArg(query, key);
|
|
1082
|
+
if (value !== "") {
|
|
1083
|
+
return value;
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
return "";
|
|
1087
|
+
}
|
|
1088
|
+
function queryBoolFlag(query, ...keys) {
|
|
1089
|
+
let found = false;
|
|
1090
|
+
let result = false;
|
|
1091
|
+
for (const key of keys) {
|
|
1092
|
+
for (const raw of getAllUrlArgs(query, key)) {
|
|
1093
|
+
found = true;
|
|
1094
|
+
const normalized = raw.trim().toLowerCase();
|
|
1095
|
+
if (normalized === "" || normalized === "true" || normalized === "1") {
|
|
1096
|
+
result = true;
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
return found ? result : void 0;
|
|
1101
|
+
}
|
|
989
1102
|
function createRequestSettings() {
|
|
990
1103
|
return {
|
|
991
1104
|
addEmoji: false,
|
|
992
1105
|
appendType: false,
|
|
1106
|
+
autoCountry: false,
|
|
993
1107
|
autoExtract: false,
|
|
994
1108
|
clashScript: false,
|
|
995
1109
|
classicalRuleset: false,
|
|
1110
|
+
dedupe: false,
|
|
996
1111
|
emoji: [],
|
|
997
1112
|
excludeRemarks: [],
|
|
998
1113
|
filterDeprecated: false,
|
|
@@ -1002,7 +1117,9 @@ function createRequestSettings() {
|
|
|
1002
1117
|
interval: 0,
|
|
1003
1118
|
list: false,
|
|
1004
1119
|
mixin: "",
|
|
1005
|
-
|
|
1120
|
+
nameRegex: [],
|
|
1121
|
+
nameRemove: [],
|
|
1122
|
+
newFieldName: true,
|
|
1006
1123
|
nodeList: false,
|
|
1007
1124
|
proxiesStyle: "flow",
|
|
1008
1125
|
proxyGroupsStyle: "flow",
|
|
@@ -1017,7 +1134,9 @@ function createRequestSettings() {
|
|
|
1017
1134
|
tls13: void 0,
|
|
1018
1135
|
udp: void 0,
|
|
1019
1136
|
uploadPath: "",
|
|
1020
|
-
url: ""
|
|
1137
|
+
url: "",
|
|
1138
|
+
userinfoProvider: "",
|
|
1139
|
+
userinfoUrl: ""
|
|
1021
1140
|
};
|
|
1022
1141
|
}
|
|
1023
1142
|
function parseRequestSettings(query) {
|
|
@@ -1029,11 +1148,14 @@ function parseRequestSettings(query) {
|
|
|
1029
1148
|
settings.url = getUrlArg(query, "url");
|
|
1030
1149
|
settings.list = boolArg(query, "list");
|
|
1031
1150
|
settings.nodeList = settings.list;
|
|
1151
|
+
settings.sort = queryBoolFlag(query, "sort", "sort_flag", "sort-flag") ?? false;
|
|
1152
|
+
settings.dedupe = queryBoolFlag(query, "dedupe", "deduplicate") ?? false;
|
|
1032
1153
|
settings.addEmoji = boolArg(query, "add_emoji");
|
|
1033
1154
|
settings.removeEmoji = boolArg(query, "remove_emoji");
|
|
1155
|
+
settings.autoCountry = boolArg(query, "auto_country");
|
|
1034
1156
|
settings.appendType = boolArg(query, "append_type");
|
|
1035
1157
|
settings.filterDeprecated = boolArg(query, "filter_deprecated");
|
|
1036
|
-
settings.newFieldName =
|
|
1158
|
+
settings.newFieldName = resolveNewFieldName(query);
|
|
1037
1159
|
settings.classicalRuleset = boolArg(query, "classical");
|
|
1038
1160
|
settings.insert = getUrlArg(query, "insert") !== "";
|
|
1039
1161
|
settings.clashScript = boolArg(query, "clash_script");
|
|
@@ -1050,10 +1172,20 @@ function parseRequestSettings(query) {
|
|
|
1050
1172
|
settings.proxyGroupsStyle = getUrlArg(query, "proxy_groups_style") || "flow";
|
|
1051
1173
|
settings.includeRemarks = listArg(query, "include");
|
|
1052
1174
|
settings.excludeRemarks = listArg(query, "exclude");
|
|
1175
|
+
settings.userinfoUrl = firstArg(query, "userinfo_url", "userinfo-url", "userinfo");
|
|
1176
|
+
settings.userinfoProvider = firstArg(
|
|
1177
|
+
query,
|
|
1178
|
+
"userinfo_provider",
|
|
1179
|
+
"userinfo-provider",
|
|
1180
|
+
"userinfo_type",
|
|
1181
|
+
"userinfo-type"
|
|
1182
|
+
);
|
|
1053
1183
|
const renameRaw = getUrlArg(query, "rename");
|
|
1054
1184
|
if (renameRaw !== "") {
|
|
1055
1185
|
settings.rename = [parseRegexMatch(renameRaw, "@")];
|
|
1056
1186
|
}
|
|
1187
|
+
settings.nameRegex = getAllUrlArgs(query, "name_regex").flatMap((raw) => raw.split("\n")).map((raw) => raw.trim()).filter((raw) => raw !== "").map((raw) => parseRegexMatch(raw, "@"));
|
|
1188
|
+
settings.nameRemove = getAllUrlArgs(query, "name_remove").flatMap((raw) => raw.split(",")).map((raw) => raw.trim()).filter((raw) => raw !== "");
|
|
1057
1189
|
const emojiRaw = getUrlArg(query, "emoji");
|
|
1058
1190
|
if (emojiRaw !== "") {
|
|
1059
1191
|
settings.emoji = [parseRegexMatch(emojiRaw, ",")];
|
|
@@ -1061,6 +1193,235 @@ function parseRequestSettings(query) {
|
|
|
1061
1193
|
return settings;
|
|
1062
1194
|
}
|
|
1063
1195
|
|
|
1196
|
+
// src/userinfo.ts
|
|
1197
|
+
var PROVIDER_ALIASES = {
|
|
1198
|
+
auto: "auto",
|
|
1199
|
+
clash: "subscription",
|
|
1200
|
+
jms: "jms",
|
|
1201
|
+
"just-my-socks": "jms",
|
|
1202
|
+
justmysocks: "jms",
|
|
1203
|
+
raw: "subscription",
|
|
1204
|
+
sub: "subscription",
|
|
1205
|
+
subscription: "subscription",
|
|
1206
|
+
"subscription-userinfo": "subscription"
|
|
1207
|
+
};
|
|
1208
|
+
function normalizeUserinfoProvider(provider) {
|
|
1209
|
+
if (!provider) {
|
|
1210
|
+
return "auto";
|
|
1211
|
+
}
|
|
1212
|
+
const key = provider.trim().toLowerCase().replace(/_/g, "-");
|
|
1213
|
+
return PROVIDER_ALIASES[key] ?? "auto";
|
|
1214
|
+
}
|
|
1215
|
+
function inferUserinfoProviderFromUrl(url) {
|
|
1216
|
+
const squished = url.trim().toLowerCase().replace(/[-_]/g, "");
|
|
1217
|
+
if (squished.includes("justmysocks") || squished.includes("jmssub") || squished.includes("getbwcounter")) {
|
|
1218
|
+
return "jms";
|
|
1219
|
+
}
|
|
1220
|
+
return void 0;
|
|
1221
|
+
}
|
|
1222
|
+
function toNonNegativeNumber(value) {
|
|
1223
|
+
if (typeof value === "number") {
|
|
1224
|
+
return Number.isFinite(value) && value > 0 ? Math.trunc(value) : 0;
|
|
1225
|
+
}
|
|
1226
|
+
if (typeof value === "string") {
|
|
1227
|
+
const parsed = toInt(value);
|
|
1228
|
+
return parsed > 0 ? parsed : 0;
|
|
1229
|
+
}
|
|
1230
|
+
return 0;
|
|
1231
|
+
}
|
|
1232
|
+
function daysInUtcMonth(year, month) {
|
|
1233
|
+
return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
|
|
1234
|
+
}
|
|
1235
|
+
var DECIMAL_TO_BINARY = 1024 ** 3 / 1e3 ** 3;
|
|
1236
|
+
function scaleDecimalBytes(value) {
|
|
1237
|
+
return Math.round(value * DECIMAL_TO_BINARY);
|
|
1238
|
+
}
|
|
1239
|
+
function scaleUserinfoDecimal(data) {
|
|
1240
|
+
return {
|
|
1241
|
+
download: scaleDecimalBytes(data.download),
|
|
1242
|
+
expire: data.expire,
|
|
1243
|
+
total: scaleDecimalBytes(data.total),
|
|
1244
|
+
upload: scaleDecimalBytes(data.upload)
|
|
1245
|
+
};
|
|
1246
|
+
}
|
|
1247
|
+
function nextMonthlyResetTimestamp(resetDay, nowSec) {
|
|
1248
|
+
const day = Math.trunc(resetDay);
|
|
1249
|
+
if (!Number.isFinite(day) || day < 1 || day > 31) {
|
|
1250
|
+
return 0;
|
|
1251
|
+
}
|
|
1252
|
+
const now = nowSec && nowSec > 0 ? Math.trunc(nowSec) : Math.trunc(Date.now() / 1e3);
|
|
1253
|
+
const current = new Date(now * 1e3);
|
|
1254
|
+
const year = current.getUTCFullYear();
|
|
1255
|
+
const month = current.getUTCMonth();
|
|
1256
|
+
const today = current.getUTCDate();
|
|
1257
|
+
const useCurrentMonth = today < day;
|
|
1258
|
+
const targetYear = useCurrentMonth ? year : month === 11 ? year + 1 : year;
|
|
1259
|
+
const targetMonth = useCurrentMonth ? month : (month + 1) % 12;
|
|
1260
|
+
const clampedDay = Math.min(day, daysInUtcMonth(targetYear, targetMonth));
|
|
1261
|
+
return Math.trunc(Date.UTC(targetYear, targetMonth, clampedDay) / 1e3);
|
|
1262
|
+
}
|
|
1263
|
+
function parseJmsUserinfo(raw, nowSec) {
|
|
1264
|
+
let parsed;
|
|
1265
|
+
try {
|
|
1266
|
+
parsed = JSON.parse(raw);
|
|
1267
|
+
} catch {
|
|
1268
|
+
return void 0;
|
|
1269
|
+
}
|
|
1270
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
1271
|
+
return void 0;
|
|
1272
|
+
}
|
|
1273
|
+
const record = parsed;
|
|
1274
|
+
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;
|
|
1275
|
+
if (!hasJmsKeys) {
|
|
1276
|
+
return void 0;
|
|
1277
|
+
}
|
|
1278
|
+
const limitRaw = record["monthly_bw_limit_b"] ?? record["monthlyBwLimitB"];
|
|
1279
|
+
const usedRaw = record["bw_counter_b"] ?? record["bwCounterB"];
|
|
1280
|
+
const resetRaw = record["bw_reset_day_of_month"] ?? record["bwResetDayOfMonth"] ?? record["reset_day"] ?? record["resetDay"];
|
|
1281
|
+
const payload = {
|
|
1282
|
+
bwCounterB: usedRaw,
|
|
1283
|
+
bwResetDayOfMonth: resetRaw,
|
|
1284
|
+
monthlyBwLimitB: limitRaw
|
|
1285
|
+
};
|
|
1286
|
+
const total = scaleDecimalBytes(toNonNegativeNumber(payload.monthlyBwLimitB));
|
|
1287
|
+
const download = scaleDecimalBytes(toNonNegativeNumber(payload.bwCounterB));
|
|
1288
|
+
const resetDay = toInt(
|
|
1289
|
+
typeof payload.bwResetDayOfMonth === "number" ? String(payload.bwResetDayOfMonth) : payload.bwResetDayOfMonth ?? ""
|
|
1290
|
+
);
|
|
1291
|
+
return {
|
|
1292
|
+
download,
|
|
1293
|
+
expire: resetDay > 0 ? nextMonthlyResetTimestamp(resetDay, nowSec) : 0,
|
|
1294
|
+
total,
|
|
1295
|
+
upload: 0
|
|
1296
|
+
};
|
|
1297
|
+
}
|
|
1298
|
+
function parseSubscriptionUserinfo(header) {
|
|
1299
|
+
if (!header || header.trim() === "") {
|
|
1300
|
+
return void 0;
|
|
1301
|
+
}
|
|
1302
|
+
const data = { download: 0, expire: 0, total: 0, upload: 0 };
|
|
1303
|
+
let found = false;
|
|
1304
|
+
for (const part of header.split(";")) {
|
|
1305
|
+
const eq = part.indexOf("=");
|
|
1306
|
+
if (eq === -1) {
|
|
1307
|
+
continue;
|
|
1308
|
+
}
|
|
1309
|
+
const key = part.slice(0, eq).trim().toLowerCase();
|
|
1310
|
+
const value = part.slice(eq + 1).trim();
|
|
1311
|
+
if (value === "") {
|
|
1312
|
+
continue;
|
|
1313
|
+
}
|
|
1314
|
+
switch (key) {
|
|
1315
|
+
case "download":
|
|
1316
|
+
case "down":
|
|
1317
|
+
data.download = toNonNegativeNumber(toInt(value));
|
|
1318
|
+
found = true;
|
|
1319
|
+
break;
|
|
1320
|
+
case "expire":
|
|
1321
|
+
case "expires":
|
|
1322
|
+
data.expire = toNonNegativeNumber(toInt(value));
|
|
1323
|
+
found = true;
|
|
1324
|
+
break;
|
|
1325
|
+
case "total":
|
|
1326
|
+
case "limit":
|
|
1327
|
+
data.total = toNonNegativeNumber(toInt(value));
|
|
1328
|
+
found = true;
|
|
1329
|
+
break;
|
|
1330
|
+
case "upload":
|
|
1331
|
+
case "up":
|
|
1332
|
+
data.upload = toNonNegativeNumber(toInt(value));
|
|
1333
|
+
found = true;
|
|
1334
|
+
break;
|
|
1335
|
+
default:
|
|
1336
|
+
break;
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
return found ? data : void 0;
|
|
1340
|
+
}
|
|
1341
|
+
function formatSubscriptionUserinfo(data) {
|
|
1342
|
+
const upload = toNonNegativeNumber(data.upload);
|
|
1343
|
+
const download = toNonNegativeNumber(data.download);
|
|
1344
|
+
const total = toNonNegativeNumber(data.total);
|
|
1345
|
+
const expire = toNonNegativeNumber(data.expire);
|
|
1346
|
+
return `upload=${upload}; download=${download}; total=${total}; expire=${expire}`;
|
|
1347
|
+
}
|
|
1348
|
+
function parseGenericJsonUserinfo(raw) {
|
|
1349
|
+
let parsed;
|
|
1350
|
+
try {
|
|
1351
|
+
parsed = JSON.parse(raw);
|
|
1352
|
+
} catch {
|
|
1353
|
+
return void 0;
|
|
1354
|
+
}
|
|
1355
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
1356
|
+
return void 0;
|
|
1357
|
+
}
|
|
1358
|
+
const record = parsed;
|
|
1359
|
+
const pick = (...keys) => {
|
|
1360
|
+
for (const key of keys) {
|
|
1361
|
+
if (record[key] !== void 0) {
|
|
1362
|
+
return record[key];
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
return void 0;
|
|
1366
|
+
};
|
|
1367
|
+
const uploadRaw = pick("upload", "upload_b", "up", "u");
|
|
1368
|
+
const downloadRaw = pick(
|
|
1369
|
+
"download",
|
|
1370
|
+
"download_b",
|
|
1371
|
+
"down",
|
|
1372
|
+
"d",
|
|
1373
|
+
"used",
|
|
1374
|
+
"bw_counter_b",
|
|
1375
|
+
"bwCounterB"
|
|
1376
|
+
);
|
|
1377
|
+
const totalRaw = pick(
|
|
1378
|
+
"total",
|
|
1379
|
+
"total_b",
|
|
1380
|
+
"limit",
|
|
1381
|
+
"bandwidth",
|
|
1382
|
+
"monthly_bw_limit_b",
|
|
1383
|
+
"monthlyBwLimitB"
|
|
1384
|
+
);
|
|
1385
|
+
const expireRaw = pick("expire", "expires", "expire_at", "expireAt", "reset");
|
|
1386
|
+
if (uploadRaw === void 0 && downloadRaw === void 0 && totalRaw === void 0) {
|
|
1387
|
+
return void 0;
|
|
1388
|
+
}
|
|
1389
|
+
return {
|
|
1390
|
+
download: toNonNegativeNumber(downloadRaw),
|
|
1391
|
+
expire: toNonNegativeNumber(expireRaw),
|
|
1392
|
+
total: toNonNegativeNumber(totalRaw),
|
|
1393
|
+
upload: toNonNegativeNumber(uploadRaw)
|
|
1394
|
+
};
|
|
1395
|
+
}
|
|
1396
|
+
function convertUserinfo(raw, provider, nowSec) {
|
|
1397
|
+
if (!raw || raw.trim() === "") {
|
|
1398
|
+
return void 0;
|
|
1399
|
+
}
|
|
1400
|
+
const normalized = normalizeUserinfoProvider(provider);
|
|
1401
|
+
if (normalized === "jms") {
|
|
1402
|
+
const jms2 = parseJmsUserinfo(raw, nowSec);
|
|
1403
|
+
if (jms2) {
|
|
1404
|
+
return formatSubscriptionUserinfo(jms2);
|
|
1405
|
+
}
|
|
1406
|
+
const generic2 = parseGenericJsonUserinfo(raw);
|
|
1407
|
+
return generic2 ? formatSubscriptionUserinfo(scaleUserinfoDecimal(generic2)) : void 0;
|
|
1408
|
+
}
|
|
1409
|
+
if (normalized === "subscription") {
|
|
1410
|
+
const parsed = parseSubscriptionUserinfo(raw) ?? parseGenericJsonUserinfo(raw);
|
|
1411
|
+
return parsed ? formatSubscriptionUserinfo(parsed) : void 0;
|
|
1412
|
+
}
|
|
1413
|
+
const jms = parseJmsUserinfo(raw, nowSec);
|
|
1414
|
+
if (jms) {
|
|
1415
|
+
return formatSubscriptionUserinfo(jms);
|
|
1416
|
+
}
|
|
1417
|
+
const generic = parseGenericJsonUserinfo(raw);
|
|
1418
|
+
if (generic) {
|
|
1419
|
+
return formatSubscriptionUserinfo(generic);
|
|
1420
|
+
}
|
|
1421
|
+
const header = parseSubscriptionUserinfo(raw);
|
|
1422
|
+
return header ? formatSubscriptionUserinfo(header) : void 0;
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1064
1425
|
// src/parser/ciphers.ts
|
|
1065
1426
|
var SS_CIPHERS = [
|
|
1066
1427
|
"2022-blake3-aes-128-gcm",
|
|
@@ -1120,9 +1481,9 @@ function isFlattenableSsr(method, obfs, protocol) {
|
|
|
1120
1481
|
}
|
|
1121
1482
|
|
|
1122
1483
|
// src/parser/construct.ts
|
|
1123
|
-
function commonConstruct(node, type,
|
|
1484
|
+
function commonConstruct(node, type, group2, remark, server, port, udp, tfo, scv, tls13, underlyingProxy) {
|
|
1124
1485
|
node.type = type;
|
|
1125
|
-
node.group =
|
|
1486
|
+
node.group = group2;
|
|
1126
1487
|
node.remark = remark;
|
|
1127
1488
|
node.hostname = server;
|
|
1128
1489
|
node.underlyingProxy = underlyingProxy;
|
|
@@ -1138,7 +1499,7 @@ function vmessConstruct(node, options) {
|
|
|
1138
1499
|
aid = 0,
|
|
1139
1500
|
cipher = "",
|
|
1140
1501
|
edge = "",
|
|
1141
|
-
group,
|
|
1502
|
+
group: group2,
|
|
1142
1503
|
host = "",
|
|
1143
1504
|
id = "",
|
|
1144
1505
|
net = "",
|
|
@@ -1157,7 +1518,7 @@ function vmessConstruct(node, options) {
|
|
|
1157
1518
|
commonConstruct(
|
|
1158
1519
|
node,
|
|
1159
1520
|
"vmess" /* VMess */,
|
|
1160
|
-
|
|
1521
|
+
group2,
|
|
1161
1522
|
remark,
|
|
1162
1523
|
add,
|
|
1163
1524
|
port,
|
|
@@ -1454,6 +1815,8 @@ function vlessConstruct(node, options) {
|
|
|
1454
1815
|
node.host = options.host ?? "";
|
|
1455
1816
|
node.path = options.path ?? "";
|
|
1456
1817
|
node.fingerprint = options.fingerprint ?? "";
|
|
1818
|
+
node.publicKey = options.publicKey ?? "";
|
|
1819
|
+
node.shortId = options.shortId ?? "";
|
|
1457
1820
|
if (options.alpn) {
|
|
1458
1821
|
node.alpn = options.alpn;
|
|
1459
1822
|
}
|
|
@@ -1503,7 +1866,7 @@ function explodeNetch(netch, node) {
|
|
|
1503
1866
|
return;
|
|
1504
1867
|
}
|
|
1505
1868
|
const type = str(data.Type);
|
|
1506
|
-
const
|
|
1869
|
+
const group2 = str(data.Group);
|
|
1507
1870
|
let remark = str(data.Remark);
|
|
1508
1871
|
const address = str(data.Hostname);
|
|
1509
1872
|
const udp = tri(data.EnableUDP);
|
|
@@ -1521,7 +1884,7 @@ function explodeNetch(netch, node) {
|
|
|
1521
1884
|
switch (type) {
|
|
1522
1885
|
case "SS":
|
|
1523
1886
|
ssConstruct(node, {
|
|
1524
|
-
group:
|
|
1887
|
+
group: group2 === "" ? DEFAULT_GROUPS.ss : group2,
|
|
1525
1888
|
method,
|
|
1526
1889
|
password,
|
|
1527
1890
|
plugin: str(data.Plugin),
|
|
@@ -1539,7 +1902,7 @@ function explodeNetch(netch, node) {
|
|
|
1539
1902
|
const obfs = str(data.OBFS);
|
|
1540
1903
|
if (isFlattenableSsr(method, obfs, protocol)) {
|
|
1541
1904
|
ssConstruct(node, {
|
|
1542
|
-
group:
|
|
1905
|
+
group: group2 === "" ? DEFAULT_GROUPS.ss : group2,
|
|
1543
1906
|
method,
|
|
1544
1907
|
password,
|
|
1545
1908
|
plugin: str(data.Plugin),
|
|
@@ -1553,7 +1916,7 @@ function explodeNetch(netch, node) {
|
|
|
1553
1916
|
});
|
|
1554
1917
|
} else {
|
|
1555
1918
|
ssrConstruct(node, {
|
|
1556
|
-
group:
|
|
1919
|
+
group: group2 === "" ? DEFAULT_GROUPS.ssr : group2,
|
|
1557
1920
|
method,
|
|
1558
1921
|
obfs,
|
|
1559
1922
|
obfsParam: str(data.OBFSParam),
|
|
@@ -1576,7 +1939,7 @@ function explodeNetch(netch, node) {
|
|
|
1576
1939
|
aid: str(data.AlterID),
|
|
1577
1940
|
cipher: method,
|
|
1578
1941
|
edge: str(data.Edge),
|
|
1579
|
-
group:
|
|
1942
|
+
group: group2 === "" ? DEFAULT_GROUPS.v2ray : group2,
|
|
1580
1943
|
host: str(data.Host),
|
|
1581
1944
|
id: str(data.UserID),
|
|
1582
1945
|
net: str(data.TransferProtocol),
|
|
@@ -1593,7 +1956,7 @@ function explodeNetch(netch, node) {
|
|
|
1593
1956
|
break;
|
|
1594
1957
|
case "Socks5":
|
|
1595
1958
|
socksConstruct(node, {
|
|
1596
|
-
group:
|
|
1959
|
+
group: group2 === "" ? DEFAULT_GROUPS.socks : group2,
|
|
1597
1960
|
password,
|
|
1598
1961
|
port,
|
|
1599
1962
|
remark,
|
|
@@ -1607,7 +1970,7 @@ function explodeNetch(netch, node) {
|
|
|
1607
1970
|
case "HTTP":
|
|
1608
1971
|
case "HTTPS":
|
|
1609
1972
|
httpConstruct(node, {
|
|
1610
|
-
group:
|
|
1973
|
+
group: group2 === "" ? DEFAULT_GROUPS.http : group2,
|
|
1611
1974
|
password,
|
|
1612
1975
|
port,
|
|
1613
1976
|
remark,
|
|
@@ -1619,7 +1982,7 @@ function explodeNetch(netch, node) {
|
|
|
1619
1982
|
break;
|
|
1620
1983
|
case "Trojan":
|
|
1621
1984
|
trojanConstruct(node, {
|
|
1622
|
-
group:
|
|
1985
|
+
group: group2 === "" ? DEFAULT_GROUPS.trojan : group2,
|
|
1623
1986
|
host: str(data.Host),
|
|
1624
1987
|
network: str(data.TransferProtocol),
|
|
1625
1988
|
password,
|
|
@@ -1635,7 +1998,7 @@ function explodeNetch(netch, node) {
|
|
|
1635
1998
|
break;
|
|
1636
1999
|
case "Snell":
|
|
1637
2000
|
snellConstruct(node, {
|
|
1638
|
-
group:
|
|
2001
|
+
group: group2 === "" ? DEFAULT_GROUPS.snell : group2,
|
|
1639
2002
|
host: str(data.Host),
|
|
1640
2003
|
obfs: str(data.OBFS),
|
|
1641
2004
|
password,
|
|
@@ -1699,10 +2062,10 @@ function explodeClash(root, nodes) {
|
|
|
1699
2062
|
const tfo = asTri(get(single, "fast-open"));
|
|
1700
2063
|
const scv = asTri(get(single, "skip-cert-verify"));
|
|
1701
2064
|
const node = createProxy();
|
|
1702
|
-
let
|
|
2065
|
+
let group2 = "";
|
|
1703
2066
|
switch (proxyType) {
|
|
1704
2067
|
case "vmess": {
|
|
1705
|
-
|
|
2068
|
+
group2 = DEFAULT_GROUPS.v2ray;
|
|
1706
2069
|
const id = asString(get(single, "uuid"));
|
|
1707
2070
|
const aid = asString(get(single, "alterId"));
|
|
1708
2071
|
const cipher = asString(get(single, "cipher"));
|
|
@@ -1748,7 +2111,7 @@ function explodeClash(root, nodes) {
|
|
|
1748
2111
|
aid,
|
|
1749
2112
|
cipher,
|
|
1750
2113
|
edge,
|
|
1751
|
-
group,
|
|
2114
|
+
group: group2,
|
|
1752
2115
|
host,
|
|
1753
2116
|
id,
|
|
1754
2117
|
net,
|
|
@@ -1766,7 +2129,7 @@ function explodeClash(root, nodes) {
|
|
|
1766
2129
|
break;
|
|
1767
2130
|
}
|
|
1768
2131
|
case "ss": {
|
|
1769
|
-
|
|
2132
|
+
group2 = DEFAULT_GROUPS.ss;
|
|
1770
2133
|
let cipher = asString(get(single, "cipher"));
|
|
1771
2134
|
const password = asString(get(single, "password"));
|
|
1772
2135
|
let plugin = "";
|
|
@@ -1817,7 +2180,7 @@ function explodeClash(root, nodes) {
|
|
|
1817
2180
|
cipher = cipher.replace(/AEAD_/g, "").replace(/_/g, "-").toLowerCase();
|
|
1818
2181
|
}
|
|
1819
2182
|
ssConstruct(node, {
|
|
1820
|
-
group,
|
|
2183
|
+
group: group2,
|
|
1821
2184
|
method: cipher,
|
|
1822
2185
|
password,
|
|
1823
2186
|
plugin,
|
|
@@ -1833,11 +2196,11 @@ function explodeClash(root, nodes) {
|
|
|
1833
2196
|
break;
|
|
1834
2197
|
}
|
|
1835
2198
|
case "socks5": {
|
|
1836
|
-
|
|
2199
|
+
group2 = DEFAULT_GROUPS.socks;
|
|
1837
2200
|
const user = asString(get(single, "username"));
|
|
1838
2201
|
const password = asString(get(single, "password"));
|
|
1839
2202
|
socksConstruct(node, {
|
|
1840
|
-
group,
|
|
2203
|
+
group: group2,
|
|
1841
2204
|
password,
|
|
1842
2205
|
port,
|
|
1843
2206
|
remark: ps,
|
|
@@ -1848,7 +2211,7 @@ function explodeClash(root, nodes) {
|
|
|
1848
2211
|
break;
|
|
1849
2212
|
}
|
|
1850
2213
|
case "ssr": {
|
|
1851
|
-
|
|
2214
|
+
group2 = DEFAULT_GROUPS.ssr;
|
|
1852
2215
|
let cipher = asString(get(single, "cipher"));
|
|
1853
2216
|
if (cipher === "dummy") {
|
|
1854
2217
|
cipher = "none";
|
|
@@ -1859,7 +2222,7 @@ function explodeClash(root, nodes) {
|
|
|
1859
2222
|
const protocolParam = get(single, "protocol-param") !== void 0 ? asString(get(single, "protocol-param")) : asString(get(single, "protocolparam"));
|
|
1860
2223
|
const obfsParam = get(single, "obfs-param") !== void 0 ? asString(get(single, "obfs-param")) : asString(get(single, "obfsparam"));
|
|
1861
2224
|
ssrConstruct(node, {
|
|
1862
|
-
group,
|
|
2225
|
+
group: group2,
|
|
1863
2226
|
method: cipher,
|
|
1864
2227
|
obfs,
|
|
1865
2228
|
obfsParam,
|
|
@@ -1877,12 +2240,12 @@ function explodeClash(root, nodes) {
|
|
|
1877
2240
|
break;
|
|
1878
2241
|
}
|
|
1879
2242
|
case "http": {
|
|
1880
|
-
|
|
2243
|
+
group2 = DEFAULT_GROUPS.http;
|
|
1881
2244
|
const user = asString(get(single, "username"));
|
|
1882
2245
|
const password = asString(get(single, "password"));
|
|
1883
2246
|
const tls = asString(get(single, "tls"));
|
|
1884
2247
|
httpConstruct(node, {
|
|
1885
|
-
group,
|
|
2248
|
+
group: group2,
|
|
1886
2249
|
password,
|
|
1887
2250
|
port,
|
|
1888
2251
|
remark: ps,
|
|
@@ -1896,7 +2259,7 @@ function explodeClash(root, nodes) {
|
|
|
1896
2259
|
break;
|
|
1897
2260
|
}
|
|
1898
2261
|
case "trojan": {
|
|
1899
|
-
|
|
2262
|
+
group2 = DEFAULT_GROUPS.trojan;
|
|
1900
2263
|
const password = asString(get(single, "password"));
|
|
1901
2264
|
const host = asString(get(single, "sni"));
|
|
1902
2265
|
let net = asString(get(single, "network"));
|
|
@@ -1914,7 +2277,7 @@ function explodeClash(root, nodes) {
|
|
|
1914
2277
|
break;
|
|
1915
2278
|
}
|
|
1916
2279
|
trojanConstruct(node, {
|
|
1917
|
-
group,
|
|
2280
|
+
group: group2,
|
|
1918
2281
|
host,
|
|
1919
2282
|
network: net,
|
|
1920
2283
|
password,
|
|
@@ -1931,13 +2294,13 @@ function explodeClash(root, nodes) {
|
|
|
1931
2294
|
break;
|
|
1932
2295
|
}
|
|
1933
2296
|
case "snell": {
|
|
1934
|
-
|
|
2297
|
+
group2 = DEFAULT_GROUPS.snell;
|
|
1935
2298
|
const password = asString(get(single, "psk"));
|
|
1936
2299
|
const obfs = asString(get(get(single, "obfs-opts"), "mode"));
|
|
1937
2300
|
const host = asString(get(get(single, "obfs-opts"), "host"));
|
|
1938
2301
|
const version = asString(get(single, "version"));
|
|
1939
2302
|
snellConstruct(node, {
|
|
1940
|
-
group,
|
|
2303
|
+
group: group2,
|
|
1941
2304
|
host,
|
|
1942
2305
|
obfs,
|
|
1943
2306
|
password,
|
|
@@ -1953,7 +2316,7 @@ function explodeClash(root, nodes) {
|
|
|
1953
2316
|
break;
|
|
1954
2317
|
}
|
|
1955
2318
|
case "wireguard": {
|
|
1956
|
-
|
|
2319
|
+
group2 = DEFAULT_GROUPS.wireguard;
|
|
1957
2320
|
const publicKey = asString(get(single, "public-key"));
|
|
1958
2321
|
const privateKey = asString(get(single, "private-key"));
|
|
1959
2322
|
const dns = get(single, "dns");
|
|
@@ -1964,7 +2327,7 @@ function explodeClash(root, nodes) {
|
|
|
1964
2327
|
const ipv6 = asString(get(single, "ipv6"));
|
|
1965
2328
|
wireGuardConstruct(node, {
|
|
1966
2329
|
dnsServers,
|
|
1967
|
-
group,
|
|
2330
|
+
group: group2,
|
|
1968
2331
|
keepAlive: "0",
|
|
1969
2332
|
mtu,
|
|
1970
2333
|
port,
|
|
@@ -1982,7 +2345,7 @@ function explodeClash(root, nodes) {
|
|
|
1982
2345
|
break;
|
|
1983
2346
|
}
|
|
1984
2347
|
case "hysteria": {
|
|
1985
|
-
|
|
2348
|
+
group2 = DEFAULT_GROUPS.hysteria;
|
|
1986
2349
|
const ports = asString(get(single, "ports"));
|
|
1987
2350
|
const protocol = asString(get(single, "protocol"));
|
|
1988
2351
|
const obfsProtocol = asString(get(single, "obfs-protocol"));
|
|
@@ -2019,7 +2382,7 @@ function explodeClash(root, nodes) {
|
|
|
2019
2382
|
down,
|
|
2020
2383
|
downSpeed,
|
|
2021
2384
|
fingerprint,
|
|
2022
|
-
group,
|
|
2385
|
+
group: group2,
|
|
2023
2386
|
hopInterval,
|
|
2024
2387
|
obfs,
|
|
2025
2388
|
obfsProtocol,
|
|
@@ -2040,7 +2403,7 @@ function explodeClash(root, nodes) {
|
|
|
2040
2403
|
break;
|
|
2041
2404
|
}
|
|
2042
2405
|
case "hysteria2": {
|
|
2043
|
-
|
|
2406
|
+
group2 = DEFAULT_GROUPS.hysteria2;
|
|
2044
2407
|
const ports = asString(get(single, "ports"));
|
|
2045
2408
|
const up = asString(get(single, "up"));
|
|
2046
2409
|
const down = asString(get(single, "down"));
|
|
@@ -2065,7 +2428,7 @@ function explodeClash(root, nodes) {
|
|
|
2065
2428
|
cwnd,
|
|
2066
2429
|
down,
|
|
2067
2430
|
fingerprint,
|
|
2068
|
-
group,
|
|
2431
|
+
group: group2,
|
|
2069
2432
|
hopInterval,
|
|
2070
2433
|
obfs,
|
|
2071
2434
|
obfsPassword,
|
|
@@ -2083,11 +2446,11 @@ function explodeClash(root, nodes) {
|
|
|
2083
2446
|
break;
|
|
2084
2447
|
}
|
|
2085
2448
|
case "anytls": {
|
|
2086
|
-
|
|
2449
|
+
group2 = DEFAULT_GROUPS.anytls;
|
|
2087
2450
|
const password = asString(get(single, "password"));
|
|
2088
2451
|
const sni = asString(get(single, "sni"));
|
|
2089
2452
|
anyTlsConstruct(node, {
|
|
2090
|
-
group,
|
|
2453
|
+
group: group2,
|
|
2091
2454
|
password,
|
|
2092
2455
|
port,
|
|
2093
2456
|
remark: ps,
|
|
@@ -2101,7 +2464,7 @@ function explodeClash(root, nodes) {
|
|
|
2101
2464
|
break;
|
|
2102
2465
|
}
|
|
2103
2466
|
case "vless": {
|
|
2104
|
-
|
|
2467
|
+
group2 = DEFAULT_GROUPS.v2ray;
|
|
2105
2468
|
const userId = asString(get(single, "uuid"));
|
|
2106
2469
|
const net = asString(get(single, "network"));
|
|
2107
2470
|
const tls = asString(get(single, "tls"));
|
|
@@ -2119,7 +2482,7 @@ function explodeClash(root, nodes) {
|
|
|
2119
2482
|
encryption: asString(get(single, "encryption")),
|
|
2120
2483
|
fingerprint: asString(get(single, "client-fingerprint")),
|
|
2121
2484
|
flow: asString(get(single, "flow")),
|
|
2122
|
-
group,
|
|
2485
|
+
group: group2,
|
|
2123
2486
|
host,
|
|
2124
2487
|
network: net,
|
|
2125
2488
|
path,
|
|
@@ -2137,12 +2500,12 @@ function explodeClash(root, nodes) {
|
|
|
2137
2500
|
break;
|
|
2138
2501
|
}
|
|
2139
2502
|
case "tuic": {
|
|
2140
|
-
|
|
2503
|
+
group2 = DEFAULT_GROUPS.v2ray;
|
|
2141
2504
|
const alpnValue = get(single, "alpn");
|
|
2142
2505
|
tuicConstruct(node, {
|
|
2143
2506
|
alpn: Array.isArray(alpnValue) ? alpnValue.map((a) => String(a)) : void 0,
|
|
2144
2507
|
congestionControl: asString(get(single, "congestion-controller")),
|
|
2145
|
-
group,
|
|
2508
|
+
group: group2,
|
|
2146
2509
|
password: asString(get(single, "password")),
|
|
2147
2510
|
port,
|
|
2148
2511
|
remark: ps,
|
|
@@ -2209,8 +2572,8 @@ function collectKeyValues(lines, startIndex, sink) {
|
|
|
2209
2572
|
sink[trim(line.slice(0, eq))] = trim(line.slice(eq + 1));
|
|
2210
2573
|
}
|
|
2211
2574
|
}
|
|
2212
|
-
function explodeSurge(
|
|
2213
|
-
let text =
|
|
2575
|
+
function explodeSurge(surge2, nodes) {
|
|
2576
|
+
let text = surge2;
|
|
2214
2577
|
if (text.includes("[Proxy]")) {
|
|
2215
2578
|
text = text.replace(/^[\s\S]*?\[/, "[");
|
|
2216
2579
|
}
|
|
@@ -3035,7 +3398,7 @@ function explodeSsConf(content, nodes) {
|
|
|
3035
3398
|
if (!(section in json)) {
|
|
3036
3399
|
return;
|
|
3037
3400
|
}
|
|
3038
|
-
const
|
|
3401
|
+
const group2 = asString(json.remarks);
|
|
3039
3402
|
const list = json[section];
|
|
3040
3403
|
if (!Array.isArray(list)) {
|
|
3041
3404
|
return;
|
|
@@ -3050,7 +3413,7 @@ function explodeSsConf(content, nodes) {
|
|
|
3050
3413
|
const server = asString(entry.server);
|
|
3051
3414
|
const node = createProxy();
|
|
3052
3415
|
ssConstruct(node, {
|
|
3053
|
-
group,
|
|
3416
|
+
group: group2,
|
|
3054
3417
|
method: asString(entry.method),
|
|
3055
3418
|
password: asString(entry.password),
|
|
3056
3419
|
plugin: asString(entry.plugin),
|
|
@@ -3155,7 +3518,7 @@ function explodeSsrConf(content, nodes) {
|
|
|
3155
3518
|
return;
|
|
3156
3519
|
}
|
|
3157
3520
|
for (const entry of list) {
|
|
3158
|
-
const
|
|
3521
|
+
const group2 = asString(entry.group) === "" ? DEFAULT_GROUPS.ssr : asString(entry.group);
|
|
3159
3522
|
const server = asString(entry.server);
|
|
3160
3523
|
const port = asString(entry.server_port);
|
|
3161
3524
|
if (port === "0" || port === "") {
|
|
@@ -3164,7 +3527,7 @@ function explodeSsrConf(content, nodes) {
|
|
|
3164
3527
|
const remark = asString(entry.remarks) === "" ? `${server}:${port}` : asString(entry.remarks);
|
|
3165
3528
|
const node = createProxy();
|
|
3166
3529
|
ssrConstruct(node, {
|
|
3167
|
-
group,
|
|
3530
|
+
group: group2,
|
|
3168
3531
|
method: asString(entry.method),
|
|
3169
3532
|
obfs: asString(entry.obfs),
|
|
3170
3533
|
obfsParam: asString(entry.obfsparam),
|
|
@@ -3269,9 +3632,9 @@ function explodeVmessConf(content, nodes) {
|
|
|
3269
3632
|
continue;
|
|
3270
3633
|
}
|
|
3271
3634
|
const subid = asString(entry.subid);
|
|
3272
|
-
let
|
|
3635
|
+
let group2 = "";
|
|
3273
3636
|
if (subid !== "") {
|
|
3274
|
-
|
|
3637
|
+
group2 = subdata.get(subid) ?? "";
|
|
3275
3638
|
}
|
|
3276
3639
|
if (ps === "") {
|
|
3277
3640
|
ps = `${add}:${port}`;
|
|
@@ -3284,7 +3647,7 @@ function explodeVmessConf(content, nodes) {
|
|
|
3284
3647
|
add,
|
|
3285
3648
|
aid: asString(entry.alterId),
|
|
3286
3649
|
cipher: asString(entry.security),
|
|
3287
|
-
group:
|
|
3650
|
+
group: group2 || DEFAULT_GROUPS.v2ray,
|
|
3288
3651
|
host: asString(entry.requestHost),
|
|
3289
3652
|
id: asString(entry.id),
|
|
3290
3653
|
net: asString(entry.network),
|
|
@@ -3298,7 +3661,7 @@ function explodeVmessConf(content, nodes) {
|
|
|
3298
3661
|
});
|
|
3299
3662
|
} else if (configType === 3) {
|
|
3300
3663
|
ssConstruct(node, {
|
|
3301
|
-
group:
|
|
3664
|
+
group: group2 || DEFAULT_GROUPS.ss,
|
|
3302
3665
|
method: asString(entry.security),
|
|
3303
3666
|
password: asString(entry.id),
|
|
3304
3667
|
port,
|
|
@@ -3308,7 +3671,7 @@ function explodeVmessConf(content, nodes) {
|
|
|
3308
3671
|
});
|
|
3309
3672
|
} else if (configType === 4) {
|
|
3310
3673
|
socksConstruct(node, {
|
|
3311
|
-
group:
|
|
3674
|
+
group: group2 || DEFAULT_GROUPS.socks,
|
|
3312
3675
|
port,
|
|
3313
3676
|
remark: ps,
|
|
3314
3677
|
scv,
|
|
@@ -3334,7 +3697,7 @@ function explodeSstap(content, nodes) {
|
|
|
3334
3697
|
}
|
|
3335
3698
|
let index = nodes.length;
|
|
3336
3699
|
for (const entry of json.configs) {
|
|
3337
|
-
const
|
|
3700
|
+
const group2 = asString(entry.group);
|
|
3338
3701
|
const server = asString(entry.server);
|
|
3339
3702
|
const port = asString(entry.server_port);
|
|
3340
3703
|
if (port === "0" || port === "") {
|
|
@@ -3346,7 +3709,7 @@ function explodeSstap(content, nodes) {
|
|
|
3346
3709
|
const configType = toInt(entry.type);
|
|
3347
3710
|
if (configType === 5) {
|
|
3348
3711
|
socksConstruct(node, {
|
|
3349
|
-
group,
|
|
3712
|
+
group: group2,
|
|
3350
3713
|
password,
|
|
3351
3714
|
port,
|
|
3352
3715
|
remark,
|
|
@@ -3358,10 +3721,10 @@ function explodeSstap(content, nodes) {
|
|
|
3358
3721
|
const obfs = asString(entry.obfs);
|
|
3359
3722
|
const method = asString(entry.method);
|
|
3360
3723
|
if (isFlattenableSsr(method, obfs, protocol)) {
|
|
3361
|
-
ssConstruct(node, { group, method, password, port, remark, server });
|
|
3724
|
+
ssConstruct(node, { group: group2, method, password, port, remark, server });
|
|
3362
3725
|
} else {
|
|
3363
3726
|
ssrConstruct(node, {
|
|
3364
|
-
group,
|
|
3727
|
+
group: group2,
|
|
3365
3728
|
method,
|
|
3366
3729
|
obfs,
|
|
3367
3730
|
obfsParam: asString(entry.obfsparam),
|
|
@@ -3667,7 +4030,7 @@ function explodeQuan(quan, node) {
|
|
|
3667
4030
|
}
|
|
3668
4031
|
const cipher = trim(configs[4]);
|
|
3669
4032
|
const id = trim(configs[5].replace(/"/g, ""));
|
|
3670
|
-
let
|
|
4033
|
+
let group2 = DEFAULT_GROUPS.v2ray;
|
|
3671
4034
|
let tls = "";
|
|
3672
4035
|
let host = "";
|
|
3673
4036
|
let path = "";
|
|
@@ -3682,7 +4045,7 @@ function explodeQuan(quan, node) {
|
|
|
3682
4045
|
const itemVal = trim(vArray.slice(1).join("="));
|
|
3683
4046
|
switch (itemName) {
|
|
3684
4047
|
case "group":
|
|
3685
|
-
|
|
4048
|
+
group2 = itemVal;
|
|
3686
4049
|
break;
|
|
3687
4050
|
case "over-tls":
|
|
3688
4051
|
tls = itemVal === "true" ? "tls" : "";
|
|
@@ -3721,7 +4084,7 @@ function explodeQuan(quan, node) {
|
|
|
3721
4084
|
aid: "0",
|
|
3722
4085
|
cipher,
|
|
3723
4086
|
edge,
|
|
3724
|
-
group,
|
|
4087
|
+
group: group2,
|
|
3725
4088
|
host,
|
|
3726
4089
|
id,
|
|
3727
4090
|
net,
|
|
@@ -3734,12 +4097,12 @@ function explodeQuan(quan, node) {
|
|
|
3734
4097
|
}
|
|
3735
4098
|
function explodeSs(ss, node) {
|
|
3736
4099
|
let body = ss.slice(5).replace(/\/\?/g, "?");
|
|
3737
|
-
const
|
|
4100
|
+
const group2 = DEFAULT_GROUPS.ss;
|
|
3738
4101
|
let remark = "";
|
|
3739
4102
|
let addition = "";
|
|
3740
4103
|
let plugin = "";
|
|
3741
4104
|
let pluginOption = "";
|
|
3742
|
-
let resolvedGroup =
|
|
4105
|
+
let resolvedGroup = group2;
|
|
3743
4106
|
const hashPos = body.indexOf("#");
|
|
3744
4107
|
if (hashPos !== -1) {
|
|
3745
4108
|
remark = urlDecode(body.slice(hashPos + 1));
|
|
@@ -3806,7 +4169,7 @@ function explodeSs(ss, node) {
|
|
|
3806
4169
|
function explodeSsr(ssr, node) {
|
|
3807
4170
|
let body = ssr.slice(6).replace(/\r/g, "");
|
|
3808
4171
|
body = urlSafeBase64Decode(body);
|
|
3809
|
-
let
|
|
4172
|
+
let group2 = "";
|
|
3810
4173
|
let remark = "";
|
|
3811
4174
|
let obfsParam = "";
|
|
3812
4175
|
let protocolParam = "";
|
|
@@ -3814,7 +4177,7 @@ function explodeSsr(ssr, node) {
|
|
|
3814
4177
|
if (obfsPos !== -1) {
|
|
3815
4178
|
const strobfs = body.slice(obfsPos + 2);
|
|
3816
4179
|
body = body.slice(0, obfsPos);
|
|
3817
|
-
|
|
4180
|
+
group2 = urlSafeBase64Decode(getUrlArg(strobfs, "group"));
|
|
3818
4181
|
remark = urlSafeBase64Decode(getUrlArg(strobfs, "remarks"));
|
|
3819
4182
|
obfsParam = urlSafeBase64Decode(getUrlArg(strobfs, "obfsparam")).replace(/\s/g, "");
|
|
3820
4183
|
protocolParam = urlSafeBase64Decode(getUrlArg(strobfs, "protoparam")).replace(/\s/g, "");
|
|
@@ -3832,7 +4195,7 @@ function explodeSsr(ssr, node) {
|
|
|
3832
4195
|
if (port === "0") {
|
|
3833
4196
|
return;
|
|
3834
4197
|
}
|
|
3835
|
-
const resolvedGroup =
|
|
4198
|
+
const resolvedGroup = group2 === "" ? DEFAULT_GROUPS.ssr : group2;
|
|
3836
4199
|
const resolvedRemark = remark === "" ? `${server}:${port}` : remark;
|
|
3837
4200
|
if (isFlattenableSsr(method, obfs, protocol)) {
|
|
3838
4201
|
ssConstruct(node, {
|
|
@@ -3870,7 +4233,7 @@ function explodeSsd(link, nodes) {
|
|
|
3870
4233
|
if (data === null || typeof data !== "object" || !("servers" in data)) {
|
|
3871
4234
|
return;
|
|
3872
4235
|
}
|
|
3873
|
-
const
|
|
4236
|
+
const group2 = String(data.airport ?? "");
|
|
3874
4237
|
const servers = data.servers;
|
|
3875
4238
|
let entries;
|
|
3876
4239
|
if (Array.isArray(servers)) {
|
|
@@ -3896,7 +4259,7 @@ function explodeSsd(link, nodes) {
|
|
|
3896
4259
|
const pluginOption = String(entry.plugin_options ?? data.plugin_options ?? "");
|
|
3897
4260
|
const node = createProxy();
|
|
3898
4261
|
ssConstruct(node, {
|
|
3899
|
-
group,
|
|
4262
|
+
group: group2,
|
|
3900
4263
|
method,
|
|
3901
4264
|
password,
|
|
3902
4265
|
plugin,
|
|
@@ -3911,7 +4274,7 @@ function explodeSsd(link, nodes) {
|
|
|
3911
4274
|
}
|
|
3912
4275
|
}
|
|
3913
4276
|
function explodeSocks(link, node) {
|
|
3914
|
-
let
|
|
4277
|
+
let group2 = "";
|
|
3915
4278
|
let remark = "";
|
|
3916
4279
|
let server = "";
|
|
3917
4280
|
let port = "";
|
|
@@ -3950,10 +4313,10 @@ function explodeSocks(link, node) {
|
|
|
3950
4313
|
username = urlDecode(getUrlArg(link, "user"));
|
|
3951
4314
|
password = urlDecode(getUrlArg(link, "pass"));
|
|
3952
4315
|
remark = urlDecode(getUrlArg(link, "remarks"));
|
|
3953
|
-
|
|
4316
|
+
group2 = urlDecode(getUrlArg(link, "group"));
|
|
3954
4317
|
}
|
|
3955
|
-
if (
|
|
3956
|
-
|
|
4318
|
+
if (group2 === "") {
|
|
4319
|
+
group2 = DEFAULT_GROUPS.socks;
|
|
3957
4320
|
}
|
|
3958
4321
|
if (remark === "") {
|
|
3959
4322
|
remark = `${server}:${port}`;
|
|
@@ -3961,7 +4324,7 @@ function explodeSocks(link, node) {
|
|
|
3961
4324
|
if (port === "0" || port === "") {
|
|
3962
4325
|
return;
|
|
3963
4326
|
}
|
|
3964
|
-
socksConstruct(node, { group, password, port, remark, server, username });
|
|
4327
|
+
socksConstruct(node, { group: group2, password, port, remark, server, username });
|
|
3965
4328
|
}
|
|
3966
4329
|
function explodeHttp(link, node) {
|
|
3967
4330
|
const server = getUrlArg(link, "server");
|
|
@@ -3969,9 +4332,9 @@ function explodeHttp(link, node) {
|
|
|
3969
4332
|
const username = urlDecode(getUrlArg(link, "user"));
|
|
3970
4333
|
const password = urlDecode(getUrlArg(link, "pass"));
|
|
3971
4334
|
let remark = urlDecode(getUrlArg(link, "remarks"));
|
|
3972
|
-
let
|
|
3973
|
-
if (
|
|
3974
|
-
|
|
4335
|
+
let group2 = urlDecode(getUrlArg(link, "group"));
|
|
4336
|
+
if (group2 === "") {
|
|
4337
|
+
group2 = DEFAULT_GROUPS.http;
|
|
3975
4338
|
}
|
|
3976
4339
|
if (remark === "") {
|
|
3977
4340
|
remark = `${server}:${port}`;
|
|
@@ -3980,7 +4343,7 @@ function explodeHttp(link, node) {
|
|
|
3980
4343
|
return;
|
|
3981
4344
|
}
|
|
3982
4345
|
httpConstruct(node, {
|
|
3983
|
-
group,
|
|
4346
|
+
group: group2,
|
|
3984
4347
|
password,
|
|
3985
4348
|
port,
|
|
3986
4349
|
remark,
|
|
@@ -3992,14 +4355,14 @@ function explodeHttp(link, node) {
|
|
|
3992
4355
|
function explodeHttpSub(link, node) {
|
|
3993
4356
|
let body = link;
|
|
3994
4357
|
let remarks = "";
|
|
3995
|
-
let
|
|
4358
|
+
let group2 = "";
|
|
3996
4359
|
const tls = body.includes("https://");
|
|
3997
4360
|
const qpos = body.indexOf("?");
|
|
3998
4361
|
if (qpos !== -1) {
|
|
3999
4362
|
const addition = body.slice(qpos + 1);
|
|
4000
4363
|
body = body.slice(0, qpos);
|
|
4001
4364
|
remarks = urlDecode(getUrlArg(addition, "remarks"));
|
|
4002
|
-
|
|
4365
|
+
group2 = urlDecode(getUrlArg(addition, "group"));
|
|
4003
4366
|
}
|
|
4004
4367
|
body = body.slice(body.indexOf("://") + 3);
|
|
4005
4368
|
body = urlSafeBase64Decode(body);
|
|
@@ -4024,8 +4387,8 @@ function explodeHttpSub(link, node) {
|
|
|
4024
4387
|
server = match[1];
|
|
4025
4388
|
port = match[2];
|
|
4026
4389
|
}
|
|
4027
|
-
if (
|
|
4028
|
-
|
|
4390
|
+
if (group2 === "") {
|
|
4391
|
+
group2 = DEFAULT_GROUPS.http;
|
|
4029
4392
|
}
|
|
4030
4393
|
if (remarks === "") {
|
|
4031
4394
|
remarks = `${server}:${port}`;
|
|
@@ -4034,7 +4397,7 @@ function explodeHttpSub(link, node) {
|
|
|
4034
4397
|
return;
|
|
4035
4398
|
}
|
|
4036
4399
|
httpConstruct(node, {
|
|
4037
|
-
group,
|
|
4400
|
+
group: group2,
|
|
4038
4401
|
password,
|
|
4039
4402
|
port,
|
|
4040
4403
|
remark: remarks,
|
|
@@ -4075,7 +4438,7 @@ function explodeTrojan(trojan, node) {
|
|
|
4075
4438
|
host = getUrlArg(addition, "peer");
|
|
4076
4439
|
}
|
|
4077
4440
|
const tfo = getUrlArg(addition, "tfo");
|
|
4078
|
-
const
|
|
4441
|
+
const group2 = urlDecode(getUrlArg(addition, "group"));
|
|
4079
4442
|
if (getUrlArg(addition, "ws") === "1") {
|
|
4080
4443
|
path = getUrlArg(addition, "wspath");
|
|
4081
4444
|
network = "ws";
|
|
@@ -4093,7 +4456,7 @@ function explodeTrojan(trojan, node) {
|
|
|
4093
4456
|
remark = `${server}:${port}`;
|
|
4094
4457
|
}
|
|
4095
4458
|
trojanConstruct(node, {
|
|
4096
|
-
group:
|
|
4459
|
+
group: group2 === "" ? DEFAULT_GROUPS.trojan : group2,
|
|
4097
4460
|
host,
|
|
4098
4461
|
network,
|
|
4099
4462
|
password,
|
|
@@ -4262,10 +4625,14 @@ function explodeVless(link, node) {
|
|
|
4262
4625
|
const network = getUrlArg(addition, "type");
|
|
4263
4626
|
const security = getUrlArg(addition, "security");
|
|
4264
4627
|
const host = getUrlArg(addition, "host");
|
|
4265
|
-
const
|
|
4628
|
+
const rawPath = urlDecode(getUrlArg(addition, "path"));
|
|
4629
|
+
const serviceName = urlDecode(getUrlArg(addition, "serviceName"));
|
|
4630
|
+
const path = rawPath !== "" ? rawPath : serviceName;
|
|
4266
4631
|
const sni = getUrlArg(addition, "sni");
|
|
4267
4632
|
const flow = getUrlArg(addition, "flow");
|
|
4268
4633
|
const fingerprint = getUrlArg(addition, "fp");
|
|
4634
|
+
const publicKey = getUrlArg(addition, "pbk");
|
|
4635
|
+
const shortId = getUrlArg(addition, "sid");
|
|
4269
4636
|
const alpn = getUrlArg(addition, "alpn");
|
|
4270
4637
|
if (remark === "") {
|
|
4271
4638
|
remark = `${server}:${port}`;
|
|
@@ -4279,9 +4646,11 @@ function explodeVless(link, node) {
|
|
|
4279
4646
|
network,
|
|
4280
4647
|
path,
|
|
4281
4648
|
port,
|
|
4649
|
+
publicKey,
|
|
4282
4650
|
remark,
|
|
4283
4651
|
scv: getUrlArg(addition, "allowInsecure") === "" ? void 0 : parseTri(getUrlArg(addition, "allowInsecure")),
|
|
4284
4652
|
server,
|
|
4653
|
+
shortId,
|
|
4285
4654
|
sni,
|
|
4286
4655
|
tls: security,
|
|
4287
4656
|
userId
|
|
@@ -4422,6 +4791,425 @@ function parseSubscription(content) {
|
|
|
4422
4791
|
// src/generator/clash.ts
|
|
4423
4792
|
var import_yaml2 = require("yaml");
|
|
4424
4793
|
|
|
4794
|
+
// src/utils/country.ts
|
|
4795
|
+
var REGION_CODES = [
|
|
4796
|
+
"AD",
|
|
4797
|
+
"AE",
|
|
4798
|
+
"AF",
|
|
4799
|
+
"AG",
|
|
4800
|
+
"AI",
|
|
4801
|
+
"AL",
|
|
4802
|
+
"AM",
|
|
4803
|
+
"AO",
|
|
4804
|
+
"AQ",
|
|
4805
|
+
"AR",
|
|
4806
|
+
"AS",
|
|
4807
|
+
"AT",
|
|
4808
|
+
"AU",
|
|
4809
|
+
"AW",
|
|
4810
|
+
"AX",
|
|
4811
|
+
"AZ",
|
|
4812
|
+
"BA",
|
|
4813
|
+
"BB",
|
|
4814
|
+
"BD",
|
|
4815
|
+
"BE",
|
|
4816
|
+
"BF",
|
|
4817
|
+
"BG",
|
|
4818
|
+
"BH",
|
|
4819
|
+
"BI",
|
|
4820
|
+
"BJ",
|
|
4821
|
+
"BL",
|
|
4822
|
+
"BM",
|
|
4823
|
+
"BN",
|
|
4824
|
+
"BO",
|
|
4825
|
+
"BQ",
|
|
4826
|
+
"BR",
|
|
4827
|
+
"BS",
|
|
4828
|
+
"BT",
|
|
4829
|
+
"BV",
|
|
4830
|
+
"BW",
|
|
4831
|
+
"BY",
|
|
4832
|
+
"BZ",
|
|
4833
|
+
"CA",
|
|
4834
|
+
"CC",
|
|
4835
|
+
"CD",
|
|
4836
|
+
"CF",
|
|
4837
|
+
"CG",
|
|
4838
|
+
"CH",
|
|
4839
|
+
"CI",
|
|
4840
|
+
"CK",
|
|
4841
|
+
"CL",
|
|
4842
|
+
"CM",
|
|
4843
|
+
"CN",
|
|
4844
|
+
"CO",
|
|
4845
|
+
"CR",
|
|
4846
|
+
"CU",
|
|
4847
|
+
"CV",
|
|
4848
|
+
"CW",
|
|
4849
|
+
"CX",
|
|
4850
|
+
"CY",
|
|
4851
|
+
"CZ",
|
|
4852
|
+
"DE",
|
|
4853
|
+
"DJ",
|
|
4854
|
+
"DK",
|
|
4855
|
+
"DM",
|
|
4856
|
+
"DO",
|
|
4857
|
+
"DZ",
|
|
4858
|
+
"EC",
|
|
4859
|
+
"EE",
|
|
4860
|
+
"EG",
|
|
4861
|
+
"EH",
|
|
4862
|
+
"ER",
|
|
4863
|
+
"ES",
|
|
4864
|
+
"ET",
|
|
4865
|
+
"FI",
|
|
4866
|
+
"FJ",
|
|
4867
|
+
"FK",
|
|
4868
|
+
"FM",
|
|
4869
|
+
"FO",
|
|
4870
|
+
"FR",
|
|
4871
|
+
"GA",
|
|
4872
|
+
"GB",
|
|
4873
|
+
"GD",
|
|
4874
|
+
"GE",
|
|
4875
|
+
"GF",
|
|
4876
|
+
"GG",
|
|
4877
|
+
"GH",
|
|
4878
|
+
"GI",
|
|
4879
|
+
"GL",
|
|
4880
|
+
"GM",
|
|
4881
|
+
"GN",
|
|
4882
|
+
"GP",
|
|
4883
|
+
"GQ",
|
|
4884
|
+
"GR",
|
|
4885
|
+
"GS",
|
|
4886
|
+
"GT",
|
|
4887
|
+
"GU",
|
|
4888
|
+
"GW",
|
|
4889
|
+
"GY",
|
|
4890
|
+
"HK",
|
|
4891
|
+
"HM",
|
|
4892
|
+
"HN",
|
|
4893
|
+
"HR",
|
|
4894
|
+
"HT",
|
|
4895
|
+
"HU",
|
|
4896
|
+
"ID",
|
|
4897
|
+
"IE",
|
|
4898
|
+
"IL",
|
|
4899
|
+
"IM",
|
|
4900
|
+
"IN",
|
|
4901
|
+
"IO",
|
|
4902
|
+
"IQ",
|
|
4903
|
+
"IR",
|
|
4904
|
+
"IS",
|
|
4905
|
+
"IT",
|
|
4906
|
+
"JE",
|
|
4907
|
+
"JM",
|
|
4908
|
+
"JO",
|
|
4909
|
+
"JP",
|
|
4910
|
+
"KE",
|
|
4911
|
+
"KG",
|
|
4912
|
+
"KH",
|
|
4913
|
+
"KI",
|
|
4914
|
+
"KM",
|
|
4915
|
+
"KN",
|
|
4916
|
+
"KP",
|
|
4917
|
+
"KR",
|
|
4918
|
+
"KW",
|
|
4919
|
+
"KY",
|
|
4920
|
+
"KZ",
|
|
4921
|
+
"LA",
|
|
4922
|
+
"LB",
|
|
4923
|
+
"LC",
|
|
4924
|
+
"LI",
|
|
4925
|
+
"LK",
|
|
4926
|
+
"LR",
|
|
4927
|
+
"LS",
|
|
4928
|
+
"LT",
|
|
4929
|
+
"LU",
|
|
4930
|
+
"LV",
|
|
4931
|
+
"LY",
|
|
4932
|
+
"MA",
|
|
4933
|
+
"MC",
|
|
4934
|
+
"MD",
|
|
4935
|
+
"ME",
|
|
4936
|
+
"MF",
|
|
4937
|
+
"MG",
|
|
4938
|
+
"MH",
|
|
4939
|
+
"MK",
|
|
4940
|
+
"ML",
|
|
4941
|
+
"MM",
|
|
4942
|
+
"MN",
|
|
4943
|
+
"MO",
|
|
4944
|
+
"MP",
|
|
4945
|
+
"MQ",
|
|
4946
|
+
"MR",
|
|
4947
|
+
"MS",
|
|
4948
|
+
"MT",
|
|
4949
|
+
"MU",
|
|
4950
|
+
"MV",
|
|
4951
|
+
"MW",
|
|
4952
|
+
"MX",
|
|
4953
|
+
"MY",
|
|
4954
|
+
"MZ",
|
|
4955
|
+
"NA",
|
|
4956
|
+
"NC",
|
|
4957
|
+
"NE",
|
|
4958
|
+
"NF",
|
|
4959
|
+
"NG",
|
|
4960
|
+
"NI",
|
|
4961
|
+
"NL",
|
|
4962
|
+
"NO",
|
|
4963
|
+
"NP",
|
|
4964
|
+
"NR",
|
|
4965
|
+
"NU",
|
|
4966
|
+
"NZ",
|
|
4967
|
+
"OM",
|
|
4968
|
+
"PA",
|
|
4969
|
+
"PE",
|
|
4970
|
+
"PF",
|
|
4971
|
+
"PG",
|
|
4972
|
+
"PH",
|
|
4973
|
+
"PK",
|
|
4974
|
+
"PL",
|
|
4975
|
+
"PM",
|
|
4976
|
+
"PN",
|
|
4977
|
+
"PR",
|
|
4978
|
+
"PS",
|
|
4979
|
+
"PT",
|
|
4980
|
+
"PW",
|
|
4981
|
+
"PY",
|
|
4982
|
+
"QA",
|
|
4983
|
+
"RE",
|
|
4984
|
+
"RO",
|
|
4985
|
+
"RS",
|
|
4986
|
+
"RU",
|
|
4987
|
+
"RW",
|
|
4988
|
+
"SA",
|
|
4989
|
+
"SB",
|
|
4990
|
+
"SC",
|
|
4991
|
+
"SD",
|
|
4992
|
+
"SE",
|
|
4993
|
+
"SG",
|
|
4994
|
+
"SH",
|
|
4995
|
+
"SI",
|
|
4996
|
+
"SJ",
|
|
4997
|
+
"SK",
|
|
4998
|
+
"SL",
|
|
4999
|
+
"SM",
|
|
5000
|
+
"SN",
|
|
5001
|
+
"SO",
|
|
5002
|
+
"SR",
|
|
5003
|
+
"SS",
|
|
5004
|
+
"ST",
|
|
5005
|
+
"SV",
|
|
5006
|
+
"SX",
|
|
5007
|
+
"SY",
|
|
5008
|
+
"SZ",
|
|
5009
|
+
"TC",
|
|
5010
|
+
"TD",
|
|
5011
|
+
"TF",
|
|
5012
|
+
"TG",
|
|
5013
|
+
"TH",
|
|
5014
|
+
"TJ",
|
|
5015
|
+
"TK",
|
|
5016
|
+
"TL",
|
|
5017
|
+
"TM",
|
|
5018
|
+
"TN",
|
|
5019
|
+
"TO",
|
|
5020
|
+
"TR",
|
|
5021
|
+
"TT",
|
|
5022
|
+
"TV",
|
|
5023
|
+
"TW",
|
|
5024
|
+
"TZ",
|
|
5025
|
+
"UA",
|
|
5026
|
+
"UG",
|
|
5027
|
+
"UM",
|
|
5028
|
+
"US",
|
|
5029
|
+
"UY",
|
|
5030
|
+
"UZ",
|
|
5031
|
+
"VA",
|
|
5032
|
+
"VC",
|
|
5033
|
+
"VE",
|
|
5034
|
+
"VG",
|
|
5035
|
+
"VI",
|
|
5036
|
+
"VN",
|
|
5037
|
+
"VU",
|
|
5038
|
+
"WF",
|
|
5039
|
+
"WS",
|
|
5040
|
+
"YE",
|
|
5041
|
+
"YT",
|
|
5042
|
+
"ZA",
|
|
5043
|
+
"ZM",
|
|
5044
|
+
"ZW"
|
|
5045
|
+
];
|
|
5046
|
+
var REGION_CODE_SET = new Set(REGION_CODES);
|
|
5047
|
+
var ZH_OVERRIDES = {
|
|
5048
|
+
AE: "\u963F\u8054\u914B",
|
|
5049
|
+
BN: "\u6587\u83B1",
|
|
5050
|
+
BO: "\u73BB\u5229\u7EF4\u4E9A",
|
|
5051
|
+
CD: "\u521A\u679C\uFF08\u91D1\uFF09",
|
|
5052
|
+
CG: "\u521A\u679C\uFF08\u5E03\uFF09",
|
|
5053
|
+
CV: "\u4F5B\u5F97\u89D2",
|
|
5054
|
+
CZ: "\u6377\u514B",
|
|
5055
|
+
DO: "\u591A\u7C73\u5C3C\u52A0",
|
|
5056
|
+
HK: "\u9999\u6E2F",
|
|
5057
|
+
KH: "\u67EC\u57D4\u5BE8",
|
|
5058
|
+
KP: "\u671D\u9C9C",
|
|
5059
|
+
KR: "\u97E9\u56FD",
|
|
5060
|
+
LA: "\u8001\u631D",
|
|
5061
|
+
MD: "\u6469\u5C14\u591A\u74E6",
|
|
5062
|
+
MK: "\u5317\u9A6C\u5176\u987F",
|
|
5063
|
+
MM: "\u7F05\u7538",
|
|
5064
|
+
MO: "\u6FB3\u95E8",
|
|
5065
|
+
NL: "\u8377\u5170",
|
|
5066
|
+
PS: "\u5DF4\u52D2\u65AF\u5766",
|
|
5067
|
+
RU: "\u4FC4\u7F57\u65AF",
|
|
5068
|
+
SY: "\u53D9\u5229\u4E9A",
|
|
5069
|
+
SZ: "\u65AF\u5A01\u58EB\u5170",
|
|
5070
|
+
TL: "\u4E1C\u5E1D\u6C76",
|
|
5071
|
+
TW: "\u53F0\u6E7E",
|
|
5072
|
+
TZ: "\u5766\u6851\u5C3C\u4E9A",
|
|
5073
|
+
VA: "\u68B5\u8482\u5188",
|
|
5074
|
+
VE: "\u59D4\u5185\u745E\u62C9"
|
|
5075
|
+
};
|
|
5076
|
+
var EN_OVERRIDES = {
|
|
5077
|
+
HK: "Hong Kong",
|
|
5078
|
+
MO: "Macau",
|
|
5079
|
+
PS: "Palestine",
|
|
5080
|
+
TW: "Taiwan"
|
|
5081
|
+
};
|
|
5082
|
+
var EXTRA_ALIASES = [
|
|
5083
|
+
"Burma",
|
|
5084
|
+
"Cape Verde",
|
|
5085
|
+
"Czechia",
|
|
5086
|
+
"East Timor",
|
|
5087
|
+
"Holland",
|
|
5088
|
+
"Hong Kong",
|
|
5089
|
+
"Macao",
|
|
5090
|
+
"Macau",
|
|
5091
|
+
"North Korea",
|
|
5092
|
+
"South Korea",
|
|
5093
|
+
"UAE",
|
|
5094
|
+
"UK",
|
|
5095
|
+
"USA",
|
|
5096
|
+
"United Kingdom",
|
|
5097
|
+
"United States"
|
|
5098
|
+
];
|
|
5099
|
+
function escapeRegExp(value) {
|
|
5100
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
5101
|
+
}
|
|
5102
|
+
var displayNameCache = /* @__PURE__ */ new Map();
|
|
5103
|
+
function displayNames(locale) {
|
|
5104
|
+
const cached = displayNameCache.get(locale);
|
|
5105
|
+
if (cached) {
|
|
5106
|
+
return cached;
|
|
5107
|
+
}
|
|
5108
|
+
try {
|
|
5109
|
+
const created = new Intl.DisplayNames([locale], { fallback: "code", type: "region" });
|
|
5110
|
+
displayNameCache.set(locale, created);
|
|
5111
|
+
return created;
|
|
5112
|
+
} catch {
|
|
5113
|
+
return void 0;
|
|
5114
|
+
}
|
|
5115
|
+
}
|
|
5116
|
+
function normalizeRegionCode(code) {
|
|
5117
|
+
const upper = code.trim().toUpperCase();
|
|
5118
|
+
return /^[A-Z]{2}$/.test(upper) ? upper : "";
|
|
5119
|
+
}
|
|
5120
|
+
function regionDisplayName(code, locale = "zh-CN") {
|
|
5121
|
+
const upper = normalizeRegionCode(code);
|
|
5122
|
+
if (upper === "") {
|
|
5123
|
+
return code.trim();
|
|
5124
|
+
}
|
|
5125
|
+
if (locale.toLowerCase().startsWith("zh") && ZH_OVERRIDES[upper] !== void 0) {
|
|
5126
|
+
return ZH_OVERRIDES[upper];
|
|
5127
|
+
}
|
|
5128
|
+
if (locale.toLowerCase().startsWith("en") && EN_OVERRIDES[upper] !== void 0) {
|
|
5129
|
+
return EN_OVERRIDES[upper];
|
|
5130
|
+
}
|
|
5131
|
+
const names = displayNames(locale);
|
|
5132
|
+
return names?.of(upper) ?? upper;
|
|
5133
|
+
}
|
|
5134
|
+
function regionFlag(code) {
|
|
5135
|
+
const upper = normalizeRegionCode(code);
|
|
5136
|
+
if (upper === "") {
|
|
5137
|
+
return "";
|
|
5138
|
+
}
|
|
5139
|
+
const base = 127462;
|
|
5140
|
+
return String.fromCodePoint(base + upper.charCodeAt(0) - 65, base + upper.charCodeAt(1) - 65);
|
|
5141
|
+
}
|
|
5142
|
+
function isRegionCode(code) {
|
|
5143
|
+
return REGION_CODE_SET.has(normalizeRegionCode(code));
|
|
5144
|
+
}
|
|
5145
|
+
var aliasRegex;
|
|
5146
|
+
function buildAliasRegex() {
|
|
5147
|
+
const ascii = [];
|
|
5148
|
+
const other = [];
|
|
5149
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5150
|
+
const add = (alias) => {
|
|
5151
|
+
const trimmed = alias.trim();
|
|
5152
|
+
if (trimmed.length < 2 || seen.has(trimmed)) {
|
|
5153
|
+
return;
|
|
5154
|
+
}
|
|
5155
|
+
seen.add(trimmed);
|
|
5156
|
+
if (/^[\x20-\x7e]+$/.test(trimmed)) {
|
|
5157
|
+
ascii.push(escapeRegExp(trimmed));
|
|
5158
|
+
} else {
|
|
5159
|
+
other.push(escapeRegExp(trimmed));
|
|
5160
|
+
}
|
|
5161
|
+
};
|
|
5162
|
+
for (const code of REGION_CODES) {
|
|
5163
|
+
add(regionDisplayName(code, "zh-CN"));
|
|
5164
|
+
add(regionDisplayName(code, "en"));
|
|
5165
|
+
add(regionFlag(code));
|
|
5166
|
+
}
|
|
5167
|
+
for (const alias of EXTRA_ALIASES) {
|
|
5168
|
+
add(alias);
|
|
5169
|
+
}
|
|
5170
|
+
const parts = [];
|
|
5171
|
+
if (ascii.length > 0) {
|
|
5172
|
+
parts.push(`(?<![A-Za-z])(?:${ascii.join("|")})(?![A-Za-z])`);
|
|
5173
|
+
}
|
|
5174
|
+
if (other.length > 0) {
|
|
5175
|
+
parts.push(`(?:${other.join("|")})`);
|
|
5176
|
+
}
|
|
5177
|
+
return new RegExp(parts.join("|"), "iu");
|
|
5178
|
+
}
|
|
5179
|
+
function getAliasRegex() {
|
|
5180
|
+
aliasRegex ??= buildAliasRegex();
|
|
5181
|
+
return aliasRegex;
|
|
5182
|
+
}
|
|
5183
|
+
function hasRegionName(remark) {
|
|
5184
|
+
const text = remark.trim();
|
|
5185
|
+
if (text === "") {
|
|
5186
|
+
return false;
|
|
5187
|
+
}
|
|
5188
|
+
if (getAliasRegex().test(text)) {
|
|
5189
|
+
return true;
|
|
5190
|
+
}
|
|
5191
|
+
for (const token of text.split(/[^\p{L}\p{N}]+/u)) {
|
|
5192
|
+
if (token === "") {
|
|
5193
|
+
continue;
|
|
5194
|
+
}
|
|
5195
|
+
if (/^\p{Lu}{2}$/u.test(token) && isRegionCode(token)) {
|
|
5196
|
+
return true;
|
|
5197
|
+
}
|
|
5198
|
+
if (/^[A-Za-z]{2}\d{2}/.test(token) && isRegionCode(token.slice(0, 2))) {
|
|
5199
|
+
return true;
|
|
5200
|
+
}
|
|
5201
|
+
}
|
|
5202
|
+
return false;
|
|
5203
|
+
}
|
|
5204
|
+
function formatCountryRemark(remark, code, locale = "zh-CN") {
|
|
5205
|
+
const name = regionDisplayName(code, locale);
|
|
5206
|
+
const trimmed = remark.trim();
|
|
5207
|
+
if (name === "") {
|
|
5208
|
+
return trimmed;
|
|
5209
|
+
}
|
|
5210
|
+
return trimmed === "" ? name : `${name}-${trimmed}`;
|
|
5211
|
+
}
|
|
5212
|
+
|
|
4425
5213
|
// src/generator/nodes.ts
|
|
4426
5214
|
function toRegex(pattern) {
|
|
4427
5215
|
try {
|
|
@@ -4630,6 +5418,39 @@ function addEmoji(node, emojiArray) {
|
|
|
4630
5418
|
}
|
|
4631
5419
|
return node.remark;
|
|
4632
5420
|
}
|
|
5421
|
+
function nodeNameRegex(node, rules) {
|
|
5422
|
+
const original = node.remark;
|
|
5423
|
+
for (const rule of rules) {
|
|
5424
|
+
if (rule.script !== "" || rule.match === "") {
|
|
5425
|
+
continue;
|
|
5426
|
+
}
|
|
5427
|
+
try {
|
|
5428
|
+
node.remark = node.remark.replace(new RegExp(rule.match, "g"), rule.replace);
|
|
5429
|
+
} catch {
|
|
5430
|
+
}
|
|
5431
|
+
}
|
|
5432
|
+
if (node.remark === "") {
|
|
5433
|
+
node.remark = original;
|
|
5434
|
+
}
|
|
5435
|
+
}
|
|
5436
|
+
var NAME_SEPARATOR_EDGES = /^[-_.\s]+|[-_.\s]+$/g;
|
|
5437
|
+
var NAME_SEPARATOR_RUN = /([-_.\s])[-_.\s]+/g;
|
|
5438
|
+
function nodeNameRemove(node, removeList) {
|
|
5439
|
+
const original = node.remark;
|
|
5440
|
+
let remark = node.remark;
|
|
5441
|
+
let removed = false;
|
|
5442
|
+
for (const fragment of removeList) {
|
|
5443
|
+
if (fragment === "" || !remark.includes(fragment)) {
|
|
5444
|
+
continue;
|
|
5445
|
+
}
|
|
5446
|
+
remark = remark.split(fragment).join("");
|
|
5447
|
+
removed = true;
|
|
5448
|
+
}
|
|
5449
|
+
if (removed) {
|
|
5450
|
+
remark = remark.replace(NAME_SEPARATOR_EDGES, "").replace(NAME_SEPARATOR_RUN, "$1");
|
|
5451
|
+
}
|
|
5452
|
+
node.remark = remark === "" ? original : remark;
|
|
5453
|
+
}
|
|
4633
5454
|
function nodeRename(node, renameArray) {
|
|
4634
5455
|
const original = node.remark;
|
|
4635
5456
|
for (const rule of renameArray) {
|
|
@@ -4645,15 +5466,39 @@ function nodeRename(node, renameArray) {
|
|
|
4645
5466
|
node.remark = original;
|
|
4646
5467
|
}
|
|
4647
5468
|
}
|
|
5469
|
+
function addCountryPrefix(node, resolve, locale = "zh-CN") {
|
|
5470
|
+
const remark = node.remark.trim();
|
|
5471
|
+
if (hasRegionName(remark)) {
|
|
5472
|
+
return node.remark;
|
|
5473
|
+
}
|
|
5474
|
+
const code = resolve(node);
|
|
5475
|
+
if (code === void 0 || code === "") {
|
|
5476
|
+
return node.remark;
|
|
5477
|
+
}
|
|
5478
|
+
return formatCountryRemark(remark, code, locale);
|
|
5479
|
+
}
|
|
4648
5480
|
function preprocessNodes(nodes, options) {
|
|
4649
5481
|
for (const node of nodes) {
|
|
4650
5482
|
if (options.removeEmoji) {
|
|
4651
5483
|
node.remark = removeEmoji(node.remark).trim();
|
|
4652
5484
|
}
|
|
5485
|
+
if (options.nameRegexArray && options.nameRegexArray.length > 0) {
|
|
5486
|
+
nodeNameRegex(node, options.nameRegexArray);
|
|
5487
|
+
}
|
|
5488
|
+
if (options.nameRemove && options.nameRemove.length > 0) {
|
|
5489
|
+
nodeNameRemove(node, options.nameRemove);
|
|
5490
|
+
}
|
|
4653
5491
|
nodeRename(node, options.renameArray);
|
|
4654
5492
|
if (options.addEmoji) {
|
|
4655
5493
|
node.remark = addEmoji(node, options.emojiArray);
|
|
4656
5494
|
}
|
|
5495
|
+
if (options.autoCountry && options.countryResolver) {
|
|
5496
|
+
node.remark = addCountryPrefix(
|
|
5497
|
+
node,
|
|
5498
|
+
options.countryResolver,
|
|
5499
|
+
options.countryLocale ?? "zh-CN"
|
|
5500
|
+
);
|
|
5501
|
+
}
|
|
4657
5502
|
}
|
|
4658
5503
|
if (options.sortFlag) {
|
|
4659
5504
|
nodes.sort((a, b) => a.remark < b.remark ? -1 : a.remark > b.remark ? 1 : 0);
|
|
@@ -5063,6 +5908,14 @@ function buildClashProxy(x, settings, clashR, remark, skipCertVerify, tfo) {
|
|
|
5063
5908
|
if (x.fingerprint !== "") {
|
|
5064
5909
|
proxy["client-fingerprint"] = x.fingerprint;
|
|
5065
5910
|
}
|
|
5911
|
+
if (x.publicKey !== "" || x.shortId !== "") {
|
|
5912
|
+
const realityOpts = {};
|
|
5913
|
+
if (x.publicKey !== "") {
|
|
5914
|
+
realityOpts["public-key"] = x.publicKey;
|
|
5915
|
+
}
|
|
5916
|
+
realityOpts["short-id"] = x.shortId;
|
|
5917
|
+
proxy["reality-opts"] = realityOpts;
|
|
5918
|
+
}
|
|
5066
5919
|
if (x.alpn.length > 0) {
|
|
5067
5920
|
proxy.alpn = x.alpn;
|
|
5068
5921
|
}
|
|
@@ -5146,60 +5999,60 @@ function buildClash(nodes, extraProxyGroup, settings, clashR = false) {
|
|
|
5146
5999
|
return { doc: { proxies }, nodeList };
|
|
5147
6000
|
}
|
|
5148
6001
|
const groups = [];
|
|
5149
|
-
for (const
|
|
6002
|
+
for (const group2 of extraProxyGroup) {
|
|
5150
6003
|
const singlegroup = {
|
|
5151
|
-
name:
|
|
5152
|
-
type:
|
|
6004
|
+
name: group2.name,
|
|
6005
|
+
type: group2.type === "smart" ? "url-test" : group2.type
|
|
5153
6006
|
};
|
|
5154
|
-
switch (
|
|
6007
|
+
switch (group2.type) {
|
|
5155
6008
|
case "select":
|
|
5156
6009
|
case "relay":
|
|
5157
6010
|
break;
|
|
5158
6011
|
case "load-balance":
|
|
5159
|
-
singlegroup.strategy =
|
|
5160
|
-
singlegroup.lazy =
|
|
5161
|
-
singlegroup.url =
|
|
5162
|
-
if (
|
|
5163
|
-
singlegroup.interval =
|
|
6012
|
+
singlegroup.strategy = group2.strategy;
|
|
6013
|
+
singlegroup.lazy = group2.lazy;
|
|
6014
|
+
singlegroup.url = group2.url;
|
|
6015
|
+
if (group2.interval > 0) {
|
|
6016
|
+
singlegroup.interval = group2.interval;
|
|
5164
6017
|
}
|
|
5165
|
-
if (
|
|
5166
|
-
singlegroup.tolerance =
|
|
6018
|
+
if (group2.tolerance > 0) {
|
|
6019
|
+
singlegroup.tolerance = group2.tolerance;
|
|
5167
6020
|
}
|
|
5168
6021
|
break;
|
|
5169
6022
|
case "smart":
|
|
5170
6023
|
case "url-test":
|
|
5171
|
-
if (
|
|
5172
|
-
singlegroup.lazy =
|
|
6024
|
+
if (group2.lazy !== void 0) {
|
|
6025
|
+
singlegroup.lazy = group2.lazy;
|
|
5173
6026
|
}
|
|
5174
|
-
singlegroup.url =
|
|
5175
|
-
if (
|
|
5176
|
-
singlegroup.interval =
|
|
6027
|
+
singlegroup.url = group2.url;
|
|
6028
|
+
if (group2.interval > 0) {
|
|
6029
|
+
singlegroup.interval = group2.interval;
|
|
5177
6030
|
}
|
|
5178
|
-
if (
|
|
5179
|
-
singlegroup.tolerance =
|
|
6031
|
+
if (group2.tolerance > 0) {
|
|
6032
|
+
singlegroup.tolerance = group2.tolerance;
|
|
5180
6033
|
}
|
|
5181
6034
|
break;
|
|
5182
6035
|
case "fallback":
|
|
5183
|
-
singlegroup.url =
|
|
5184
|
-
if (
|
|
5185
|
-
singlegroup.interval =
|
|
6036
|
+
singlegroup.url = group2.url;
|
|
6037
|
+
if (group2.interval > 0) {
|
|
6038
|
+
singlegroup.interval = group2.interval;
|
|
5186
6039
|
}
|
|
5187
|
-
if (
|
|
5188
|
-
singlegroup.tolerance =
|
|
6040
|
+
if (group2.tolerance > 0) {
|
|
6041
|
+
singlegroup.tolerance = group2.tolerance;
|
|
5189
6042
|
}
|
|
5190
6043
|
break;
|
|
5191
6044
|
default:
|
|
5192
6045
|
continue;
|
|
5193
6046
|
}
|
|
5194
|
-
if (
|
|
5195
|
-
singlegroup["disable-udp"] =
|
|
6047
|
+
if (group2.disableUdp !== void 0) {
|
|
6048
|
+
singlegroup["disable-udp"] = group2.disableUdp;
|
|
5196
6049
|
}
|
|
5197
6050
|
const filtered = [];
|
|
5198
|
-
for (const rule of
|
|
6051
|
+
for (const rule of group2.proxies) {
|
|
5199
6052
|
groupGenerate(rule, nodeList, filtered, true);
|
|
5200
6053
|
}
|
|
5201
|
-
if (
|
|
5202
|
-
singlegroup.use =
|
|
6054
|
+
if (group2.usingProvider.length > 0) {
|
|
6055
|
+
singlegroup.use = group2.usingProvider;
|
|
5203
6056
|
} else {
|
|
5204
6057
|
if (filtered.length === 0) {
|
|
5205
6058
|
filtered.push("DIRECT");
|
|
@@ -5233,6 +6086,162 @@ function toClash(nodes, extraProxyGroup, settings, clashR = false) {
|
|
|
5233
6086
|
return stringifyClash(doc);
|
|
5234
6087
|
}
|
|
5235
6088
|
|
|
6089
|
+
// src/generator/default-profile.ts
|
|
6090
|
+
var TEST_URL = "http://www.gstatic.com/generate_204";
|
|
6091
|
+
function group(name, type, proxies, extra = {}) {
|
|
6092
|
+
return {
|
|
6093
|
+
disableUdp: void 0,
|
|
6094
|
+
evaluateBeforeUse: void 0,
|
|
6095
|
+
interval: 0,
|
|
6096
|
+
lazy: void 0,
|
|
6097
|
+
name,
|
|
6098
|
+
persistent: void 0,
|
|
6099
|
+
proxies: [...proxies],
|
|
6100
|
+
strategy: "consistent-hashing" /* ConsistentHashing */,
|
|
6101
|
+
timeout: 5,
|
|
6102
|
+
tolerance: 0,
|
|
6103
|
+
type,
|
|
6104
|
+
url: "",
|
|
6105
|
+
usingProvider: [],
|
|
6106
|
+
...extra
|
|
6107
|
+
};
|
|
6108
|
+
}
|
|
6109
|
+
function getDefaultProxyGroups() {
|
|
6110
|
+
return [
|
|
6111
|
+
group("\u{1F680} \u8282\u70B9\u9009\u62E9", "select" /* Select */, ["[]\u267B\uFE0F \u81EA\u52A8\u9009\u62E9", "[]DIRECT", ".*"]),
|
|
6112
|
+
group("\u267B\uFE0F \u81EA\u52A8\u9009\u62E9", "url-test" /* URLTest */, [".*"], {
|
|
6113
|
+
interval: 300,
|
|
6114
|
+
tolerance: 50,
|
|
6115
|
+
url: TEST_URL
|
|
6116
|
+
}),
|
|
6117
|
+
group("\u{1F30D} \u56FD\u5916\u5A92\u4F53", "select" /* Select */, [
|
|
6118
|
+
"[]\u{1F680} \u8282\u70B9\u9009\u62E9",
|
|
6119
|
+
"[]\u267B\uFE0F \u81EA\u52A8\u9009\u62E9",
|
|
6120
|
+
"[]\u{1F3AF} \u5168\u7403\u76F4\u8FDE",
|
|
6121
|
+
".*"
|
|
6122
|
+
]),
|
|
6123
|
+
group("\u{1F4F2} \u7535\u62A5\u4FE1\u606F", "select" /* Select */, ["[]\u{1F680} \u8282\u70B9\u9009\u62E9", "[]\u{1F3AF} \u5168\u7403\u76F4\u8FDE", ".*"]),
|
|
6124
|
+
group("\u24C2\uFE0F \u5FAE\u8F6F\u670D\u52A1", "select" /* Select */, ["[]\u{1F3AF} \u5168\u7403\u76F4\u8FDE", "[]\u{1F680} \u8282\u70B9\u9009\u62E9", ".*"]),
|
|
6125
|
+
group("\u{1F34E} \u82F9\u679C\u670D\u52A1", "select" /* Select */, ["[]\u{1F680} \u8282\u70B9\u9009\u62E9", "[]\u{1F3AF} \u5168\u7403\u76F4\u8FDE", ".*"]),
|
|
6126
|
+
group("\u{1F3AF} \u5168\u7403\u76F4\u8FDE", "select" /* Select */, ["[]DIRECT", "[]\u{1F680} \u8282\u70B9\u9009\u62E9", "[]\u267B\uFE0F \u81EA\u52A8\u9009\u62E9"]),
|
|
6127
|
+
group("\u{1F6D1} \u5168\u7403\u62E6\u622A", "select" /* Select */, ["[]REJECT", "[]DIRECT"]),
|
|
6128
|
+
group("\u{1F343} \u5E94\u7528\u51C0\u5316", "select" /* Select */, ["[]REJECT", "[]DIRECT"]),
|
|
6129
|
+
group("\u{1F41F} \u6F0F\u7F51\u4E4B\u9C7C", "select" /* Select */, [
|
|
6130
|
+
"[]\u{1F680} \u8282\u70B9\u9009\u62E9",
|
|
6131
|
+
"[]\u{1F3AF} \u5168\u7403\u76F4\u8FDE",
|
|
6132
|
+
"[]\u267B\uFE0F \u81EA\u52A8\u9009\u62E9",
|
|
6133
|
+
".*"
|
|
6134
|
+
])
|
|
6135
|
+
];
|
|
6136
|
+
}
|
|
6137
|
+
function inline(group2, rule) {
|
|
6138
|
+
return {
|
|
6139
|
+
content: `[]${rule}`,
|
|
6140
|
+
ruleGroup: group2,
|
|
6141
|
+
rulePath: "",
|
|
6142
|
+
rulePathTyped: "",
|
|
6143
|
+
ruleType: "surge" /* Surge */,
|
|
6144
|
+
updateInterval: 86400
|
|
6145
|
+
};
|
|
6146
|
+
}
|
|
6147
|
+
function surge(group2, lines) {
|
|
6148
|
+
return {
|
|
6149
|
+
content: lines.join("\n"),
|
|
6150
|
+
ruleGroup: group2,
|
|
6151
|
+
rulePath: "",
|
|
6152
|
+
rulePathTyped: "",
|
|
6153
|
+
ruleType: "surge" /* Surge */,
|
|
6154
|
+
updateInterval: 86400
|
|
6155
|
+
};
|
|
6156
|
+
}
|
|
6157
|
+
function getDefaultRulesets() {
|
|
6158
|
+
return [
|
|
6159
|
+
surge("\u{1F3AF} \u5168\u7403\u76F4\u8FDE", [
|
|
6160
|
+
"DOMAIN-SUFFIX,localhost",
|
|
6161
|
+
"DOMAIN,localhost",
|
|
6162
|
+
"IP-CIDR,127.0.0.0/8",
|
|
6163
|
+
"IP-CIDR,10.0.0.0/8",
|
|
6164
|
+
"IP-CIDR,172.16.0.0/12",
|
|
6165
|
+
"IP-CIDR,192.168.0.0/16",
|
|
6166
|
+
"IP-CIDR,224.0.0.0/4",
|
|
6167
|
+
"DOMAIN-SUFFIX,cn",
|
|
6168
|
+
"DOMAIN-SUFFIX,126.com",
|
|
6169
|
+
"DOMAIN-SUFFIX,163.com",
|
|
6170
|
+
"DOMAIN-SUFFIX,qq.com",
|
|
6171
|
+
"DOMAIN-SUFFIX,baidu.com",
|
|
6172
|
+
"DOMAIN-SUFFIX,alibaba.com",
|
|
6173
|
+
"DOMAIN-SUFFIX,taobao.com"
|
|
6174
|
+
]),
|
|
6175
|
+
surge("\u{1F6D1} \u5168\u7403\u62E6\u622A", [
|
|
6176
|
+
"DOMAIN-SUFFIX,doubleclick.net",
|
|
6177
|
+
"DOMAIN-SUFFIX,googlesyndication.com",
|
|
6178
|
+
"DOMAIN-SUFFIX,googleadservices.com",
|
|
6179
|
+
"DOMAIN-SUFFIX,ads.yahoo.com",
|
|
6180
|
+
"DOMAIN-KEYWORD,adservice",
|
|
6181
|
+
"DOMAIN-KEYWORD,advertising"
|
|
6182
|
+
]),
|
|
6183
|
+
surge("\u{1F343} \u5E94\u7528\u51C0\u5316", [
|
|
6184
|
+
"DOMAIN-SUFFIX,app-measurement.com",
|
|
6185
|
+
"DOMAIN-SUFFIX,crashlytics.com",
|
|
6186
|
+
"DOMAIN-KEYWORD,analytics",
|
|
6187
|
+
"DOMAIN-KEYWORD,tracking"
|
|
6188
|
+
]),
|
|
6189
|
+
surge("\u{1F30D} \u56FD\u5916\u5A92\u4F53", [
|
|
6190
|
+
"DOMAIN-SUFFIX,netflix.com",
|
|
6191
|
+
"DOMAIN-SUFFIX,nflxvideo.net",
|
|
6192
|
+
"DOMAIN-SUFFIX,youtube.com",
|
|
6193
|
+
"DOMAIN-SUFFIX,googlevideo.com",
|
|
6194
|
+
"DOMAIN-SUFFIX,disneyplus.com",
|
|
6195
|
+
"DOMAIN-SUFFIX,spotify.com",
|
|
6196
|
+
"DOMAIN-SUFFIX,tiktok.com"
|
|
6197
|
+
]),
|
|
6198
|
+
surge("\u{1F4F2} \u7535\u62A5\u4FE1\u606F", [
|
|
6199
|
+
"DOMAIN-SUFFIX,telegram.org",
|
|
6200
|
+
"DOMAIN-SUFFIX,t.me",
|
|
6201
|
+
"DOMAIN-SUFFIX,telegram.me",
|
|
6202
|
+
"IP-CIDR,149.154.160.0/20",
|
|
6203
|
+
"IP-CIDR,91.108.4.0/22"
|
|
6204
|
+
]),
|
|
6205
|
+
surge("\u24C2\uFE0F \u5FAE\u8F6F\u670D\u52A1", [
|
|
6206
|
+
"DOMAIN-SUFFIX,microsoft.com",
|
|
6207
|
+
"DOMAIN-SUFFIX,windows.com",
|
|
6208
|
+
"DOMAIN-SUFFIX,office.com",
|
|
6209
|
+
"DOMAIN-SUFFIX,live.com"
|
|
6210
|
+
]),
|
|
6211
|
+
surge("\u{1F34E} \u82F9\u679C\u670D\u52A1", [
|
|
6212
|
+
"DOMAIN-SUFFIX,apple.com",
|
|
6213
|
+
"DOMAIN-SUFFIX,icloud.com",
|
|
6214
|
+
"DOMAIN-SUFFIX,apple-cloudkit.com"
|
|
6215
|
+
]),
|
|
6216
|
+
surge("\u{1F680} \u8282\u70B9\u9009\u62E9", ["DOMAIN-SUFFIX,google.com", "DOMAIN-SUFFIX,github.com"]),
|
|
6217
|
+
inline("\u{1F3AF} \u5168\u7403\u76F4\u8FDE", "GEOIP,CN"),
|
|
6218
|
+
inline("\u{1F41F} \u6F0F\u7F51\u4E4B\u9C7C", "FINAL")
|
|
6219
|
+
];
|
|
6220
|
+
}
|
|
6221
|
+
function getDefaultRulesetConfigs() {
|
|
6222
|
+
const base = "https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash";
|
|
6223
|
+
const list = (group2, file) => ({
|
|
6224
|
+
group: group2,
|
|
6225
|
+
interval: 86400,
|
|
6226
|
+
url: `${base}/${file}`
|
|
6227
|
+
});
|
|
6228
|
+
return [
|
|
6229
|
+
list("\u{1F3AF} \u5168\u7403\u76F4\u8FDE", "LocalAreaNetwork.list"),
|
|
6230
|
+
list("\u{1F6D1} \u5168\u7403\u62E6\u622A", "BanAD.list"),
|
|
6231
|
+
list("\u{1F343} \u5E94\u7528\u51C0\u5316", "BanProgramAD.list"),
|
|
6232
|
+
list("\u{1F3AF} \u5168\u7403\u76F4\u8FDE", "GoogleCN.list"),
|
|
6233
|
+
list("\u24C2\uFE0F \u5FAE\u8F6F\u670D\u52A1", "Microsoft.list"),
|
|
6234
|
+
list("\u{1F34E} \u82F9\u679C\u670D\u52A1", "Apple.list"),
|
|
6235
|
+
list("\u{1F30D} \u56FD\u5916\u5A92\u4F53", "ProxyMedia.list"),
|
|
6236
|
+
list("\u{1F4F2} \u7535\u62A5\u4FE1\u606F", "Telegram.list"),
|
|
6237
|
+
list("\u{1F680} \u8282\u70B9\u9009\u62E9", "ProxyLite.list"),
|
|
6238
|
+
list("\u{1F3AF} \u5168\u7403\u76F4\u8FDE", "ChinaDomain.list"),
|
|
6239
|
+
list("\u{1F3AF} \u5168\u7403\u76F4\u8FDE", "ChinaCompanyIp.list"),
|
|
6240
|
+
{ group: "\u{1F3AF} \u5168\u7403\u76F4\u8FDE", interval: 86400, url: "[]GEOIP,CN" },
|
|
6241
|
+
{ group: "\u{1F41F} \u6F0F\u7F51\u4E4B\u9C7C", interval: 86400, url: "[]FINAL" }
|
|
6242
|
+
];
|
|
6243
|
+
}
|
|
6244
|
+
|
|
5236
6245
|
// src/generator/links.ts
|
|
5237
6246
|
function vmessLinkConstruct(remarks, add, port, type, id, aid, net, path, host, tls) {
|
|
5238
6247
|
return JSON.stringify({
|
|
@@ -5258,8 +6267,8 @@ function ssLinkConstruct(proxy) {
|
|
|
5258
6267
|
link += `#${urlEncode(proxy.remark)}`;
|
|
5259
6268
|
return link;
|
|
5260
6269
|
}
|
|
5261
|
-
function ssrLinkConstruct(hostname, port, protocol, method, obfs, password,
|
|
5262
|
-
const payload = `${hostname}:${port}:${protocol}:${method}:${obfs}:${urlSafeBase64Encode(password)}/?group=${urlSafeBase64Encode(
|
|
6270
|
+
function ssrLinkConstruct(hostname, port, protocol, method, obfs, password, group2, remark, obfsParam = "", protocolParam = "") {
|
|
6271
|
+
const payload = `${hostname}:${port}:${protocol}:${method}:${obfs}:${urlSafeBase64Encode(password)}/?group=${urlSafeBase64Encode(group2)}&remarks=${urlSafeBase64Encode(remark)}&obfsparam=${urlSafeBase64Encode(obfsParam)}&protoparam=${urlSafeBase64Encode(protocolParam)}`;
|
|
5263
6272
|
return `ssr://${urlSafeBase64Encode(payload)}`;
|
|
5264
6273
|
}
|
|
5265
6274
|
function trojanLinkConstruct(proxy) {
|
|
@@ -5406,8 +6415,8 @@ function proxyToSsSub(nodes, baseConf) {
|
|
|
5406
6415
|
}
|
|
5407
6416
|
return JSON.stringify(proxies);
|
|
5408
6417
|
}
|
|
5409
|
-
function proxyToSsd(nodes,
|
|
5410
|
-
const resolvedGroup =
|
|
6418
|
+
function proxyToSsd(nodes, group2, userinfo) {
|
|
6419
|
+
const resolvedGroup = group2 === "" ? "SSD" : group2;
|
|
5411
6420
|
const doc = {
|
|
5412
6421
|
airport: resolvedGroup,
|
|
5413
6422
|
encryption: "aes-128-gcm",
|
|
@@ -5420,7 +6429,7 @@ function proxyToSsd(nodes, group, userinfo) {
|
|
|
5420
6429
|
const download = getUrlArg(data, "download");
|
|
5421
6430
|
const total = getUrlArg(data, "total");
|
|
5422
6431
|
const expiry = getUrlArg(data, "expire");
|
|
5423
|
-
const gb =
|
|
6432
|
+
const gb = 1e3 ** 3;
|
|
5424
6433
|
doc.traffic_used = (Number(upload || 0) + Number(download || 0)) / gb;
|
|
5425
6434
|
doc.traffic_total = Number(total || 0) / gb;
|
|
5426
6435
|
if (expiry !== "") {
|
|
@@ -5659,6 +6668,14 @@ function buildSurge(nodes, extraProxyGroup, settings, options) {
|
|
|
5659
6668
|
if (x.host !== "") {
|
|
5660
6669
|
proxy += `, sni=${x.host}`;
|
|
5661
6670
|
}
|
|
6671
|
+
if (x.transferProtocol === "ws") {
|
|
6672
|
+
proxy += ", ws=true";
|
|
6673
|
+
if (x.path !== "") {
|
|
6674
|
+
proxy += `, ws-path=${x.path}`;
|
|
6675
|
+
}
|
|
6676
|
+
const wsHost = x.host !== "" ? x.host : x.hostname;
|
|
6677
|
+
proxy += `, ws-headers=Host:"${wsHost}"`;
|
|
6678
|
+
}
|
|
5662
6679
|
if (scv !== void 0) {
|
|
5663
6680
|
proxy += `, skip-cert-verify=${triStr(scv)}`;
|
|
5664
6681
|
}
|
|
@@ -5704,7 +6721,7 @@ function buildSurge(nodes, extraProxyGroup, settings, options) {
|
|
|
5704
6721
|
if (surgeVer < 4) {
|
|
5705
6722
|
continue;
|
|
5706
6723
|
}
|
|
5707
|
-
proxy = `
|
|
6724
|
+
proxy = `hysteria2, ${x.hostname}, ${x.port}, password=${x.password}`;
|
|
5708
6725
|
if (x.downSpeed) {
|
|
5709
6726
|
proxy += `, download-bandwidth=${x.downSpeed}`;
|
|
5710
6727
|
}
|
|
@@ -5747,10 +6764,10 @@ function buildSurge(nodes, extraProxyGroup, settings, options) {
|
|
|
5747
6764
|
return { extraSections, groups: [], proxies, sectionOrder };
|
|
5748
6765
|
}
|
|
5749
6766
|
const groups = [];
|
|
5750
|
-
for (const
|
|
6767
|
+
for (const group2 of extraProxyGroup) {
|
|
5751
6768
|
const filtered = [];
|
|
5752
6769
|
let groupLine = "";
|
|
5753
|
-
switch (
|
|
6770
|
+
switch (group2.type) {
|
|
5754
6771
|
case "select":
|
|
5755
6772
|
case "smart":
|
|
5756
6773
|
case "url-test":
|
|
@@ -5762,15 +6779,15 @@ function buildSurge(nodes, extraProxyGroup, settings, options) {
|
|
|
5762
6779
|
}
|
|
5763
6780
|
break;
|
|
5764
6781
|
case "ssid": {
|
|
5765
|
-
const rest =
|
|
5766
|
-
const line = `${
|
|
5767
|
-
groups.push(`${
|
|
6782
|
+
const rest = group2.proxies.slice(1).join(",");
|
|
6783
|
+
const line = `${group2.type},default=${group2.proxies[0] ?? ""},${rest}`;
|
|
6784
|
+
groups.push(`${group2.name} = ${line}`);
|
|
5768
6785
|
continue;
|
|
5769
6786
|
}
|
|
5770
6787
|
default:
|
|
5771
6788
|
continue;
|
|
5772
6789
|
}
|
|
5773
|
-
for (const rule of
|
|
6790
|
+
for (const rule of group2.proxies) {
|
|
5774
6791
|
groupGenerate(rule, nodelist, filtered, true);
|
|
5775
6792
|
}
|
|
5776
6793
|
if (filtered.length === 0) {
|
|
@@ -5779,27 +6796,27 @@ function buildSurge(nodes, extraProxyGroup, settings, options) {
|
|
|
5779
6796
|
if (filtered.length === 1) {
|
|
5780
6797
|
const single = filtered[0].toLowerCase();
|
|
5781
6798
|
if (single === "direct" || single === "reject" || single === "reject-tinygif") {
|
|
5782
|
-
proxies.push(`${
|
|
6799
|
+
proxies.push(`${group2.name} = ${single}`);
|
|
5783
6800
|
continue;
|
|
5784
6801
|
}
|
|
5785
6802
|
}
|
|
5786
|
-
groupLine = `${
|
|
5787
|
-
if (
|
|
5788
|
-
groupLine += `,url=${
|
|
5789
|
-
if (
|
|
5790
|
-
groupLine += `,tolerance=${
|
|
6803
|
+
groupLine = `${group2.type},${filtered.join(",")}`;
|
|
6804
|
+
if (group2.type === "url-test" || group2.type === "fallback" || group2.type === "load-balance") {
|
|
6805
|
+
groupLine += `,url=${group2.url},interval=${group2.interval}`;
|
|
6806
|
+
if (group2.tolerance > 0) {
|
|
6807
|
+
groupLine += `,tolerance=${group2.tolerance}`;
|
|
5791
6808
|
}
|
|
5792
|
-
if (
|
|
5793
|
-
groupLine += `,timeout=${
|
|
6809
|
+
if (group2.timeout > 0) {
|
|
6810
|
+
groupLine += `,timeout=${group2.timeout}`;
|
|
5794
6811
|
}
|
|
5795
|
-
if (
|
|
5796
|
-
groupLine += `,persistent=${triStr(
|
|
6812
|
+
if (group2.persistent !== void 0) {
|
|
6813
|
+
groupLine += `,persistent=${triStr(group2.persistent)}`;
|
|
5797
6814
|
}
|
|
5798
|
-
if (
|
|
5799
|
-
groupLine += `,evaluate-before-use=${triStr(
|
|
6815
|
+
if (group2.evaluateBeforeUse !== void 0) {
|
|
6816
|
+
groupLine += `,evaluate-before-use=${triStr(group2.evaluateBeforeUse)}`;
|
|
5800
6817
|
}
|
|
5801
6818
|
}
|
|
5802
|
-
groups.push(`${
|
|
6819
|
+
groups.push(`${group2.name} = ${groupLine}`);
|
|
5803
6820
|
}
|
|
5804
6821
|
return { extraSections, groups, proxies, sectionOrder };
|
|
5805
6822
|
}
|
|
@@ -5899,11 +6916,47 @@ function buildLoonNode(x, settings, remark) {
|
|
|
5899
6916
|
proxy += `,skip-cert-verify=${scv ? "true" : "false"}`;
|
|
5900
6917
|
}
|
|
5901
6918
|
break;
|
|
6919
|
+
case "vless" /* VLESS */:
|
|
6920
|
+
if (x.transferProtocol !== "" && x.transferProtocol !== "tcp" && x.transferProtocol !== "ws") {
|
|
6921
|
+
return void 0;
|
|
6922
|
+
}
|
|
6923
|
+
proxy = `VLESS,${hostname},${port},"${x.userId}"`;
|
|
6924
|
+
if (x.flow !== "") {
|
|
6925
|
+
proxy += `,flow=${x.flow}`;
|
|
6926
|
+
}
|
|
6927
|
+
if (x.publicKey !== "") {
|
|
6928
|
+
proxy += `,public-key="${x.publicKey}"`;
|
|
6929
|
+
}
|
|
6930
|
+
if (x.shortId !== "") {
|
|
6931
|
+
proxy += `,short-id=${x.shortId}`;
|
|
6932
|
+
}
|
|
6933
|
+
if (x.transferProtocol === "ws") {
|
|
6934
|
+
proxy += `,path=${x.path},host=${x.host}`;
|
|
6935
|
+
}
|
|
6936
|
+
proxy += `,transport=${x.transferProtocol === "ws" ? "ws" : "tcp"}`;
|
|
6937
|
+
if (x.udp !== void 0) {
|
|
6938
|
+
proxy += `,udp=${x.udp ? "true" : "false"}`;
|
|
6939
|
+
} else {
|
|
6940
|
+
proxy += ",udp=false";
|
|
6941
|
+
}
|
|
6942
|
+
proxy += `,over-tls=${x.tlsSecure ? "true" : "false"}`;
|
|
6943
|
+
if (x.tlsSecure && x.serverName !== "") {
|
|
6944
|
+
proxy += `,sni=${x.serverName}`;
|
|
6945
|
+
}
|
|
6946
|
+
if (scv !== void 0) {
|
|
6947
|
+
proxy += `,skip-cert-verify=${scv ? "true" : "false"}`;
|
|
6948
|
+
}
|
|
6949
|
+
break;
|
|
5902
6950
|
case "trojan" /* Trojan */:
|
|
5903
6951
|
proxy = `trojan,${hostname},${port},"${x.password}"`;
|
|
5904
6952
|
if (x.host !== "") {
|
|
5905
6953
|
proxy += `,tls-name=${x.host}`;
|
|
5906
6954
|
}
|
|
6955
|
+
if (x.transferProtocol === "ws") {
|
|
6956
|
+
proxy += `,transport=ws,path=${x.path},host=${x.host}`;
|
|
6957
|
+
} else {
|
|
6958
|
+
proxy += ",transport=tcp";
|
|
6959
|
+
}
|
|
5907
6960
|
if (scv !== void 0) {
|
|
5908
6961
|
proxy += `,skip-cert-verify=${scv ? "true" : "false"}`;
|
|
5909
6962
|
}
|
|
@@ -5945,26 +6998,22 @@ function buildLoonNode(x, settings, remark) {
|
|
|
5945
6998
|
proxy += `, peers=[{${generatePeer(x, true)}}]`;
|
|
5946
6999
|
break;
|
|
5947
7000
|
case "hysteria2" /* Hysteria2 */:
|
|
5948
|
-
proxy = `
|
|
5949
|
-
if (scv !== void 0) {
|
|
5950
|
-
proxy += `,skip-cert-verify=${scv ? "true" : "false"}`;
|
|
5951
|
-
}
|
|
5952
|
-
if (x.fingerprint !== "") {
|
|
5953
|
-
proxy += `,tls-cert-sha256=${x.fingerprint}`;
|
|
5954
|
-
}
|
|
7001
|
+
proxy = `Hysteria2,${hostname},${port},"${x.password}"`;
|
|
5955
7002
|
if (x.sni !== "") {
|
|
5956
7003
|
proxy += `,sni=${x.sni}`;
|
|
5957
7004
|
}
|
|
5958
|
-
|
|
5959
|
-
|
|
5960
|
-
proxy = `anytls,${hostname},${port},"${x.password}"`;
|
|
5961
|
-
if (x.sni !== "") {
|
|
5962
|
-
proxy += `,sni=${x.sni}`;
|
|
7005
|
+
if (x.downSpeed > 0) {
|
|
7006
|
+
proxy += `,download-bandwidth=${x.downSpeed}`;
|
|
5963
7007
|
}
|
|
5964
7008
|
if (scv !== void 0) {
|
|
5965
7009
|
proxy += `,skip-cert-verify=${scv ? "true" : "false"}`;
|
|
5966
7010
|
}
|
|
7011
|
+
if (x.fingerprint !== "") {
|
|
7012
|
+
proxy += `,tls-cert-sha256=${x.fingerprint}`;
|
|
7013
|
+
}
|
|
5967
7014
|
break;
|
|
7015
|
+
// Loon has no AnyTLS/TUIC mapping — keep the drop instead of
|
|
7016
|
+
// emitting non-standard lines.
|
|
5968
7017
|
default:
|
|
5969
7018
|
return void 0;
|
|
5970
7019
|
}
|
|
@@ -5979,48 +7028,48 @@ function buildLoonNode(x, settings, remark) {
|
|
|
5979
7028
|
}
|
|
5980
7029
|
function buildLoonGroups(extraProxyGroup, nodelist) {
|
|
5981
7030
|
const lines = [];
|
|
5982
|
-
for (const
|
|
7031
|
+
for (const group2 of extraProxyGroup) {
|
|
5983
7032
|
const filtered = [];
|
|
5984
|
-
switch (
|
|
7033
|
+
switch (group2.type) {
|
|
5985
7034
|
case "select":
|
|
5986
7035
|
case "load-balance":
|
|
5987
7036
|
case "url-test":
|
|
5988
7037
|
case "fallback":
|
|
5989
7038
|
break;
|
|
5990
7039
|
case "ssid":
|
|
5991
|
-
if (
|
|
7040
|
+
if (group2.proxies.length < 2) {
|
|
5992
7041
|
continue;
|
|
5993
7042
|
}
|
|
5994
7043
|
lines.push(
|
|
5995
|
-
`${
|
|
7044
|
+
`${group2.name} = ssid,default=${group2.proxies[0]},${group2.proxies.slice(1).join(",")}`
|
|
5996
7045
|
);
|
|
5997
7046
|
continue;
|
|
5998
7047
|
default:
|
|
5999
7048
|
continue;
|
|
6000
7049
|
}
|
|
6001
|
-
for (const rule of
|
|
7050
|
+
for (const rule of group2.proxies) {
|
|
6002
7051
|
groupGenerate(rule, nodelist, filtered, true);
|
|
6003
7052
|
}
|
|
6004
7053
|
if (filtered.length === 0) {
|
|
6005
7054
|
filtered.push("DIRECT");
|
|
6006
7055
|
}
|
|
6007
|
-
let groupLine = `${
|
|
6008
|
-
if (
|
|
6009
|
-
groupLine += `,url=${
|
|
6010
|
-
if (
|
|
6011
|
-
groupLine += `,algorithm=${
|
|
6012
|
-
if (
|
|
6013
|
-
groupLine += `,max-timeout=${
|
|
7056
|
+
let groupLine = `${group2.type},${filtered.join(",")}`;
|
|
7057
|
+
if (group2.type !== "select") {
|
|
7058
|
+
groupLine += `,url=${group2.url},interval=${group2.interval}`;
|
|
7059
|
+
if (group2.type === "load-balance") {
|
|
7060
|
+
groupLine += `,algorithm=${group2.strategy === "round-robin" ? "round-robin" : "pcc"}`;
|
|
7061
|
+
if (group2.timeout > 0) {
|
|
7062
|
+
groupLine += `,max-timeout=${group2.timeout}`;
|
|
6014
7063
|
}
|
|
6015
7064
|
}
|
|
6016
|
-
if (
|
|
6017
|
-
groupLine += `,tolerance=${
|
|
7065
|
+
if (group2.type === "url-test" && group2.tolerance > 0) {
|
|
7066
|
+
groupLine += `,tolerance=${group2.tolerance}`;
|
|
6018
7067
|
}
|
|
6019
|
-
if (
|
|
6020
|
-
groupLine += `,max-timeout=${
|
|
7068
|
+
if (group2.type === "fallback") {
|
|
7069
|
+
groupLine += `,max-timeout=${group2.timeout}`;
|
|
6021
7070
|
}
|
|
6022
7071
|
}
|
|
6023
|
-
lines.push(`${
|
|
7072
|
+
lines.push(`${group2.name} = ${groupLine}`);
|
|
6024
7073
|
}
|
|
6025
7074
|
return lines;
|
|
6026
7075
|
}
|
|
@@ -6051,6 +7100,9 @@ function toLoon(nodes, extraProxyGroup, settings, options) {
|
|
|
6051
7100
|
if (groupLines.length > 0) {
|
|
6052
7101
|
setRawSection(sections, "Proxy Group", groupLines);
|
|
6053
7102
|
}
|
|
7103
|
+
if (options.rules && options.rules.lines.length > 0) {
|
|
7104
|
+
setRawSection(sections, options.rules.section, options.rules.lines);
|
|
7105
|
+
}
|
|
6054
7106
|
return renderRawIni(sections);
|
|
6055
7107
|
}
|
|
6056
7108
|
|
|
@@ -6181,12 +7233,12 @@ function convertRuleset(content, type) {
|
|
|
6181
7233
|
}
|
|
6182
7234
|
return lines.join("\n");
|
|
6183
7235
|
}
|
|
6184
|
-
function transformRuleToCommon(input,
|
|
7236
|
+
function transformRuleToCommon(input, group2, noResolveOnly = false) {
|
|
6185
7237
|
const parts = input.split(",");
|
|
6186
7238
|
if (parts.length < 2) {
|
|
6187
|
-
return `${parts[0] ?? ""},${
|
|
7239
|
+
return `${parts[0] ?? ""},${group2}`;
|
|
6188
7240
|
}
|
|
6189
|
-
let line = `${parts[0]},${parts[1]},${
|
|
7241
|
+
let line = `${parts[0]},${parts[1]},${group2}`;
|
|
6190
7242
|
if (parts.length > 2 && (!noResolveOnly || parts[2] === "no-resolve")) {
|
|
6191
7243
|
line += `,${parts[2]}`;
|
|
6192
7244
|
}
|
|
@@ -6195,7 +7247,7 @@ function transformRuleToCommon(input, group, noResolveOnly = false) {
|
|
|
6195
7247
|
function startsWithAny(line, types) {
|
|
6196
7248
|
return types.some((type) => line.startsWith(type));
|
|
6197
7249
|
}
|
|
6198
|
-
function collectRuleLines(content,
|
|
7250
|
+
function collectRuleLines(content, group2, noResolveOnly) {
|
|
6199
7251
|
const converted = convertRuleset(content, "surge" /* Surge */);
|
|
6200
7252
|
const out = [];
|
|
6201
7253
|
for (const rawLine of converted.split(/\r?\n/)) {
|
|
@@ -6209,7 +7261,7 @@ function collectRuleLines(content, group, noResolveOnly) {
|
|
|
6209
7261
|
if (line === "") {
|
|
6210
7262
|
continue;
|
|
6211
7263
|
}
|
|
6212
|
-
out.push(transformRuleToCommon(line,
|
|
7264
|
+
out.push(transformRuleToCommon(line, group2, noResolveOnly));
|
|
6213
7265
|
}
|
|
6214
7266
|
return out;
|
|
6215
7267
|
}
|
|
@@ -6220,13 +7272,13 @@ function rulesetToClashRules(rulesets) {
|
|
|
6220
7272
|
if (content === "") {
|
|
6221
7273
|
continue;
|
|
6222
7274
|
}
|
|
6223
|
-
const
|
|
7275
|
+
const group2 = ruleset.ruleGroup;
|
|
6224
7276
|
if (content.startsWith("[]")) {
|
|
6225
7277
|
let line = content.slice(2);
|
|
6226
7278
|
if (line.startsWith("FINAL")) {
|
|
6227
7279
|
line = `MATCH${line.slice(5)}`;
|
|
6228
7280
|
}
|
|
6229
|
-
rules.push(transformRuleToCommon(line,
|
|
7281
|
+
rules.push(transformRuleToCommon(line, group2));
|
|
6230
7282
|
continue;
|
|
6231
7283
|
}
|
|
6232
7284
|
const converted = convertRuleset(content, ruleset.ruleType);
|
|
@@ -6241,7 +7293,7 @@ function rulesetToClashRules(rulesets) {
|
|
|
6241
7293
|
if (line.includes("//")) {
|
|
6242
7294
|
line = stripComment(line);
|
|
6243
7295
|
}
|
|
6244
|
-
rules.push(transformRuleToCommon(line,
|
|
7296
|
+
rules.push(transformRuleToCommon(line, group2));
|
|
6245
7297
|
}
|
|
6246
7298
|
}
|
|
6247
7299
|
return rules;
|
|
@@ -6283,21 +7335,21 @@ function rulesetToSurgeRules(rulesets, surgeVersion) {
|
|
|
6283
7335
|
if (ruleset.content === "") {
|
|
6284
7336
|
continue;
|
|
6285
7337
|
}
|
|
6286
|
-
const
|
|
7338
|
+
const group2 = ruleset.ruleGroup;
|
|
6287
7339
|
if (ruleset.content.startsWith("[]")) {
|
|
6288
7340
|
let line = ruleset.content.slice(2);
|
|
6289
7341
|
if (line === "MATCH") {
|
|
6290
7342
|
line = "FINAL";
|
|
6291
7343
|
}
|
|
6292
7344
|
if (surgeVersion === -1 || surgeVersion === -2) {
|
|
6293
|
-
line = transformRuleToCommon(line,
|
|
7345
|
+
line = transformRuleToCommon(line, group2, true);
|
|
6294
7346
|
} else if (!line.startsWith("AND") && !line.startsWith("OR") && !line.startsWith("NOT")) {
|
|
6295
|
-
line = transformRuleToCommon(line,
|
|
7347
|
+
line = transformRuleToCommon(line, group2);
|
|
6296
7348
|
}
|
|
6297
7349
|
lines.push(line.replace(/,,/g, ","));
|
|
6298
7350
|
continue;
|
|
6299
7351
|
}
|
|
6300
|
-
for (const rawLine of collectRuleLines(ruleset.content,
|
|
7352
|
+
for (const rawLine of collectRuleLines(ruleset.content, group2, noResolveOnly)) {
|
|
6301
7353
|
if (surgeVersion === -2 && rawLine.startsWith("IP-CIDR6")) {
|
|
6302
7354
|
continue;
|
|
6303
7355
|
}
|
|
@@ -6340,11 +7392,11 @@ function rulesetToSingBoxRules(rulesets) {
|
|
|
6340
7392
|
if (content === "") {
|
|
6341
7393
|
continue;
|
|
6342
7394
|
}
|
|
6343
|
-
const
|
|
7395
|
+
const group2 = ruleset.ruleGroup;
|
|
6344
7396
|
if (content.startsWith("[]")) {
|
|
6345
7397
|
const line = content.slice(2);
|
|
6346
7398
|
if (line.startsWith("FINAL") || line.startsWith("MATCH")) {
|
|
6347
|
-
final =
|
|
7399
|
+
final = group2;
|
|
6348
7400
|
continue;
|
|
6349
7401
|
}
|
|
6350
7402
|
const parts = line.split(",");
|
|
@@ -6356,7 +7408,7 @@ function rulesetToSingBoxRules(rulesets) {
|
|
|
6356
7408
|
if (type === "match" || type === "final") {
|
|
6357
7409
|
rules.push({ outbound: value });
|
|
6358
7410
|
} else {
|
|
6359
|
-
rules.push({ outbound:
|
|
7411
|
+
rules.push({ outbound: group2, [type]: value });
|
|
6360
7412
|
}
|
|
6361
7413
|
continue;
|
|
6362
7414
|
}
|
|
@@ -6387,7 +7439,7 @@ function rulesetToSingBoxRules(rulesets) {
|
|
|
6387
7439
|
if (Object.keys(rule).length === 0) {
|
|
6388
7440
|
continue;
|
|
6389
7441
|
}
|
|
6390
|
-
rule.outbound =
|
|
7442
|
+
rule.outbound = group2;
|
|
6391
7443
|
rules.push(rule);
|
|
6392
7444
|
}
|
|
6393
7445
|
return { final, rules };
|
|
@@ -6448,8 +7500,8 @@ function buildMellowEndpoint(x, remark) {
|
|
|
6448
7500
|
}
|
|
6449
7501
|
function buildMellowGroups(extraProxyGroup, nodelist, remarks) {
|
|
6450
7502
|
const lines = [];
|
|
6451
|
-
for (const
|
|
6452
|
-
switch (
|
|
7503
|
+
for (const group2 of extraProxyGroup) {
|
|
7504
|
+
switch (group2.type) {
|
|
6453
7505
|
case "select":
|
|
6454
7506
|
case "url-test":
|
|
6455
7507
|
case "fallback":
|
|
@@ -6459,7 +7511,7 @@ function buildMellowGroups(extraProxyGroup, nodelist, remarks) {
|
|
|
6459
7511
|
continue;
|
|
6460
7512
|
}
|
|
6461
7513
|
const filtered = [];
|
|
6462
|
-
for (const rule of
|
|
7514
|
+
for (const rule of group2.proxies) {
|
|
6463
7515
|
groupGenerate(rule, nodelist, filtered, false);
|
|
6464
7516
|
}
|
|
6465
7517
|
if (filtered.length === 0) {
|
|
@@ -6469,7 +7521,7 @@ function buildMellowGroups(extraProxyGroup, nodelist, remarks) {
|
|
|
6469
7521
|
filtered.push(...remarks);
|
|
6470
7522
|
}
|
|
6471
7523
|
}
|
|
6472
|
-
lines.push(`${
|
|
7524
|
+
lines.push(`${group2.name}, ${filtered.join(":")}, latency, interval=300, timeout=6`);
|
|
6473
7525
|
}
|
|
6474
7526
|
return lines;
|
|
6475
7527
|
}
|
|
@@ -6519,7 +7571,7 @@ function toMellow(nodes, extraProxyGroup, settings, options) {
|
|
|
6519
7571
|
function buildQuanNode(x, settings, remark, nodeList) {
|
|
6520
7572
|
const hostname = x.hostname;
|
|
6521
7573
|
const port = String(x.port);
|
|
6522
|
-
const
|
|
7574
|
+
const group2 = x.group;
|
|
6523
7575
|
let method = x.encryptMethod;
|
|
6524
7576
|
const scv = x.allowInsecure !== void 0 ? x.allowInsecure : settings.skipCertVerify;
|
|
6525
7577
|
let proxyStr;
|
|
@@ -6528,7 +7580,7 @@ function buildQuanNode(x, settings, remark, nodeList) {
|
|
|
6528
7580
|
if (method === "auto") {
|
|
6529
7581
|
method = "chacha20-ietf-poly1305";
|
|
6530
7582
|
}
|
|
6531
|
-
proxyStr = `${remark} = vmess, ${hostname}, ${port}, ${method}, "${x.userId}", group=${
|
|
7583
|
+
proxyStr = `${remark} = vmess, ${hostname}, ${port}, ${method}, "${x.userId}", group=${group2}`;
|
|
6532
7584
|
if (x.tlsSecure) {
|
|
6533
7585
|
proxyStr += `, over-tls=true, tls-host=${x.host}`;
|
|
6534
7586
|
if (scv !== void 0) {
|
|
@@ -6549,10 +7601,10 @@ function buildQuanNode(x, settings, remark, nodeList) {
|
|
|
6549
7601
|
case "ssr" /* ShadowsocksR */:
|
|
6550
7602
|
if (nodeList) {
|
|
6551
7603
|
proxyStr = `ssr://${urlSafeBase64Encode(
|
|
6552
|
-
`${hostname}:${port}:${x.protocol}:${method}:${x.obfs}:${urlSafeBase64Encode(x.password)}/?group=${urlSafeBase64Encode(
|
|
7604
|
+
`${hostname}:${port}:${x.protocol}:${method}:${x.obfs}:${urlSafeBase64Encode(x.password)}/?group=${urlSafeBase64Encode(group2)}&remarks=${urlSafeBase64Encode(remark)}&obfsparam=${urlSafeBase64Encode(x.obfsParam)}&protoparam=${urlSafeBase64Encode(x.protocolParam)}`
|
|
6553
7605
|
)}`;
|
|
6554
7606
|
} else {
|
|
6555
|
-
proxyStr = `${remark} = shadowsocksr, ${hostname}, ${port}, ${method}, "${x.password}", group=${
|
|
7607
|
+
proxyStr = `${remark} = shadowsocksr, ${hostname}, ${port}, ${method}, "${x.password}", group=${group2}, protocol=${x.protocol}, obfs=${x.obfs}`;
|
|
6556
7608
|
if (x.protocolParam !== "") {
|
|
6557
7609
|
proxyStr += `, protocol_param=${x.protocolParam}`;
|
|
6558
7610
|
}
|
|
@@ -6567,9 +7619,9 @@ function buildQuanNode(x, settings, remark, nodeList) {
|
|
|
6567
7619
|
if (x.plugin !== "" && x.pluginOption !== "") {
|
|
6568
7620
|
proxyStr += `/?plugin=${urlEncode(`${x.plugin};${x.pluginOption}`)}`;
|
|
6569
7621
|
}
|
|
6570
|
-
proxyStr += `&group=${urlSafeBase64Encode(
|
|
7622
|
+
proxyStr += `&group=${urlSafeBase64Encode(group2)}#${urlEncode(remark)}`;
|
|
6571
7623
|
} else {
|
|
6572
|
-
proxyStr = `${remark} = shadowsocks, ${hostname}, ${port}, ${method}, "${x.password}", group=${
|
|
7624
|
+
proxyStr = `${remark} = shadowsocks, ${hostname}, ${port}, ${method}, "${x.password}", group=${group2}`;
|
|
6573
7625
|
if (x.plugin === "obfs-local" && x.pluginOption !== "") {
|
|
6574
7626
|
proxyStr += `, ${x.pluginOption.replace(/;/g, ", ")}`;
|
|
6575
7627
|
}
|
|
@@ -6577,7 +7629,7 @@ function buildQuanNode(x, settings, remark, nodeList) {
|
|
|
6577
7629
|
break;
|
|
6578
7630
|
case "http" /* HTTP */:
|
|
6579
7631
|
case "https" /* HTTPS */:
|
|
6580
|
-
proxyStr = `${remark} = http, upstream-proxy-address=${hostname}, upstream-proxy-port=${port}, group=${
|
|
7632
|
+
proxyStr = `${remark} = http, upstream-proxy-address=${hostname}, upstream-proxy-port=${port}, group=${group2}`;
|
|
6581
7633
|
if (x.username !== "" && x.password !== "") {
|
|
6582
7634
|
proxyStr += `, upstream-proxy-auth=true, upstream-proxy-username=${x.username}, upstream-proxy-password=${x.password}`;
|
|
6583
7635
|
} else {
|
|
@@ -6597,7 +7649,7 @@ function buildQuanNode(x, settings, remark, nodeList) {
|
|
|
6597
7649
|
}
|
|
6598
7650
|
break;
|
|
6599
7651
|
case "socks5" /* SOCKS5 */:
|
|
6600
|
-
proxyStr = `${remark} = socks, upstream-proxy-address=${hostname}, upstream-proxy-port=${port}, group=${
|
|
7652
|
+
proxyStr = `${remark} = socks, upstream-proxy-address=${hostname}, upstream-proxy-port=${port}, group=${group2}`;
|
|
6601
7653
|
if (x.username !== "" && x.password !== "") {
|
|
6602
7654
|
proxyStr += `, upstream-proxy-auth=true, upstream-proxy-username=${x.username}, upstream-proxy-password=${x.password}`;
|
|
6603
7655
|
} else {
|
|
@@ -6623,9 +7675,9 @@ function buildQuanNode(x, settings, remark, nodeList) {
|
|
|
6623
7675
|
}
|
|
6624
7676
|
function buildQuanGroups(extraProxyGroup, nodelist) {
|
|
6625
7677
|
const lines = [];
|
|
6626
|
-
for (const
|
|
7678
|
+
for (const group2 of extraProxyGroup) {
|
|
6627
7679
|
let type;
|
|
6628
|
-
switch (
|
|
7680
|
+
switch (group2.type) {
|
|
6629
7681
|
case "select":
|
|
6630
7682
|
case "fallback":
|
|
6631
7683
|
type = "static";
|
|
@@ -6637,10 +7689,10 @@ function buildQuanGroups(extraProxyGroup, nodelist) {
|
|
|
6637
7689
|
type = "balance, round-robin";
|
|
6638
7690
|
break;
|
|
6639
7691
|
case "ssid": {
|
|
6640
|
-
let singlegroup2 = `${
|
|
7692
|
+
let singlegroup2 = `${group2.name} : wifi = ${group2.proxies[0] ?? ""}`;
|
|
6641
7693
|
let content = "";
|
|
6642
7694
|
let celluar = "";
|
|
6643
|
-
for (const proxy of
|
|
7695
|
+
for (const proxy of group2.proxies.slice(1)) {
|
|
6644
7696
|
const m = /^(.*?),?celluar\s?=\s?(.*?)(,.*)$/.exec(proxy);
|
|
6645
7697
|
if (!m) {
|
|
6646
7698
|
content += `${proxy}
|
|
@@ -6663,7 +7715,7 @@ ${content.trim().replace(/^,|,$/g, "").replace(/,/g, "\n")}`;
|
|
|
6663
7715
|
continue;
|
|
6664
7716
|
}
|
|
6665
7717
|
const filtered = [];
|
|
6666
|
-
for (const rule of
|
|
7718
|
+
for (const rule of group2.proxies) {
|
|
6667
7719
|
groupGenerate(rule, nodelist, filtered, true);
|
|
6668
7720
|
}
|
|
6669
7721
|
if (filtered.length === 0) {
|
|
@@ -6673,7 +7725,7 @@ ${content.trim().replace(/^,|,$/g, "").replace(/,/g, "\n")}`;
|
|
|
6673
7725
|
type = "static";
|
|
6674
7726
|
}
|
|
6675
7727
|
const proxies = filtered.join("\n");
|
|
6676
|
-
let singlegroup = `${
|
|
7728
|
+
let singlegroup = `${group2.name} : ${type}`;
|
|
6677
7729
|
if (type === "static") {
|
|
6678
7730
|
singlegroup += `, ${filtered[0]}`;
|
|
6679
7731
|
}
|
|
@@ -6711,6 +7763,9 @@ function toQuan(nodes, extraProxyGroup, settings, options) {
|
|
|
6711
7763
|
if (groupLines.length > 0) {
|
|
6712
7764
|
setRawSection(sections, "POLICY", groupLines);
|
|
6713
7765
|
}
|
|
7766
|
+
if (options.rules && options.rules.lines.length > 0) {
|
|
7767
|
+
setRawSection(sections, options.rules.section, options.rules.lines);
|
|
7768
|
+
}
|
|
6714
7769
|
return renderRawIni(sections);
|
|
6715
7770
|
}
|
|
6716
7771
|
|
|
@@ -6829,12 +7884,32 @@ function buildQuanxNode(x, settings, remark) {
|
|
|
6829
7884
|
}
|
|
6830
7885
|
}
|
|
6831
7886
|
break;
|
|
6832
|
-
case "
|
|
6833
|
-
|
|
6834
|
-
|
|
6835
|
-
|
|
7887
|
+
case "vless" /* VLESS */: {
|
|
7888
|
+
const vmethod = method === "" ? "none" : method;
|
|
7889
|
+
proxyStr = `vless = ${hostname}:${port}, method=${vmethod}, password=${x.userId}`;
|
|
7890
|
+
if (tlsSecure && tls13 !== void 0) {
|
|
7891
|
+
proxyStr += `, tls13=${triStr2(tls13)}`;
|
|
7892
|
+
}
|
|
7893
|
+
const obfsHost = host !== "" ? host : x.serverName !== "" ? x.serverName : x.sni;
|
|
7894
|
+
if (x.transferProtocol === "ws") {
|
|
7895
|
+
proxyStr += tlsSecure ? ", obfs=wss" : ", obfs=ws";
|
|
7896
|
+
proxyStr += `, obfs-host=${obfsHost}, obfs-uri=${path}`;
|
|
7897
|
+
} else if (tlsSecure) {
|
|
7898
|
+
proxyStr += `, obfs=over-tls, obfs-host=${obfsHost}`;
|
|
7899
|
+
}
|
|
7900
|
+
if (x.publicKey !== "") {
|
|
7901
|
+
proxyStr += `, reality-base64-pubkey=${x.publicKey}`;
|
|
7902
|
+
}
|
|
7903
|
+
if (x.shortId !== "") {
|
|
7904
|
+
proxyStr += `, reality-hex-shortid=${x.shortId}`;
|
|
7905
|
+
}
|
|
7906
|
+
if (x.flow !== "") {
|
|
7907
|
+
proxyStr += `, vless-flow=${x.flow}`;
|
|
6836
7908
|
}
|
|
6837
7909
|
break;
|
|
7910
|
+
}
|
|
7911
|
+
// Quantumult X has no AnyTLS/Hysteria2/TUIC mapping — drop them instead
|
|
7912
|
+
// of emitting non-standard lines.
|
|
6838
7913
|
default:
|
|
6839
7914
|
return void 0;
|
|
6840
7915
|
}
|
|
@@ -6852,10 +7927,10 @@ function buildQuanxNode(x, settings, remark) {
|
|
|
6852
7927
|
}
|
|
6853
7928
|
function buildQuanxGroups(extraProxyGroup, nodelist) {
|
|
6854
7929
|
const lines = [];
|
|
6855
|
-
for (const
|
|
7930
|
+
for (const group2 of extraProxyGroup) {
|
|
6856
7931
|
let type;
|
|
6857
7932
|
const filtered = [];
|
|
6858
|
-
switch (
|
|
7933
|
+
switch (group2.type) {
|
|
6859
7934
|
case "select":
|
|
6860
7935
|
type = "static";
|
|
6861
7936
|
break;
|
|
@@ -6870,15 +7945,15 @@ function buildQuanxGroups(extraProxyGroup, nodelist) {
|
|
|
6870
7945
|
break;
|
|
6871
7946
|
case "ssid":
|
|
6872
7947
|
type = "ssid";
|
|
6873
|
-
for (const proxy of
|
|
7948
|
+
for (const proxy of group2.proxies) {
|
|
6874
7949
|
filtered.push(proxy.replace(/=/g, ":"));
|
|
6875
7950
|
}
|
|
6876
7951
|
break;
|
|
6877
7952
|
default:
|
|
6878
7953
|
continue;
|
|
6879
7954
|
}
|
|
6880
|
-
if (
|
|
6881
|
-
for (const rule of
|
|
7955
|
+
if (group2.type !== "ssid") {
|
|
7956
|
+
for (const rule of group2.proxies) {
|
|
6882
7957
|
groupGenerate(rule, nodelist, filtered, true);
|
|
6883
7958
|
}
|
|
6884
7959
|
if (filtered.length === 0) {
|
|
@@ -6889,11 +7964,11 @@ function buildQuanxGroups(extraProxyGroup, nodelist) {
|
|
|
6889
7964
|
}
|
|
6890
7965
|
}
|
|
6891
7966
|
const proxies = filtered.join(", ");
|
|
6892
|
-
let line = `${type}=${
|
|
6893
|
-
if (
|
|
6894
|
-
line += `, check-interval=${
|
|
6895
|
-
if (
|
|
6896
|
-
line += `, tolerance=${
|
|
7967
|
+
let line = `${type}=${group2.name}, ${proxies}`;
|
|
7968
|
+
if (group2.type !== "select" && group2.type !== "ssid") {
|
|
7969
|
+
line += `, check-interval=${group2.interval}`;
|
|
7970
|
+
if (group2.tolerance > 0) {
|
|
7971
|
+
line += `, tolerance=${group2.tolerance}`;
|
|
6897
7972
|
}
|
|
6898
7973
|
}
|
|
6899
7974
|
lines.push(line);
|
|
@@ -6927,6 +8002,9 @@ function toQuanX(nodes, extraProxyGroup, settings, options) {
|
|
|
6927
8002
|
if (groupLines.length > 0) {
|
|
6928
8003
|
setRawSection(sections, "policy", groupLines);
|
|
6929
8004
|
}
|
|
8005
|
+
if (options.rules && options.rules.lines.length > 0) {
|
|
8006
|
+
setRawSection(sections, options.rules.section, options.rules.lines);
|
|
8007
|
+
}
|
|
6930
8008
|
return renderRawIni(sections);
|
|
6931
8009
|
}
|
|
6932
8010
|
|
|
@@ -7022,18 +8100,9 @@ function buildOutbound(x, settings, remark) {
|
|
|
7022
8100
|
proxy = out;
|
|
7023
8101
|
break;
|
|
7024
8102
|
}
|
|
8103
|
+
// sing-box has no SSR support — drop such nodes.
|
|
7025
8104
|
case "ssr" /* ShadowsocksR */:
|
|
7026
|
-
|
|
7027
|
-
...common,
|
|
7028
|
-
method: x.encryptMethod,
|
|
7029
|
-
obfs: x.obfs,
|
|
7030
|
-
obfs_param: x.obfsParam,
|
|
7031
|
-
password: x.password,
|
|
7032
|
-
protocol: x.protocol,
|
|
7033
|
-
protocol_param: x.protocolParam,
|
|
7034
|
-
type: "shadowsocksr"
|
|
7035
|
-
};
|
|
7036
|
-
break;
|
|
8105
|
+
return void 0;
|
|
7037
8106
|
case "vmess" /* VMess */: {
|
|
7038
8107
|
const out = {
|
|
7039
8108
|
...common,
|
|
@@ -7049,6 +8118,18 @@ function buildOutbound(x, settings, remark) {
|
|
|
7049
8118
|
proxy = out;
|
|
7050
8119
|
break;
|
|
7051
8120
|
}
|
|
8121
|
+
case "vless" /* VLESS */: {
|
|
8122
|
+
const out = { ...common, type: "vless", uuid: x.userId };
|
|
8123
|
+
if (x.flow !== "") {
|
|
8124
|
+
out.flow = x.flow;
|
|
8125
|
+
}
|
|
8126
|
+
const transport = buildTransport(x);
|
|
8127
|
+
if (transport) {
|
|
8128
|
+
out.transport = transport;
|
|
8129
|
+
}
|
|
8130
|
+
proxy = out;
|
|
8131
|
+
break;
|
|
8132
|
+
}
|
|
7052
8133
|
case "trojan" /* Trojan */: {
|
|
7053
8134
|
const out = { ...common, password: x.password, type: "trojan" };
|
|
7054
8135
|
const transport = buildTransport(x);
|
|
@@ -7058,6 +8139,20 @@ function buildOutbound(x, settings, remark) {
|
|
|
7058
8139
|
proxy = out;
|
|
7059
8140
|
break;
|
|
7060
8141
|
}
|
|
8142
|
+
case "tuic" /* TUIC */: {
|
|
8143
|
+
const out = {
|
|
8144
|
+
...common,
|
|
8145
|
+
password: x.password,
|
|
8146
|
+
type: "tuic",
|
|
8147
|
+
udp_relay_mode: "native",
|
|
8148
|
+
uuid: x.userId
|
|
8149
|
+
};
|
|
8150
|
+
if (x.congestionControl !== "") {
|
|
8151
|
+
out.congestion_control = x.congestionControl;
|
|
8152
|
+
}
|
|
8153
|
+
proxy = out;
|
|
8154
|
+
break;
|
|
8155
|
+
}
|
|
7061
8156
|
case "wireguard" /* WireGuard */: {
|
|
7062
8157
|
const addresses = [x.selfIp];
|
|
7063
8158
|
if (x.selfIpv6 !== "") {
|
|
@@ -7170,6 +8265,17 @@ function buildOutbound(x, settings, remark) {
|
|
|
7170
8265
|
}
|
|
7171
8266
|
const tls = buildTls(x, scv);
|
|
7172
8267
|
if (tls) {
|
|
8268
|
+
if (x.type === "vless" /* VLESS */ && (x.publicKey !== "" || x.shortId !== "")) {
|
|
8269
|
+
const tlsRec = tls;
|
|
8270
|
+
if (x.fingerprint !== "") {
|
|
8271
|
+
tlsRec.utls = { enabled: true, fingerprint: x.fingerprint };
|
|
8272
|
+
}
|
|
8273
|
+
tlsRec.reality = {
|
|
8274
|
+
enabled: true,
|
|
8275
|
+
public_key: x.publicKey,
|
|
8276
|
+
short_id: x.shortId
|
|
8277
|
+
};
|
|
8278
|
+
}
|
|
7173
8279
|
proxy.tls = tls;
|
|
7174
8280
|
}
|
|
7175
8281
|
if (udp !== void 0 && !udp) {
|
|
@@ -7214,9 +8320,9 @@ function toSingBox(nodes, extraProxyGroup, settings, options) {
|
|
|
7214
8320
|
remarksList.push(remark);
|
|
7215
8321
|
}
|
|
7216
8322
|
if (!options.nodeList) {
|
|
7217
|
-
for (const
|
|
8323
|
+
for (const group2 of extraProxyGroup) {
|
|
7218
8324
|
let type;
|
|
7219
|
-
switch (
|
|
8325
|
+
switch (group2.type) {
|
|
7220
8326
|
case "select":
|
|
7221
8327
|
type = "selector";
|
|
7222
8328
|
break;
|
|
@@ -7229,18 +8335,18 @@ function toSingBox(nodes, extraProxyGroup, settings, options) {
|
|
|
7229
8335
|
continue;
|
|
7230
8336
|
}
|
|
7231
8337
|
const filtered = [];
|
|
7232
|
-
for (const rule of
|
|
8338
|
+
for (const rule of group2.proxies) {
|
|
7233
8339
|
groupGenerate(rule, nodelist, filtered, true);
|
|
7234
8340
|
}
|
|
7235
8341
|
if (filtered.length === 0) {
|
|
7236
8342
|
filtered.push("DIRECT");
|
|
7237
8343
|
}
|
|
7238
|
-
const entry = { outbounds: filtered, tag:
|
|
7239
|
-
if (
|
|
7240
|
-
entry.url =
|
|
7241
|
-
entry.interval = formatSingBoxInterval(
|
|
7242
|
-
if (
|
|
7243
|
-
entry.tolerance =
|
|
8344
|
+
const entry = { outbounds: filtered, tag: group2.name, type };
|
|
8345
|
+
if (group2.type === "url-test") {
|
|
8346
|
+
entry.url = group2.url;
|
|
8347
|
+
entry.interval = formatSingBoxInterval(group2.interval);
|
|
8348
|
+
if (group2.tolerance > 0) {
|
|
8349
|
+
entry.tolerance = group2.tolerance;
|
|
7244
8350
|
}
|
|
7245
8351
|
}
|
|
7246
8352
|
outbounds.push(entry);
|
|
@@ -7260,12 +8366,30 @@ function toSingBox(nodes, extraProxyGroup, settings, options) {
|
|
|
7260
8366
|
return JSON.stringify(doc, null, 2);
|
|
7261
8367
|
}
|
|
7262
8368
|
|
|
8369
|
+
// src/generator/surfboard.ts
|
|
8370
|
+
function toSurfboard(nodes, extraProxyGroup, settings, options) {
|
|
8371
|
+
const filtered = nodes.filter(
|
|
8372
|
+
(n) => n.type !== "hysteria2" /* Hysteria2 */ && n.type !== "anytls" /* AnyTLS */
|
|
8373
|
+
);
|
|
8374
|
+
return toSurge(filtered, extraProxyGroup, settings, {
|
|
8375
|
+
baseConf: options.baseConf,
|
|
8376
|
+
nodeList: options.nodeList,
|
|
8377
|
+
rules: options.rules,
|
|
8378
|
+
version: 5
|
|
8379
|
+
});
|
|
8380
|
+
}
|
|
8381
|
+
|
|
7263
8382
|
// src/engine.ts
|
|
7264
8383
|
var V2RAY_TYPE_MASK = 1 | 2 | 4 | 8;
|
|
7265
8384
|
function runPreprocess(nodes, settings) {
|
|
7266
8385
|
preprocessNodes(nodes, {
|
|
7267
8386
|
addEmoji: settings.addEmoji,
|
|
8387
|
+
autoCountry: settings.autoCountry,
|
|
8388
|
+
countryLocale: settings.countryLocale,
|
|
8389
|
+
countryResolver: settings.countryResolver,
|
|
7268
8390
|
emojiArray: settings.emojiArray,
|
|
8391
|
+
nameRegexArray: settings.nameRegexArray,
|
|
8392
|
+
nameRemove: settings.nameRemove,
|
|
7269
8393
|
removeEmoji: settings.removeEmoji,
|
|
7270
8394
|
renameArray: settings.renameArray,
|
|
7271
8395
|
sortFlag: settings.sortFlag
|
|
@@ -7277,56 +8401,62 @@ function runPreprocess(nodes, settings) {
|
|
|
7277
8401
|
function generate(nodes, options) {
|
|
7278
8402
|
const settings = { ...createExtraSettings(), ...options.settings };
|
|
7279
8403
|
runPreprocess(nodes, settings);
|
|
8404
|
+
const groups = resolveGroups(options);
|
|
8405
|
+
const rulesets = resolveRulesets(options, settings);
|
|
7280
8406
|
switch (options.target) {
|
|
7281
8407
|
case "clash" /* Clash */:
|
|
7282
8408
|
case "clashr" /* ClashR */: {
|
|
7283
|
-
const { doc } = buildClash(
|
|
7284
|
-
|
|
7285
|
-
options.groups ?? [],
|
|
7286
|
-
settings,
|
|
7287
|
-
options.target === "clashr" /* ClashR */
|
|
7288
|
-
);
|
|
7289
|
-
attachClashRules(doc, settings, options.rulesets);
|
|
8409
|
+
const { doc } = buildClash(nodes, groups, settings, options.target === "clashr" /* ClashR */);
|
|
8410
|
+
attachClashRules(doc, settings, rulesets);
|
|
7290
8411
|
return stringifyClash(doc);
|
|
7291
8412
|
}
|
|
7292
8413
|
case "surge" /* Surge */: {
|
|
7293
|
-
const surgeVersion = options.surgeVersion ??
|
|
7294
|
-
const rules =
|
|
7295
|
-
return toSurge(nodes,
|
|
8414
|
+
const surgeVersion = options.surgeVersion ?? 5;
|
|
8415
|
+
const rules = rulesets ? rulesetToSurgeRules(rulesets, surgeVersion) : void 0;
|
|
8416
|
+
return toSurge(nodes, groups, settings, {
|
|
7296
8417
|
baseConf: options.baseConf ?? "",
|
|
7297
8418
|
nodeList: settings.nodeList,
|
|
7298
8419
|
rules,
|
|
7299
8420
|
version: surgeVersion
|
|
7300
8421
|
});
|
|
7301
8422
|
}
|
|
7302
|
-
case "quanx" /* QuantumultX */:
|
|
7303
|
-
|
|
8423
|
+
case "quanx" /* QuantumultX */: {
|
|
8424
|
+
const rules = rulesets ? rulesetToSurgeRules(rulesets, -1) : void 0;
|
|
8425
|
+
return toQuanX(nodes, groups, settings, {
|
|
7304
8426
|
baseConf: options.baseConf ?? "",
|
|
7305
|
-
nodeList: settings.nodeList
|
|
8427
|
+
nodeList: settings.nodeList,
|
|
8428
|
+
rules
|
|
7306
8429
|
});
|
|
7307
|
-
|
|
7308
|
-
|
|
8430
|
+
}
|
|
8431
|
+
case "quan" /* Quantumult */: {
|
|
8432
|
+
const rules = rulesets ? rulesetToSurgeRules(rulesets, -2) : void 0;
|
|
8433
|
+
return toQuan(nodes, groups, settings, {
|
|
7309
8434
|
baseConf: options.baseConf ?? "",
|
|
7310
|
-
nodeList: settings.nodeList
|
|
8435
|
+
nodeList: settings.nodeList,
|
|
8436
|
+
rules
|
|
7311
8437
|
});
|
|
7312
|
-
|
|
7313
|
-
|
|
8438
|
+
}
|
|
8439
|
+
case "loon" /* Loon */: {
|
|
8440
|
+
const rules = rulesets ? rulesetToSurgeRules(rulesets, -4) : void 0;
|
|
8441
|
+
return toLoon(nodes, groups, settings, {
|
|
7314
8442
|
baseConf: options.baseConf ?? "",
|
|
7315
|
-
nodeList: settings.nodeList
|
|
8443
|
+
nodeList: settings.nodeList,
|
|
8444
|
+
rules
|
|
7316
8445
|
});
|
|
8446
|
+
}
|
|
7317
8447
|
case "singbox" /* SingBox */:
|
|
7318
|
-
return toSingBox(nodes,
|
|
8448
|
+
return toSingBox(nodes, groups, settings, {
|
|
7319
8449
|
baseConf: options.baseConf ?? "",
|
|
7320
8450
|
nodeList: settings.nodeList,
|
|
7321
8451
|
overwriteOriginalRules: settings.overwriteOriginalRules,
|
|
7322
|
-
rulesets
|
|
8452
|
+
rulesets
|
|
7323
8453
|
});
|
|
7324
8454
|
case "mellow" /* Mellow */:
|
|
7325
|
-
return toMellow(nodes,
|
|
8455
|
+
return toMellow(nodes, groups, settings, {
|
|
7326
8456
|
baseConf: options.baseConf ?? "",
|
|
7327
8457
|
nodeList: settings.nodeList,
|
|
7328
8458
|
overwriteOriginalRules: settings.overwriteOriginalRules,
|
|
7329
|
-
rulesets
|
|
8459
|
+
rulesets
|
|
7330
8460
|
});
|
|
7331
8461
|
case "v2ray" /* V2Ray */:
|
|
7332
8462
|
return proxyToSingle(nodes, 4, settings);
|
|
@@ -7340,6 +8470,16 @@ function generate(nodes, options) {
|
|
|
7340
8470
|
return proxyToSingle(nodes, 2, settings);
|
|
7341
8471
|
case "ssd" /* SSD */:
|
|
7342
8472
|
return proxyToSsd(nodes, "", "");
|
|
8473
|
+
case "sssub" /* SSSub */:
|
|
8474
|
+
return proxyToSsSub(nodes, options.baseConf ?? "");
|
|
8475
|
+
case "surfboard" /* Surfboard */: {
|
|
8476
|
+
const rules = rulesets ? rulesetToSurgeRules(rulesets, options.surgeVersion ?? 5) : void 0;
|
|
8477
|
+
return toSurfboard(nodes, groups, settings, {
|
|
8478
|
+
baseConf: options.baseConf ?? "",
|
|
8479
|
+
nodeList: settings.nodeList,
|
|
8480
|
+
rules
|
|
8481
|
+
});
|
|
8482
|
+
}
|
|
7343
8483
|
case "nodelist" /* NodeList */: {
|
|
7344
8484
|
settings.nodeList = true;
|
|
7345
8485
|
return proxyToSingle(nodes, V2RAY_TYPE_MASK, settings);
|
|
@@ -7351,7 +8491,28 @@ function generate(nodes, options) {
|
|
|
7351
8491
|
function toSip008(nodes, baseConf = "") {
|
|
7352
8492
|
return proxyToSsSub(nodes, baseConf);
|
|
7353
8493
|
}
|
|
8494
|
+
function resolveGroups(options) {
|
|
8495
|
+
if (options.includeRules !== false && (!options.groups || options.groups.length === 0)) {
|
|
8496
|
+
return getDefaultProxyGroups();
|
|
8497
|
+
}
|
|
8498
|
+
return options.groups ?? [];
|
|
8499
|
+
}
|
|
8500
|
+
function resolveRulesets(options, settings) {
|
|
8501
|
+
if (options.includeRules === false) {
|
|
8502
|
+
return void 0;
|
|
8503
|
+
}
|
|
8504
|
+
if (!settings.enableRuleGenerator || settings.nodeList) {
|
|
8505
|
+
return void 0;
|
|
8506
|
+
}
|
|
8507
|
+
if (options.rulesets && options.rulesets.length > 0) {
|
|
8508
|
+
return options.rulesets;
|
|
8509
|
+
}
|
|
8510
|
+
return getDefaultRulesets();
|
|
8511
|
+
}
|
|
7354
8512
|
function attachClashRules(doc, settings, rulesets) {
|
|
8513
|
+
if (!settings.enableRuleGenerator || settings.nodeList) {
|
|
8514
|
+
return;
|
|
8515
|
+
}
|
|
7355
8516
|
if (!rulesets || rulesets.length === 0) {
|
|
7356
8517
|
return;
|
|
7357
8518
|
}
|