| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910 | const Protocols = {    VMESS: 'vmess',    VLESS: 'vless',    TROJAN: 'trojan',    SHADOWSOCKS: 'shadowsocks',    DOKODEMO: 'dokodemo-door',    MTPROTO: 'mtproto',    SOCKS: 'socks',    HTTP: 'http',};const VmessMethods = {    AES_128_GCM: 'aes-128-gcm',    CHACHA20_POLY1305: 'chacha20-poly1305',    AUTO: 'auto',    NONE: 'none',};const SSMethods = {    // AES_256_CFB: 'aes-256-cfb',    // AES_128_CFB: 'aes-128-cfb',    // CHACHA20: 'chacha20',    // CHACHA20_IETF: 'chacha20-ietf',    CHACHA20_POLY1305: 'chacha20-poly1305',    AES_256_GCM: 'aes-256-gcm',    AES_128_GCM: 'aes-128-gcm',	BLAKE3_AES_128_GCM: '2022-blake3-aes-128-gcm',    BLAKE3_AES_256_GCM: '2022-blake3-aes-256-gcm',    BLAKE3_CHACHA20_POLY1305: '2022-blake3-chacha20-poly1305',};const RULE_IP = {    PRIVATE: 'geoip:private',    CN: 'geoip:cn',};const RULE_DOMAIN = {    ADS: 'geosite:category-ads',    ADS_ALL: 'geosite:category-ads-all',    CN: 'geosite:cn',    GOOGLE: 'geosite:google',    FACEBOOK: 'geosite:facebook',    SPEEDTEST: 'geosite:speedtest',};const XTLS_FLOW_CONTROL = {    ORIGIN: "xtls-rprx-origin",    DIRECT: "xtls-rprx-direct",};const TLS_FLOW_CONTROL = {    VISION: "xtls-rprx-vision",};const TLS_VERSION_OPTION = {    TLS10: "1.0",    TLS11: "1.1",    TLS12: "1.2",    TLS13: "1.3",};const TLS_CIPHER_OPTION = {    RSA_AES_128_CBC: "TLS_RSA_WITH_AES_128_CBC_SHA",    RSA_AES_256_CBC: "TLS_RSA_WITH_AES_256_CBC_SHA",    RSA_AES_128_GCM: "TLS_RSA_WITH_AES_128_GCM_SHA256",    RSA_AES_256_GCM: "TLS_RSA_WITH_AES_256_GCM_SHA384",    AES_128_GCM: "TLS_AES_128_GCM_SHA256",    AES_256_GCM: "TLS_AES_256_GCM_SHA384",    CHACHA20_POLY1305: "TLS_CHACHA20_POLY1305_SHA256",    ECDHE_ECDSA_AES_128_CBC: "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",    ECDHE_ECDSA_AES_256_CBC: "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",    ECDHE_RSA_AES_128_CBC: "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",    ECDHE_RSA_AES_256_CBC: "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",    ECDHE_ECDSA_AES_128_GCM: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",    ECDHE_ECDSA_AES_256_GCM: "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",    ECDHE_RSA_AES_128_GCM: "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",    ECDHE_RSA_AES_256_GCM: "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",    ECDHE_ECDSA_CHACHA20_POLY1305: "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",    ECDHE_RSA_CHACHA20_POLY1305: "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",};const UTLS_FINGERPRINT = {    UTLS_CHROME: "chrome",    UTLS_FIREFOX: "firefox",    UTLS_SAFARI: "safari",    UTLS_IOS: "ios",    UTLS_android: "android",    UTLS_EDGE: "edge",    UTLS_360: "360",    UTLS_QQ: "qq",    UTLS_RANDOM: "random",    UTLS_RANDOMIZED: "randomized",};const ALPN_OPTION = {    H2: "h2",    HTTP1: "http/1.1",    BOTH: "h2,http/1.1",};Object.freeze(Protocols);Object.freeze(VmessMethods);Object.freeze(SSMethods);Object.freeze(RULE_IP);Object.freeze(RULE_DOMAIN);Object.freeze(XTLS_FLOW_CONTROL);Object.freeze(TLS_FLOW_CONTROL);Object.freeze(TLS_VERSION_OPTION);Object.freeze(TLS_CIPHER_OPTION);Object.freeze(UTLS_FINGERPRINT);Object.freeze(ALPN_OPTION);class XrayCommonClass {    static toJsonArray(arr) {        return arr.map(obj => obj.toJson());    }    static fromJson() {        return new XrayCommonClass();    }    toJson() {        return this;    }    toString(format=true) {        return format ? JSON.stringify(this.toJson(), null, 2) : JSON.stringify(this.toJson());    }    static toHeaders(v2Headers) {        let newHeaders = [];        if (v2Headers) {            Object.keys(v2Headers).forEach(key => {                let values = v2Headers[key];                if (typeof(values) === 'string') {                    newHeaders.push({ name: key, value: values });                } else {                    for (let i = 0; i < values.length; ++i) {                        newHeaders.push({ name: key, value: values[i] });                    }                }            });        }        return newHeaders;    }    static toV2Headers(headers, arr=true) {        let v2Headers = {};        for (let i = 0; i < headers.length; ++i) {            let name = headers[i].name;            let value = headers[i].value;            if (ObjectUtil.isEmpty(name) || ObjectUtil.isEmpty(value)) {                continue;            }            if (!(name in v2Headers)) {                v2Headers[name] = arr ? [value] : value;            } else {                if (arr) {                    v2Headers[name].push(value);                } else {                    v2Headers[name] = value;                }            }        }        return v2Headers;    }}class TcpStreamSettings extends XrayCommonClass {    constructor(        type = 'none',        acceptProxyProtocol = false,        request = new TcpStreamSettings.TcpRequest(),        response = new TcpStreamSettings.TcpResponse(),    ) {        super();        this.type = type;        this.request = request;        this.response = response;        this.acceptProxyProtocol = acceptProxyProtocol;    }    static fromJson(json = {}) {        let header = json.header;        if (!header) {            header = {};        }        return new TcpStreamSettings(            header.type,            json.acceptProxyProtocol,            TcpStreamSettings.TcpRequest.fromJson(header.request),            TcpStreamSettings.TcpResponse.fromJson(header.response),        );    }    toJson() {        return {            header: {                type: this.type,                request: this.type === 'http' ? this.request.toJson() : undefined,                response: this.type === 'http' ? this.response.toJson() : undefined,            },            acceptProxyProtocol: this.acceptProxyProtocol,        };    }}TcpStreamSettings.TcpRequest = class extends XrayCommonClass {    constructor(version = '1.1',        method = 'GET',        path = ['/'],        headers = [],    ) {        super();        this.version = version;        this.method = method;        this.path = path.length === 0 ? ['/'] : path;        this.headers = headers;    }    addPath(path) {        this.path.push(path);    }    removePath(index) {        this.path.splice(index, 1);    }    addHeader(name, value) {        this.headers.push({ name: name, value: value });    }    getHeader(name) {        for (const header of this.headers) {            if (header.name.toLowerCase() === name.toLowerCase()) {                return header.value;            }        }        return null;    }    removeHeader(index) {        this.headers.splice(index, 1);    }    static fromJson(json = {}) {        return new TcpStreamSettings.TcpRequest(            json.version,            json.method,            json.path,            XrayCommonClass.toHeaders(json.headers),        );    }    toJson() {        return {            method: this.method,            path: ObjectUtil.clone(this.path),            headers: XrayCommonClass.toV2Headers(this.headers),        };    }};TcpStreamSettings.TcpResponse = class extends XrayCommonClass {    constructor(version = '1.1',        status = '200',        reason = 'OK',        headers = [],    ) {        super();        this.version = version;        this.status = status;        this.reason = reason;        this.headers = headers;    }    addHeader(name, value) {        this.headers.push({ name: name, value: value });    }    removeHeader(index) {        this.headers.splice(index, 1);    }    static fromJson(json = {}) {        return new TcpStreamSettings.TcpResponse(            json.version,            json.status,            json.reason,            XrayCommonClass.toHeaders(json.headers),        );    }    toJson() {        return {            version: this.version,            status: this.status,            reason: this.reason,            headers: XrayCommonClass.toV2Headers(this.headers),        };    }};class KcpStreamSettings extends XrayCommonClass {    constructor(mtu=1350, tti=20,                uplinkCapacity=5,                downlinkCapacity=20,                congestion=false,                readBufferSize=2,                writeBufferSize=2,                type='none',                seed=RandomUtil.randomSeq(10),                ) {        super();        this.mtu = mtu;        this.tti = tti;        this.upCap = uplinkCapacity;        this.downCap = downlinkCapacity;        this.congestion = congestion;        this.readBuffer = readBufferSize;        this.writeBuffer = writeBufferSize;        this.type = type;        this.seed = seed;    }    static fromJson(json={}) {        return new KcpStreamSettings(            json.mtu,            json.tti,            json.uplinkCapacity,            json.downlinkCapacity,            json.congestion,            json.readBufferSize,            json.writeBufferSize,            ObjectUtil.isEmpty(json.header) ? 'none' : json.header.type,            json.seed,        );    }    toJson() {        return {            mtu: this.mtu,            tti: this.tti,            uplinkCapacity: this.upCap,            downlinkCapacity: this.downCap,            congestion: this.congestion,            readBufferSize: this.readBuffer,            writeBufferSize: this.writeBuffer,            header: {                type: this.type,            },            seed: this.seed,        };    }}class WsStreamSettings extends XrayCommonClass {    constructor(acceptProxyProtocol=false, path='/', headers=[]) {        super();        this.acceptProxyProtocol = acceptProxyProtocol;        this.path = path;        this.headers = headers;    }    addHeader(name, value) {        this.headers.push({ name: name, value: value });    }    getHeader(name) {        for (const header of this.headers) {            if (header.name.toLowerCase() === name.toLowerCase()) {                return header.value;            }        }        return null;    }    removeHeader(index) {        this.headers.splice(index, 1);    }    static fromJson(json={}) {        return new WsStreamSettings(            json.acceptProxyProtocol,            json.path,            XrayCommonClass.toHeaders(json.headers),        );    }    toJson() {        return {            acceptProxyProtocol: this.acceptProxyProtocol,            path: this.path,            headers: XrayCommonClass.toV2Headers(this.headers, false),        };    }}class HttpStreamSettings extends XrayCommonClass {    constructor(path='/', host=['']) {        super();        this.path = path;        this.host = host.length === 0 ? [''] : host;    }    addHost(host) {        this.host.push(host);    }    removeHost(index) {        this.host.splice(index, 1);    }    static fromJson(json={}) {        return new HttpStreamSettings(json.path, json.host);    }    toJson() {        let host = [];        for (let i = 0; i < this.host.length; ++i) {            if (!ObjectUtil.isEmpty(this.host[i])) {                host.push(this.host[i]);            }        }        return {            path: this.path,            host: host,        }    }}class QuicStreamSettings extends XrayCommonClass {    constructor(security=VmessMethods.NONE,                key='', type='none') {        super();        this.security = security;        this.key = key;        this.type = type;    }    static fromJson(json={}) {        return new QuicStreamSettings(            json.security,            json.key,            json.header ? json.header.type : 'none',        );    }    toJson() {        return {            security: this.security,            key: this.key,            header: {                type: this.type,            }        }    }}class GrpcStreamSettings extends XrayCommonClass {    constructor(serviceName="") {        super();        this.serviceName = serviceName;    }    static fromJson(json={}) {        return new GrpcStreamSettings(json.serviceName);    }    toJson() {        return {            serviceName: this.serviceName,        }    }}class TlsStreamSettings extends XrayCommonClass {    constructor(serverName = '', minVersion = TLS_VERSION_OPTION.TLS12, maxVersion = TLS_VERSION_OPTION.TLS13,        cipherSuites = '',        certificates = [new TlsStreamSettings.Cert()], alpn=[''] ,settings=[new TlsStreamSettings.Settings()]) {        super();        this.server = serverName;        this.minVersion = minVersion;        this.maxVersion = maxVersion;        this.cipherSuites = cipherSuites;        this.certs = certificates;        this.alpn = alpn;		this.settings = settings;    }    addCert(cert) {        this.certs.push(cert);    }    removeCert(index) {        this.certs.splice(index, 1);    }    static fromJson(json={}) {        let certs;		let settings;        if (!ObjectUtil.isEmpty(json.certificates)) {            certs = json.certificates.map(cert => TlsStreamSettings.Cert.fromJson(cert));        }		if (!ObjectUtil.isEmpty(json.settings)) {            let values = json.settings[0];            settings = [new TlsStreamSettings.Settings(values.allowInsecure , values.fingerprint, values.serverName)];        }        return new TlsStreamSettings(            json.serverName,            json.minVersion,            json.maxVersion,            json.cipherSuites,            certs,            json.alpn,			settings,        );    }    toJson() {        return {            serverName: this.server,            minVersion: this.minVersion,            maxVersion: this.maxVersion,            cipherSuites: this.cipherSuites,            certificates: TlsStreamSettings.toJsonArray(this.certs),            alpn: this.alpn,            settings: TlsStreamSettings.toJsonArray(this.settings),			        };    }}TlsStreamSettings.Cert = class extends XrayCommonClass {    constructor(useFile=true, certificateFile='', keyFile='', certificate='', key='') {        super();        this.useFile = useFile;        this.certFile = certificateFile;        this.keyFile = keyFile;        this.cert = certificate instanceof Array ? certificate.join('\n') : certificate;        this.key = key instanceof Array ? key.join('\n') : key;    }    static fromJson(json={}) {        if ('certificateFile' in json && 'keyFile' in json) {            return new TlsStreamSettings.Cert(                true,                json.certificateFile,                json.keyFile,            );        } else {            return new TlsStreamSettings.Cert(                false, '', '',                json.certificate.join('\n'),                json.key.join('\n'),            );        }    }    toJson() {        if (this.useFile) {            return {                certificateFile: this.certFile,                keyFile: this.keyFile,            };        } else {            return {                certificate: this.cert.split('\n'),                key: this.key.split('\n'),            };        }    }};TlsStreamSettings.Settings = class extends XrayCommonClass {  constructor(insecure = false, fingerprint = '', serverName = '') {    super();    this.inSecure = insecure;    this.fingerprint = fingerprint;    this.serverName = serverName;  }  static fromJson(json = {}) {    return new TlsStreamSettings.Settings(      json.allowInsecure,      json.fingerprint,      json.servername,    );  }  toJson() {    return {      allowInsecure: this.inSecure,      fingerprint: this.fingerprint,      serverName: this.serverName,    };  }};class StreamSettings extends XrayCommonClass {    constructor(network='tcp',		security='none',		tlsSettings=new TlsStreamSettings(),		tcpSettings=new TcpStreamSettings(),		kcpSettings=new KcpStreamSettings(),		wsSettings=new WsStreamSettings(),		httpSettings=new HttpStreamSettings(),		quicSettings=new QuicStreamSettings(),		grpcSettings=new GrpcStreamSettings(),		) {        super();        this.network = network;        this.security = security;        this.tls = tlsSettings;        this.tcp = tcpSettings;        this.kcp = kcpSettings;        this.ws = wsSettings;        this.http = httpSettings;        this.quic = quicSettings;        this.grpc = grpcSettings;    }    get isTls() {        return this.security === 'tls';    }    set isTls(isTls) {        if (isTls) {            this.security = 'tls';        } else {            this.security = 'none';        }    }    get isXTLS() {        return this.security === "xtls";    }    set isXTLS(isXTLS) {        if (isXTLS) {            this.security = 'xtls';        } else {            this.security = 'none';        }    }    static fromJson(json={}) {        let tls;        if (json.security === "xtls") {            tls = TlsStreamSettings.fromJson(json.XTLSSettings);        } else {            tls = TlsStreamSettings.fromJson(json.tlsSettings);        }        return new StreamSettings(            json.network,            json.security,            tls,            TcpStreamSettings.fromJson(json.tcpSettings),            KcpStreamSettings.fromJson(json.kcpSettings),            WsStreamSettings.fromJson(json.wsSettings),            HttpStreamSettings.fromJson(json.httpSettings),            QuicStreamSettings.fromJson(json.quicSettings),            GrpcStreamSettings.fromJson(json.grpcSettings),        );    }    toJson() {        const network = this.network;        return {            network: network,            security: this.security,            tlsSettings: this.isTls ? this.tls.toJson() : undefined,            XTLSSettings: this.isXTLS ? this.tls.toJson() : undefined,            tcpSettings: network === 'tcp' ? this.tcp.toJson() : undefined,            kcpSettings: network === 'kcp' ? this.kcp.toJson() : undefined,            wsSettings: network === 'ws' ? this.ws.toJson() : undefined,            httpSettings: network === 'http' ? this.http.toJson() : undefined,            quicSettings: network === 'quic' ? this.quic.toJson() : undefined,            grpcSettings: network === 'grpc' ? this.grpc.toJson() : undefined,        };    }}class Sniffing extends XrayCommonClass {    constructor(enabled=true, destOverride=['http', 'tls']) {        super();        this.enabled = enabled;        this.destOverride = destOverride;    }    static fromJson(json={}) {        let destOverride = ObjectUtil.clone(json.destOverride);        if (!ObjectUtil.isEmpty(destOverride) && !ObjectUtil.isArrEmpty(destOverride)) {            if (ObjectUtil.isEmpty(destOverride[0])) {                destOverride = ['http', 'tls'];            }        }        return new Sniffing(            !!json.enabled,            destOverride,        );    }}class Inbound extends XrayCommonClass {    constructor(port=RandomUtil.randomIntRange(10000, 60000),                listen='',                protocol=Protocols.VLESS,                settings=null,                streamSettings=new StreamSettings(),                tag='',                sniffing=new Sniffing(),                clientStats='',                ) {        super();        this.port = port;        this.listen = listen;        this._protocol = protocol;        this.settings = ObjectUtil.isEmpty(settings) ? Inbound.Settings.getSettings(protocol) : settings;        this.stream = streamSettings;        this.tag = tag;        this.sniffing = sniffing;        this.clientStats = clientStats;    }    getClientStats() {        return this.clientStats;    }    get protocol() {        return this._protocol;    }        set protocol(protocol) {        this._protocol = protocol;        this.settings = Inbound.Settings.getSettings(protocol);        if (protocol === Protocols.TROJAN) {            this.tls = false;        }    }    get tls() {        return this.stream.security === 'tls';    }    set tls(isTls) {        if (isTls) {            this.stream.security = 'tls';        } else {            this.stream.security = 'none';        }    }    get XTLS() {        return this.stream.security === 'xtls';    }    set XTLS(isXTLS) {        if (isXTLS) {            this.stream.security = 'xtls';        } else {            this.stream.security = 'none';        }    }    get network() {        return this.stream.network;    }    set network(network) {        this.stream.network = network;    }    get isTcp() {        return this.network === "tcp";    }    get isWs() {        return this.network === "ws";    }    get isKcp() {        return this.network === "kcp";    }    get isQuic() {        return this.network === "quic"    }    get isGrpc() {        return this.network === "grpc";    }    get isH2() {        return this.network === "http";    }    // VMess & VLess    get uuid() {        switch (this.protocol) {            case Protocols.VMESS:                return this.settings.vmesses[0].id;            case Protocols.VLESS:                return this.settings.vlesses[0].id;            default:                return "";        }    }    // VLess & Trojan    get flow() {        switch (this.protocol) {            case Protocols.VLESS:                return this.settings.vlesses[0].flow;            case Protocols.TROJAN:                return this.settings.trojans[0].flow;            default:                return "";        }    }    // VMess    get alterId() {        switch (this.protocol) {            case Protocols.VMESS:                return this.settings.vmesses[0].alterId;            default:                return "";        }    }    // Socks & HTTP    get username() {        switch (this.protocol) {            case Protocols.SOCKS:            case Protocols.HTTP:                return this.settings.accounts[0].user;            default:                return "";        }    }    // Trojan & Shadowsocks & Socks & HTTP    get password() {        switch (this.protocol) {            case Protocols.TROJAN:                return this.settings.trojans[0].password;            case Protocols.SHADOWSOCKS:                return this.settings.password;            case Protocols.SOCKS:            case Protocols.HTTP:                return this.settings.accounts[0].pass;            default:                return "";        }    }    // Shadowsocks    get method() {        switch (this.protocol) {            case Protocols.SHADOWSOCKS:                return this.settings.method;            default:                return "";        }    }    get serverName() {        if (this.stream.isTls || this.stream.isXTLS) {            return this.stream.tls.server;        }        return "";    }    get host() {        if (this.isTcp) {            return this.stream.tcp.request.getHeader("Host");        } else if (this.isWs) {            return this.stream.ws.getHeader("Host");        } else if (this.isH2) {            return this.stream.http.host[0];        }        return null;    }    get path() {        if (this.isTcp) {            return this.stream.tcp.request.path[0];        } else if (this.isWs) {            return this.stream.ws.path;        } else if (this.isH2) {            return this.stream.http.path[0];        }        return null;    }    get quicSecurity() {        return this.stream.quic.security;    }    get quicKey() {        return this.stream.quic.key;    }    get quicType() {        return this.stream.quic.type;    }    get kcpType() {        return this.stream.kcp.type;    }    get kcpSeed() {        return this.stream.kcp.seed;    }    get serviceName() {        return this.stream.grpc.serviceName;    }    isExpiry(index) {        switch (this.protocol) {            case Protocols.VMESS:                if(this.settings.vmesses[index]._expiryTime != null)                    return this.settings.vmesses[index]._expiryTime < new Date().getTime();                return false            case Protocols.VLESS:                if(this.settings.vlesses[index]._expiryTime != null)                    return this.settings.vlesses[index]._expiryTime < new Date().getTime();                return false                case Protocols.TROJAN:                    if(this.settings.trojans[index]._expiryTime != null)                        return this.settings.trojans[index]._expiryTime < new Date().getTime();                    return false            default:                return false;        }    }    canEnableTls() {        switch (this.protocol) {            case Protocols.VMESS:            case Protocols.VLESS:            case Protocols.TROJAN:            case Protocols.SHADOWSOCKS:                break;            default:                return false;        }        switch (this.network) {            case "tcp":            case "ws":            case "http":            case "quic":            case "grpc":                return true;            default:                return false;        }    }	    //this is used for xtls-rprx-vision    canEnableTlsFlow() {        if ((this.stream.security === 'tls') && (this.network === "tcp")) {            switch (this.protocol) {                case Protocols.VLESS:                    return true;                default:                    return false;            }        }        return false;    }	    canSetTls() {        return this.canEnableTls();    }         canEnableXTLS() {        switch (this.protocol) {            case Protocols.VLESS:            case Protocols.TROJAN:                break;            default:                return false;        }        return this.network === "tcp";    }    canEnableStream() {        switch (this.protocol) {            case Protocols.VMESS:            case Protocols.VLESS:			case Protocols.TROJAN:            case Protocols.SHADOWSOCKS:                return true;            default:                return false;        }    }    canSniffing() {        switch (this.protocol) {            case Protocols.VMESS:            case Protocols.VLESS:            case Protocols.TROJAN:            case Protocols.SHADOWSOCKS:                return true;            default:                return false;        }    }    reset() {        this.port = RandomUtil.randomIntRange(10000, 60000);        this.listen = '';        this.protocol = Protocols.VMESS;        this.settings = Inbound.Settings.getSettings(Protocols.VMESS);        this.stream = new StreamSettings();        this.tag = '';        this.sniffing = new Sniffing();    }    genVmessLink(address='', remark='', clientIndex=0) {        if (this.protocol !== Protocols.VMESS) {            return '';        }        let network = this.stream.network;        let type = 'none';        let host = '';        let path = '';        if (network === 'tcp') {            let tcp = this.stream.tcp;            type = tcp.type;            if (type === 'http') {                let request = tcp.request;                path = request.path.join(',');                let index = request.headers.findIndex(header => header.name.toLowerCase() === 'host');                if (index >= 0) {                    host = request.headers[index].value;                }            }        } else if (network === 'kcp') {            let kcp = this.stream.kcp;            type = kcp.type;            path = kcp.seed;        } else if (network === 'ws') {            let ws = this.stream.ws;            path = ws.path;            let index = ws.headers.findIndex(header => header.name.toLowerCase() === 'host');            if (index >= 0) {                host = ws.headers[index].value;            }        } else if (network === 'http') {            network = 'h2';            path = this.stream.http.path;            host = this.stream.http.host.join(',');        } else if (network === 'quic') {            type = this.stream.quic.type;            host = this.stream.quic.security;            path = this.stream.quic.key;        } else if (network === 'grpc') {            path = this.stream.grpc.serviceName;        }        if (this.stream.security === 'tls') {            if (!ObjectUtil.isEmpty(this.stream.tls.server)) {                address = this.stream.tls.server;            }        }		        let obj = {            v: '2',            ps: remark,            add: address,            port: this.port,            id: this.settings.vmesses[clientIndex].id,            aid: this.settings.vmesses[clientIndex].alterId,            net: network,            type: type,            host: host,            path: path,            tls: this.stream.security,			sni: this.stream.tls.settings[0]['serverName'],            fp: this.stream.tls.settings[0]['fingerprint'],            alpn: this.stream.tls.alpn[0],        };        return 'vmess://' + base64(JSON.stringify(obj, null, 2));    }    genVLESSLink(address = '', remark='', clientIndex=0) {        const settings = this.settings;        const uuid = settings.vlesses[clientIndex].id;        const port = this.port;        const type = this.stream.network;        const params = new Map();        params.set("type", this.stream.network);		params.set("security", this.stream.security);        if (this.XTLS) {            params.set("security", "xtls");        } else {            params.set("security", this.stream.security);        }        switch (type) {            case "tcp":                const tcp = this.stream.tcp;                if (tcp.type === 'http') {                    const request = tcp.request;                    params.set("path", request.path.join(','));                    const index = request.headers.findIndex(header => header.name.toLowerCase() === 'host');                    if (index >= 0) {                        const host = request.headers[index].value;                        params.set("host", host);                    }                    params.set("headerType", 'http');                }                break;            case "kcp":                const kcp = this.stream.kcp;                params.set("headerType", kcp.type);                params.set("seed", kcp.seed);                break;            case "ws":                const ws = this.stream.ws;                params.set("path", ws.path);                const index = ws.headers.findIndex(header => header.name.toLowerCase() === 'host');                if (index >= 0) {                    const host = ws.headers[index].value;                    params.set("host", host);                }                break;            case "http":                const http = this.stream.http;                params.set("path", http.path);                params.set("host", http.host);                break;            case "quic":                const quic = this.stream.quic;                params.set("quicSecurity", quic.security);                params.set("key", quic.key);                params.set("headerType", quic.type);                break;            case "grpc":                const grpc = this.stream.grpc;                params.set("serviceName", grpc.serviceName);                break;        }        if (this.stream.security === 'tls') {            if (!ObjectUtil.isEmpty(this.stream.tls.server)) {                address = this.stream.tls.server;                params.set("fp" , this.stream.tls.settings[0]['fingerprint']);                params.set("alpn", this.stream.tls.alpn[0]);                if (this.stream.tls.settings[0]['serverName'] !== ''){                    params.set("sni", this.stream.tls.settings[0]['serverName']);                }                else{                   params.set("sni", address);                }               if (type === "tcp" && this.settings.vlesses[clientIndex].flow.length > 0) {                    params.set("flow", this.settings.vlesses[clientIndex].flow);                }			}        }				 if (this.xtls) {            if (this.stream.security === 'xtls') {                if (!ObjectUtil.isEmpty(this.stream.tls.server)) {                    address = this.stream.tls.server;                    if (type === "tcp") {                        params.set("flow", this.settings.vlesses[clientIndex].flow);                    }                }			}        }        const link = `vless://${uuid}@${address}:${port}`;        const url = new URL(link);        for (const [key, value] of params) {            url.searchParams.set(key, value)        }        url.hash = encodeURIComponent(remark);        return url.toString();    }    genSSLink(address = '', remark = '') {        let settings = this.settings;        const server = this.stream.tls.server;        if (!ObjectUtil.isEmpty(server)) {            address = server;        }        if (settings.method == SSMethods.BLAKE3_AES_128_GCM || settings.method == SSMethods.BLAKE3_AES_256_GCM || settings.method == SSMethods.BLAKE3_CHACHA20_POLY1305) {            return `ss://${settings.method}:${settings.password}@${address}:${this.port}#${encodeURIComponent(remark)}`;        } else {            return 'ss://' + safeBase64(settings.method + ':' + settings.password + '@' + address + ':' + this.port)                + '#' + encodeURIComponent(remark);        }    }    genTrojanLink(address = '', remark = '', clientIndex = 0) {        let settings = this.settings;        const port = this.port;        const type = this.stream.network;        const params = new Map();        switch (type) {            case "tcp":                const tcp = this.stream.tcp;                if (tcp.type === 'http') {                    const request = tcp.request;                    params.set("path", request.path.join(','));                    const index = request.headers.findIndex(header => header.name.toLowerCase() === 'host');                    if (index >= 0) {                        const host = request.headers[index].value;                        params.set("host", host);                    }                    params.set("headerType", 'http');                }                break;            case "kcp":                const kcp = this.stream.kcp;                params.set("headerType", kcp.type);                params.set("seed", kcp.seed);                break;            case "ws":                const ws = this.stream.ws;                params.set("path", ws.path);                const index = ws.headers.findIndex(header => header.name.toLowerCase() === 'host');                if (index >= 0) {                    const host = ws.headers[index].value;                    params.set("host", host);                }                break;            case "http":                const http = this.stream.http;                params.set("path", http.path);                params.set("host", http.host);                break;            case "quic":                const quic = this.stream.quic;                params.set("quicSecurity", quic.security);                params.set("key", quic.key);                params.set("headerType", quic.type);                break;            case "grpc":                const grpc = this.stream.grpc;                params.set("serviceName", grpc.serviceName);                break;        }        if (this.stream.security === 'tls') {            if (!ObjectUtil.isEmpty(this.stream.tls.server)) {                address = this.stream.tls.server;                params.set("fp" , this.stream.tls.settings[0]['fingerprint']);                params.set("alpn", this.stream.tls.alpn[0]);                if (this.stream.tls.settings[0]['serverName'] !== ''){                    params.set("sni", this.stream.tls.settings[0]['serverName']);                }                else{                   params.set("sni", address);                }			}        }				if (this.stream.security === 'xtls') {            if (!ObjectUtil.isEmpty(this.stream.tls.server)) {                address = this.stream.tls.server;                 if (type === "tcp" && this.settings.trojans[clientIndex].flow.length > 0) {                    params.set("flow", this.settings.trojans[clientIndex].flow);                }			}        }                const link = `trojan://${settings.trojans[clientIndex].password}@${address}:${this.port}#${encodeURIComponent(remark)}`;        const url = new URL(link);        for (const [key, value] of params) {            url.searchParams.set(key, value)        }        url.hash = encodeURIComponent(remark);        return url.toString();    }    genLink(address='', remark='', clientIndex=0) {        switch (this.protocol) {            case Protocols.VMESS:                if (this.settings.vmesses[clientIndex].email != ""){                    remark += '-' + this.settings.vmesses[clientIndex].email                }                return this.genVmessLink(address, remark, clientIndex);            case Protocols.VLESS:                if (this.settings.vlesses[clientIndex].email != ""){                    remark += '-' + this.settings.vlesses[clientIndex].email                }                return this.genVLESSLink(address, remark, clientIndex);            case Protocols.SHADOWSOCKS: return this.genSSLink(address, remark);            case Protocols.TROJAN:                if (this.settings.trojans[clientIndex].email != ""){                    remark += '-' + this.settings.trojans[clientIndex].email                }                return this.genTrojanLink(address, remark, clientIndex);            default: return '';        }    }    genInboundLinks(address = '', remark = '') {    let link = '';        switch (this.protocol) {            case Protocols.VMESS:            case Protocols.VLESS:            case Protocols.TROJAN:                JSON.parse(this.settings).clients.forEach((_,index) => {                    link += this.genLink(address, remark, index) + '\r\n';                });                return link;            case Protocols.SHADOWSOCKS:                return (this.genSSLink(address, remark) + '\r\n');            default: return '';        }}    static fromJson(json={}) {        return new Inbound(            json.port,            json.listen,            json.protocol,            Inbound.Settings.fromJson(json.protocol, json.settings),            StreamSettings.fromJson(json.streamSettings),            json.tag,            Sniffing.fromJson(json.sniffing),            json.clientStats        )    }    toJson() {        let streamSettings;        if (this.canEnableStream() || this.protocol === Protocols.TROJAN) {            streamSettings = this.stream.toJson();        }        return {            port: this.port,            listen: this.listen,            protocol: this.protocol,            settings: this.settings instanceof XrayCommonClass ? this.settings.toJson() : this.settings,            streamSettings: streamSettings,            tag: this.tag,            sniffing: this.sniffing.toJson(),            clientStats: this.clientStats        };    }}Inbound.Settings = class extends XrayCommonClass {    constructor(protocol) {        super();        this.protocol = protocol;    }    static getSettings(protocol) {        switch (protocol) {            case Protocols.VMESS: return new Inbound.VmessSettings(protocol);            case Protocols.VLESS: return new Inbound.VLESSSettings(protocol);            case Protocols.TROJAN: return new Inbound.TrojanSettings(protocol);            case Protocols.SHADOWSOCKS: return new Inbound.ShadowsocksSettings(protocol);            case Protocols.DOKODEMO: return new Inbound.DokodemoSettings(protocol);            case Protocols.MTPROTO: return new Inbound.MtprotoSettings(protocol);            case Protocols.SOCKS: return new Inbound.SocksSettings(protocol);            case Protocols.HTTP: return new Inbound.HttpSettings(protocol);            default: return null;        }    }    static fromJson(protocol, json) {        switch (protocol) {            case Protocols.VMESS: return Inbound.VmessSettings.fromJson(json);            case Protocols.VLESS: return Inbound.VLESSSettings.fromJson(json);            case Protocols.TROJAN: return Inbound.TrojanSettings.fromJson(json);            case Protocols.SHADOWSOCKS: return Inbound.ShadowsocksSettings.fromJson(json);            case Protocols.DOKODEMO: return Inbound.DokodemoSettings.fromJson(json);            case Protocols.MTPROTO: return Inbound.MtprotoSettings.fromJson(json);            case Protocols.SOCKS: return Inbound.SocksSettings.fromJson(json);            case Protocols.HTTP: return Inbound.HttpSettings.fromJson(json);            default: return null;        }    }    toJson() {        return {};    }};Inbound.VmessSettings = class extends Inbound.Settings {    constructor(protocol,                vmesses=[new Inbound.VmessSettings.Vmess()],                disableInsecureEncryption=false) {        super(protocol);        this.vmesses = vmesses;        this.disableInsecure = disableInsecureEncryption;    }    indexOfVmessById(id) {        return this.vmesses.findIndex(vmess => vmess.id === id);    }    addVmess(vmess) {        if (this.indexOfVmessById(vmess.id) >= 0) {            return false;        }        this.vmesses.push(vmess);    }    delVmess(vmess) {        const i = this.indexOfVmessById(vmess.id);        if (i >= 0) {            this.vmesses.splice(i, 1);        }    }    static fromJson(json={}) {        return new Inbound.VmessSettings(            Protocols.VMESS,            json.clients.map(client => Inbound.VmessSettings.Vmess.fromJson(client)),            ObjectUtil.isEmpty(json.disableInsecureEncryption) ? false : json.disableInsecureEncryption,        );    }    toJson() {        return {            clients: Inbound.VmessSettings.toJsonArray(this.vmesses),            disableInsecureEncryption: this.disableInsecure,        };    }};Inbound.VmessSettings.Vmess = class extends XrayCommonClass {    constructor(id=RandomUtil.randomUUID(), alterId=0, email=RandomUtil.randomText(),limitIp=0, totalGB=0, expiryTime='') {        super();        this.id = id;        this.alterId = alterId;        this.email = email;        this.limitIp = limitIp;        this.totalGB = totalGB;        this.expiryTime = expiryTime;    }    static fromJson(json={}) {        return new Inbound.VmessSettings.Vmess(            json.id,            json.alterId,            json.email,            json.limitIp,            json.totalGB,            json.expiryTime,        );    }    get _expiryTime() {        if (this.expiryTime === 0 || this.expiryTime === "") {            return null;        }        return moment(this.expiryTime);    }    set _expiryTime(t) {        if (t == null || t === "") {            this.expiryTime = 0;        } else {            this.expiryTime = t.valueOf();        }    }    get _totalGB() {        return toFixed(this.totalGB / ONE_GB, 2);    }    set _totalGB(gb) {        this.totalGB = toFixed(gb * ONE_GB, 0);    }};Inbound.VLESSSettings = class extends Inbound.Settings {    constructor(protocol,                vlesses=[new Inbound.VLESSSettings.VLESS()],                decryption='none',                fallbacks=[],) {        super(protocol);        this.vlesses = vlesses;        this.decryption = 'none';        this.fallbacks = fallbacks;    }    addFallback() {        this.fallbacks.push(new Inbound.VLESSSettings.Fallback());    }    delFallback(index) {        this.fallbacks.splice(index, 1);    }    static fromJson(json={}) {        return new Inbound.VLESSSettings(            Protocols.VLESS,            json.clients.map(client => Inbound.VLESSSettings.VLESS.fromJson(client)),            'none',            Inbound.VLESSSettings.Fallback.fromJson(json.fallbacks),        );    }    toJson() {        return {            clients: Inbound.VLESSSettings.toJsonArray(this.vlesses),            decryption: this.decryption,            fallbacks: Inbound.VLESSSettings.toJsonArray(this.fallbacks),        };    }};Inbound.VLESSSettings.VLESS = class extends XrayCommonClass {    constructor(id=RandomUtil.randomUUID(), flow='', email=RandomUtil.randomText(),limitIp=0, totalGB=0, expiryTime='') {        super();        this.id = id;        this.flow = flow;        this.email = email;        this.limitIp = limitIp;        this.totalGB = totalGB;        this.expiryTime = expiryTime;    }    static fromJson(json={}) {        return new Inbound.VLESSSettings.VLESS(            json.id,            json.flow,            json.email,            json.limitIp,            json.totalGB,            json.expiryTime,        );    }    get _expiryTime() {        if (this.expiryTime === 0 || this.expiryTime === "") {            return null;        }        return moment(this.expiryTime);    }    set _expiryTime(t) {        if (t == null || t === "") {            this.expiryTime = 0;        } else {            this.expiryTime = t.valueOf();        }    }    get _totalGB() {        return toFixed(this.totalGB / ONE_GB, 2);    }    set _totalGB(gb) {        this.totalGB = toFixed(gb * ONE_GB, 0);    }};Inbound.VLESSSettings.Fallback = class extends XrayCommonClass {    constructor(name="", alpn='', path='', dest='', xver=0) {        super();        this.name = name;        this.alpn = alpn;        this.path = path;        this.dest = dest;        this.xver = xver;    }    toJson() {        let xver = this.xver;        if (!Number.isInteger(xver)) {            xver = 0;        }        return {            name: this.name,            alpn: this.alpn,            path: this.path,            dest: this.dest,            xver: xver,        }    }    static fromJson(json=[]) {        const fallbacks = [];        for (let fallback of json) {            fallbacks.push(new Inbound.VLESSSettings.Fallback(                fallback.name,                fallback.alpn,                fallback.path,                fallback.dest,                fallback.xver,            ))        }        return fallbacks;    }};Inbound.TrojanSettings = class extends Inbound.Settings {    constructor(protocol,		trojans=[new Inbound.TrojanSettings.Trojan()],		fallbacks=[],) {        super(protocol);        this.trojans = trojans;        this.fallbacks = fallbacks;    }    addTrojanFallback() {        this.fallbacks.push(new Inbound.TrojanSettings.Fallback());    }    delTrojanFallback(index) {        this.fallbacks.splice(index, 1);    }    static fromJson(json={}) {        return new Inbound.TrojanSettings(            Protocols.TROJAN,            json.clients.map(client => Inbound.TrojanSettings.Trojan.fromJson(client)),            Inbound.TrojanSettings.Fallback.fromJson(json.fallbacks),);    }    toJson() {        return {            clients: Inbound.TrojanSettings.toJsonArray(this.trojans),            fallbacks: Inbound.TrojanSettings.toJsonArray(this.fallbacks),        };    }};Inbound.TrojanSettings.Trojan = class extends XrayCommonClass {    constructor(password=RandomUtil.randomSeq(10), flow='', email=RandomUtil.randomText(),limitIp=0, totalGB=0, expiryTime='') {        super();        this.password = password;        this.flow = flow;        this.email = email;        this.limitIp = limitIp;        this.totalGB = totalGB;        this.expiryTime = expiryTime;    }    toJson() {        return {            password: this.password,            flow: this.flow,            email: this.email,            limitIp: this.limitIp,            totalGB: this.totalGB,            expiryTime: this.expiryTime,        };    }    static fromJson(json={}) {        return new Inbound.TrojanSettings.Trojan(            json.password,            json.flow,            json.email,            json.limitIp,            json.totalGB,            json.expiryTime,        );    }    get _expiryTime() {        if (this.expiryTime === 0 || this.expiryTime === "") {            return null;        }        return moment(this.expiryTime);    }    set _expiryTime(t) {        if (t == null || t === "") {            this.expiryTime = 0;        } else {            this.expiryTime = t.valueOf();        }    }    get _totalGB() {        return toFixed(this.totalGB / ONE_GB, 2);    }    set _totalGB(gb) {        this.totalGB = toFixed(gb * ONE_GB, 0);    }};Inbound.TrojanSettings.Fallback = class extends XrayCommonClass {    constructor(name="", alpn='', path='', dest='', xver=0) {        super();        this.name = name;        this.alpn = alpn;        this.path = path;        this.dest = dest;        this.xver = xver;    }    toJson() {        let xver = this.xver;        if (!Number.isInteger(xver)) {            xver = 0;        }        return {            name: this.name,            alpn: this.alpn,            path: this.path,            dest: this.dest,            xver: xver,        }    }    static fromJson(json=[]) {        const fallbacks = [];        for (let fallback of json) {            fallbacks.push(new Inbound.TrojanSettings.Fallback(                fallback.name,                fallback.alpn,                fallback.path,                fallback.dest,                fallback.xver,            ))        }        return fallbacks;    }};Inbound.ShadowsocksSettings = class extends Inbound.Settings {    constructor(protocol,        method = SSMethods.BLAKE3_AES_256_GCM,        password = RandomUtil.randomSeq(44),        network = 'tcp,udp'    ) {        super(protocol);        this.method = method;        this.password = password;        this.network = network;    }    static fromJson(json = {}) {        return new Inbound.ShadowsocksSettings(            Protocols.SHADOWSOCKS,            json.method,            json.password,            json.network,        );    }    toJson() {        return {            method: this.method,            password: this.password,            network: this.network,        };    }};Inbound.DokodemoSettings = class extends Inbound.Settings {    constructor(protocol, address, port, network='tcp,udp', followRedirect=false) {        super(protocol);        this.address = address;        this.port = port;        this.network = network;		this.followRedirect = followRedirect;    }    static fromJson(json={}) {        return new Inbound.DokodemoSettings(            Protocols.DOKODEMO,            json.address,            json.port,            json.network,			json.followRedirect,        );    }    toJson() {        return {            address: this.address,            port: this.port,            network: this.network,			followRedirect: this.followRedirect,        };    }};Inbound.MtprotoSettings = class extends Inbound.Settings {    constructor(protocol, users=[new Inbound.MtprotoSettings.MtUser()]) {        super(protocol);        this.users = users;    }    static fromJson(json={}) {        return new Inbound.MtprotoSettings(            Protocols.MTPROTO,            json.users.map(user => Inbound.MtprotoSettings.MtUser.fromJson(user)),        );    }    toJson() {        return {            users: XrayCommonClass.toJsonArray(this.users),        };    }};Inbound.MtprotoSettings.MtUser = class extends XrayCommonClass {    constructor(secret=RandomUtil.randomMTSecret()) {        super();        this.secret = secret;    }    static fromJson(json={}) {        return new Inbound.MtprotoSettings.MtUser(json.secret);    }};Inbound.SocksSettings = class extends Inbound.Settings {    constructor(protocol, auth='password', accounts=[new Inbound.SocksSettings.SocksAccount()], udp=false, ip='127.0.0.1') {        super(protocol);        this.auth = auth;        this.accounts = accounts;        this.udp = udp;        this.ip = ip;    }    addAccount(account) {        this.accounts.push(account);    }    delAccount(index) {        this.accounts.splice(index, 1);    }    static fromJson(json={}) {        let accounts;        if (json.auth === 'password') {            accounts = json.accounts.map(                account => Inbound.SocksSettings.SocksAccount.fromJson(account)            )        }        return new Inbound.SocksSettings(            Protocols.SOCKS,            json.auth,            accounts,            json.udp,            json.ip,        );    }    toJson() {        return {            auth: this.auth,            accounts: this.auth === 'password' ? this.accounts.map(account => account.toJson()) : undefined,            udp: this.udp,            ip: this.ip,        };    }};Inbound.SocksSettings.SocksAccount = class extends XrayCommonClass {    constructor(user=RandomUtil.randomSeq(10), pass=RandomUtil.randomSeq(10)) {        super();        this.user = user;        this.pass = pass;    }    static fromJson(json={}) {        return new Inbound.SocksSettings.SocksAccount(json.user, json.pass);    }};Inbound.HttpSettings = class extends Inbound.Settings {    constructor(protocol, accounts=[new Inbound.HttpSettings.HttpAccount()]) {        super(protocol);        this.accounts = accounts;    }    addAccount(account) {        this.accounts.push(account);    }    delAccount(index) {        this.accounts.splice(index, 1);    }    static fromJson(json={}) {        return new Inbound.HttpSettings(            Protocols.HTTP,            json.accounts.map(account => Inbound.HttpSettings.HttpAccount.fromJson(account)),        );    }    toJson() {        return {            accounts: Inbound.HttpSettings.toJsonArray(this.accounts),        };    }};Inbound.HttpSettings.HttpAccount = class extends XrayCommonClass {    constructor(user=RandomUtil.randomSeq(10), pass=RandomUtil.randomSeq(10)) {        super();        this.user = user;        this.pass = pass;    }    static fromJson(json={}) {        return new Inbound.HttpSettings.HttpAccount(json.user, json.pass);    }};
 |