<%+cbi/valueheader%>
<%
local api = require "luci.model.cbi.passwall.api.api"
local has_v2ray = api.is_finded("v2ray")
local has_xray = api.is_finded("xray")
-%>
<script type="text/javascript">//<![CDATA[
	function padright(str, cnt, pad) {
		return str + Array(cnt + 1).join(pad);
	}
	
	function b64EncodeUnicode(str) {
		return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
			return String.fromCharCode('0x' + p1);
		}));
	}
	
	function b64encutf8safe(str) {
		return b64EncodeUnicode(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '');
	}
	
	function b64DecodeUnicode(str) {
		return decodeURIComponent(Array.prototype.map.call(atob(str), function(c) {
			return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
		}).join(''));
	}
	
	function b64decutf8safe(str) {
		var l;
		str = str.replace(/-/g, "+").replace(/_/g, "/");
		l = str.length;
		l = (4 - l % 4) % 4;
		if (l)
			str = padright(str, l, "=");
		return b64DecodeUnicode(str);
	}
	
	function b64encsafe(str) {
		return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '')
	}
	
	function b64decsafe(str) {
		var l;
		str = str.replace(/-/g, "+").replace(/_/g, "/");
		l = str.length;
		l = (4 - l % 4) % 4;
		if (l)
			str = padright(str, l, "=");
		return atob(str);
	}
	
	function dictvalue(d, key) {
		var v = d[key];
		if (typeof(v) === 'undefined' || v === '')
			return '';
		return b64decsafe(v);
	}
	function parseNodeUrl(url) {
		var m = url.match(/^(([^:\/?#]+:)?(?:\/\/((?:([^\/?#:]*)([^\/?#:]*)@)?([^\/?#:]*)(?::([^\/?#:]*))?)))?([^?#]*)(\?[^#]*)?(#.*)?$/),
			r = {
				hash: m[10] || "", // #asd
				host: m[3] || "", // localhost:257
				hostname: m[6] || "", // localhost
				href: m[0] || "", // http://username:password@localhost:257/deploy/?asd=asd#asd
				origin: m[1] || "", // http://username:password@localhost:257
				pathname: m[8] || (m[1] ? "/" : ""), // /deploy/
				port: m[7] || "", // 257
				protocol: m[2] || "", // http:
				search: m[9] || "", // ?asd=asd
				passwd: m[4] || "", // username
				removed: m[5] || "" // password
			};
		if (r.protocol.length === 2) {
			r.protocol = "file:///" + r.protocol.toUpperCase();
			r.origin = r.protocol + "//" + r.host;
		}
		r.href = r.origin + r.pathname + r.search + r.hash;
		return m && r;
	}

	function buildUrl(btn, urlname, sid) {
		var opt = {
			base: "cbid.passwall",
			client : true,
			get: function(opt) {
				var id = this.base + "." + opt;
				var obj = document.getElementsByName(id)[0] || document.getElementsByClassName(id)[0] || document.getElementById(id)
				if (obj) {
					return obj;
				} else {
					return null;
				}
			},
			getlist: function(opt) {
				var id = this.base + "." + opt;
				var objs = document.getElementsByName(id) || document.getElementsByClassName(id);
				var ret = [];
				if (objs) {
					for (var i = 0; i < objs.length; i++) {
						ret[i] = objs[i].value;
					}
				} else {
					alert("<%:Faltal on get option, please help in debug: %>" + opt);
				}
				return ret;
			},
			query: function(param, src, tval = "1", fval = "0") {
				var ret = "&" + param + "=";
				var obj = this.get(src);
				if (obj) {
					if (obj.type === "checkbox") {
						return ret + (obj.checked === true ? tval : fval);
					} else {
						return ret + encodeURIComponent(obj.value);
					}
				}
				return ""
			}
		}
		
		var s = document.getElementById(urlname + "-status");
		if (!s) {
			alert("Never");
			return false;
		}
		opt.base = "cbid." + urlname + "." + sid;
		opt.client = urlname.indexOf("server") === -1;
		var v_type = opt.get("type").value;
		var v_alias = opt.get("remarks");
		var url = null;
		if (v_type === "SS") {
			var v_server = opt.get("address");
			var v_port = opt.get("port");
			var v_method = opt.get("ss_encrypt_method");
			var v_password = opt.get("password");
			
			url = b64encsafe(v_method.value + ":" + v_password.value) + "@" +
				v_server.value + ":" +
				v_port.value + "/?";
			
			var params = "";
			var v_plugin = opt.get("ss_plugin").value;
			if (v_plugin && v_plugin != "none") {
				if (v_plugin == "simple-obfs" || v_plugin == "obfs-local") {
					v_plugin = "obfs-local";
				}
				var v_plugin_opts = opt.get("ss_plugin_opts").value;
				if (v_plugin_opts && v_plugin_opts != "") {
					v_plugin += encodeURI(";" + v_plugin_opts);
				}
				params += "&plugin=" + encodeURI(v_plugin);
			}
			params += "&group="
			params += "#" + encodeURI(v_alias.value);
			if (params[0] == "&") {
				params = params.substring(1);
			}
			url += params;
		} else if (v_type === "SSR") {
			var v_server = opt.get("address");
			var v_port = opt.get("port");
			var v_protocol = opt.get("ssr_protocol");
			var v_method = opt.get("ssr_encrypt_method");
			var v_obfs = opt.get("obfs");
			var v_password = opt.get("password");
			var v_obfs_param = opt.get("obfs_param");
			var v_protocol_param = opt.get("protocol_param");
			var ssr_str = v_server.value + ":" +
				v_port.value + ":" +
				v_protocol.value + ":" +
				v_method.value + ":" +
				v_obfs.value + ":" +
				b64encsafe(v_password.value) +
				"/?obfsparam=" + b64encsafe(v_obfs_param.value) +
				"&protoparam=" + b64encsafe(v_protocol_param.value) +
				"&remarks=" + b64encutf8safe(v_alias.value);
			url = b64encsafe(ssr_str);
		} else if ((v_type === "V2ray" || v_type === "Xray") && opt.get("protocol").value === "vmess") {
			v_type = "vmess";
			var info = {};
			info.v = "2";
			info.ps = v_alias.value;
			info.add = opt.get("address").value;
			info.port = opt.get("port").value;
			info.id = opt.get("uuid").value;
			info.aid = opt.get("alter_id").value;
			
			var v_transport = opt.get("transport").value;
			if (v_transport === "ws") {
				info.host = opt.get("ws_host").value;
				info.path = opt.get("ws_path").value;
			} else if (v_transport === "h2") {
				info.host = opt.get("h2_host").value;
				info.path = opt.get("h2_path").value;
			} else if (v_transport === "tcp") {
				info.type = opt.get("tcp_guise").value;
				info.host = opt.get("tcp_guise_http_host").value;
				info.path = opt.get("tcp_guise_http_path").value;
			} else if (v_transport === "mkcp") {
				v_transport = "kcp";
				info.type = opt.get("mkcp_guise").value;
			} else if (v_transport === "quic") {
				info.type = opt.get("quic_guise").value;
				info.key = opt.get("quic_key").value;
				info.securty = opt.get("quic_security").value;
			} else if (v_transport === "grpc") {
				info.path = opt.get("grpc_serviceName").value;
			}
			if (info.path && info.path != "") {
				info.path = encodeURI(info.path);
			}
			info.net = v_transport;
			
			info.security = opt.get("security").value || "auto";
			if (opt.get("tls").checked) {
				var v_security = "tls";
				info.tls = "tls";
				info.sni = opt.get("tls_serverName").value;
			}
			url = b64EncodeUnicode(JSON.stringify(info));
		} else if ((v_type === "V2ray" || v_type === "Xray") && opt.get("protocol").value === "vless") {
			v_type = "vless";
			var v_password = opt.get("uuid");
			var v_server = opt.get("address");
			var v_port = opt.get("port");
			url = encodeURIComponent(v_password.value) +
				"@" + v_server.value +
				":" + v_port.value + "?";
			
			var params = "";
			var v_transport = opt.get("transport").value;
			if (v_transport === "ws") {
				params += opt.query("host", "ws_host");
				params += opt.query("path", "ws_path");
			} else if (v_transport === "h2") {
				params += opt.query("host", "h2_host");
				params += opt.query("path", "h2_path");
			} else if (v_transport === "tcp") {
				params += opt.query("headerType", "tcp_guise");
				params += opt.query("host", "tcp_guise_http_host");
				params += opt.query("path", "tcp_guise_http_path");
			} else if (v_transport === "mkcp") {
				v_transport = "kcp";
				params += opt.query("headerType", "mkcp_guise");
			} else if (v_transport === "quic") {
				params += opt.query("headerType", "quic_guise");
				params += opt.query("key", "quic_key");
				params += opt.query("quicSecurity", "quic_security");
			} else if (v_transport === "grpc") {
				//不知道是用path还是serviceName，这里先这样吧
				params += opt.query("path", "grpc_serviceName");
				params += opt.query("serviceName", "grpc_serviceName");
			}
			params += "&type=" + v_transport;
			
			params += opt.query("encryption", "encryption");
			if (opt.get("tls").checked) {
				var v_security = "tls";
				if (opt.get("xtls").checked) {
					v_security = "xtls";
					var v_flow = "xtls-rprx-direct";
					if (opt.get("flow").value) {
						v_flow = opt.get("flow").value;
					}
					params += "&flow=" + v_flow;
				}
				params += "&security=" + v_security;
				params += opt.query("sni", "tls_serverName");
			}
			params += "#" + encodeURI(v_alias.value);
			if (params[0] == "&") {
				params = params.substring(1);
			}
			url += params;
		} else if (((v_type === "V2ray" || v_type === "Xray") && opt.get("protocol").value === "trojan") || v_type === "Trojan" || v_type === "Trojan-Plus" || v_type === "Trojan-Go") {
			if (((v_type === "V2ray" || v_type === "Xray") && opt.get("protocol").value === "trojan") || v_type === "Trojan-Plus") {
				v_type = "trojan";
			}
			var v_password = opt.get(!opt.client && v_type === "Trojan-Go"  ? "passwords" : "password");
			var v_server = opt.get("address");
			var v_port = opt.get("port");
			url = encodeURIComponent(v_password.value) +
				"@" + v_server.value +
				":" + v_port.value + "/?";
			var params = "";
			if (opt.get("tls").checked) {
				params += opt.query("sni", "tls_serverName");
				if (v_type !== "Trojan-Go") {
					params += "&tls=1"
					params += opt.query("allowinsecure", "tls_allowInsecure");
				}
			}
			if (v_type === "Trojan-Go") {
				if (!opt.get("tls").checked && opt.get("trojan_transport").value === "original") {
					var plugin = {};
					plugin.type = opt.get("plugin_type").value;
					if (plugin.type !== "plaintext") {
						plugin.command = opt.get("plugin_cmd").value;
						plugin.option = opt.get("plugin_option").value;
						plugin.arg = opt.getlist("plugin_arg");
					}
					params += "&plugin=" + encodeURIComponent(JSON.stringify(plugin));
				}
				params += opt.query("type", "trojan_transport");
				var ws = (opt.get("trojan_transport").value.indexOf("ws") !== -1);
				var h2 = (opt.get("trojan_transport").value.indexOf("h2") !== -1);
				if (ws) {
					params += opt.query("host", "ws_host");
					params += opt.query("path", "ws_path");
				} else if (h2) {
					params += opt.query("host", "h2_host");
					params += opt.query("path", "h2_path");
				}
				var enc = "none";
				if (opt.get("ss_aead").checked === true) {
					enc = "ss;" +
						opt.get("ss_aead_method").value +
						":" + opt.get("ss_aead_pwd").value;
				}
				params += "&encryption=" + encodeURIComponent(enc);
			}
			params += "#" + encodeURI(v_alias.value);
			if (params[0] == "&") {
				params = params.substring(1);
			}
			url += params;
		} else if (v_type === "Brook") {
			var url = "";
			var params = "?";
			var v_protocol = opt.get("brook_protocol");
			var v_server = opt.get("address");
			var v_port = opt.get("port");
			var v_password = opt.get("password");
			var b_protocol_value = v_protocol.value.split('client').join('server');
			
			var url_protocol = b_protocol_value;
			params += opt.query("password", "password");
			if (b_protocol_value == "wsserver") {
				var server = '';
				var prefix = "ws://";
				if (opt.get("brook_tls").checked) {
					prefix = "wss://";
					url_protocol = 'wssserver';
				}
				var v_path = opt.get("ws_path");
				var v_path_value = v_path.value || '/ws';
				if (v_path_value.length > 1 && v_path_value.indexOf('/') < 0) {
					v_path_value = '/' + v_path_value;
				}
				params += "&" + url_protocol + "=" + encodeURIComponent(prefix + v_server.value + ":" + v_port.value + v_path_value);
			} else {
				params += "&" + url_protocol + "=" + encodeURIComponent(v_server.value + ":" + v_port.value);
			}
			url += url_protocol;
			url += params;
		}
		if (url) {
			url = v_type.toLowerCase() + "://" + url;
			var textarea = document.createElement("textarea");
			textarea.textContent =  url;
			textarea.style.position = "fixed";
			document.body.appendChild(textarea);
			textarea.select();
			try {
				document.execCommand("copy"); // Security exception may be thrown by some browsers.
				s.innerHTML = "<font color='green'><%:Share URL to clipboard successfully.%></font>";
			} catch (ex) {
				s.innerHTML = "<font color='red'><%:Share URL to clipboard unable.%></font>";
			} finally {
				document.body.removeChild(textarea);
			}
			//alert(url);
		} else {
			alert("<%:Not a supported scheme:%> " + v_type);
		}
		return false;
	}
	
	function fromUrl(btn, urlname, sid) {
		var opt = {
			base: 'cbid.passwall',
			client : true,
			get: function(opt) {
				var obj;
				var id = this.base + '.' + opt;
				obj = document.getElementsByName(id)[0] || document.getElementById(id);
				if (obj) {
					var combobox = document.getElementById('cbi.combobox.' + id);
					if (combobox) {
						obj.combobox = combobox;
					}
					return obj;
				} else {
					return null;
				}
			},
			set: function(opt, val) {
				var obj;
				obj = this.get(opt)
				if (obj) {
					var event = document.createEvent("HTMLEvents");
					event.initEvent("change", true, true);
					if (obj.type === 'checkbox') {
						obj.checked = val;
					} else {
						obj.value = val;
						if (obj.combobox) {
							obj.combobox.value = val;
						}
					}
					try {
						obj.dispatchEvent(event);
					} catch(err) {
					}
				} else {
					//alert('<%:Faltal on set option, please help in debug: %>' + opt + ' = ' + val);
				}
			},
			setlist: function(opt, vlist) {
				var id = this.base + "." + opt;
				var objs = document.getElementsByName(id) || document.getElementsByClassName(id);
				if (objs) {
					var values = "";
					for (var i = 0; i < vlist.length; i++) {
						values += vlist[i] + ", ";
					}
					alert("Manually input the option:\n" + opt + "s:\n[" + values + "]");
				} else {
					//alert("<%:Faltal on set option, please help in debug: %>" + opt);
				}
			}
		}
		
		var s = document.getElementById(urlname + '-status');
		if (!s) {
			alert("Never");
			return false;
		}
		opt.base = "cbid." + urlname + "." + sid;
		opt.client = urlname.indexOf("server") === -1;
		var ssrurl = prompt('<%:Paste Share URL Here%>', '');
		if (ssrurl === null || ssrurl === "") {
			return false;
		}
		s.innerHTML = "";
		var ssu = ssrurl.split('://');
		var event = document.createEvent("HTMLEvents");
		event.initEvent("change", true, true);
		if (ssu[0] === "ssr") {
			//var b64c = ssu[1].match(/([A-Za-z0-9_-]+)/);
			var sstr = b64decsafe(ssu[1]);
			var ploc = sstr.indexOf("/?");
			var url0 = "", param = "";
			if (ploc > 0) {
				url0 = sstr.substr(0, ploc);
				param = sstr.substr(ploc + 2);
			} else {
				var url0 = sstr;
			}
			console.log(param);
			var ssm = url0.match(/^(.+):([^:]+):([^:]*):([^:]+):([^:]*):([^:]+)/);
			if (!ssm || ssm.length < 7) {
				s.innerHTML = "<font color='red'><%:Invalid Share URL Format%></font>";
				return false;
			}
			var pdict = {};
			if (param.length > 2) {
				var a = param.split('&');
				for (var i = 0; i < a.length; i++) {
					var b = a[i].split('=');
					pdict[decodeURIComponent(b[0])] = decodeURIComponent(b[1] || '');
				}
			}
			opt.set('type', "SSR");
			opt.set('address', ssm[1]);
			opt.set('port', ssm[2]);
			opt.set('ssr_protocol', ssm[3]);
			opt.set('ssr_encrypt_method', ssm[4]);
			opt.set('obfs', ssm[5]);
			opt.set('password', b64decsafe(ssm[6]));
			opt.set('obfs_param', dictvalue(pdict, 'obfsparam'));
			opt.set('protocol_param', dictvalue(pdict, 'protoparam'));
			var rem = pdict['remarks'];
			if (typeof(rem) !== 'undefined' && rem !== '' && rem.length > 0)
				opt.set('remarks', b64decutf8safe(rem));
		} else if (ssu[0] === "ss") {
			var url0 = "", param = "";
			var sipIndex = ssu[1].indexOf("@");
			var ploc = ssu[1].indexOf("#");
			if (ploc > 0) {
				url0 = ssu[1].substr(0, ploc);
				param = ssu[1].substr(ploc + 1);
			} else {
				url0 = ssu[1];
			}
			if (sipIndex !== -1) {
				// SIP002
				var userInfo = b64decsafe(url0.substr(0, sipIndex));
				var temp = url0.substr(sipIndex + 1).split("/?");
				var serverInfo = temp[0].split(":");
				var server = serverInfo[0];
				var port = serverInfo[1];
				var method, password, plugin, pluginOpts;
				if (temp[1]) {
					var pluginInfo = decodeURIComponent(temp[1]);
					var pluginIndex = pluginInfo.indexOf(";");
					var pluginNameInfo = pluginInfo.substr(0, pluginIndex);
					plugin = pluginNameInfo.substr(pluginNameInfo.indexOf("=") + 1)
					pluginOpts = pluginInfo.substr(pluginIndex + 1);
				}
				var userInfoSplitIndex = userInfo.indexOf(":");
				if (userInfoSplitIndex !== -1) {
					method = userInfo.substr(0, userInfoSplitIndex);
					password = userInfo.substr(userInfoSplitIndex + 1);
				}
				opt.set('type', "SS");
				opt.set('address', server);
				opt.set('port', port);
				opt.set('password', password || "");
				opt.set('ss_encrypt_method', method || "");
				opt.set('ss_plugin', plugin || "none");
				if (plugin && plugin != "none") {
					opt.set('ss_plugin_opts', pluginOpts || "");
				}
				if (param !== undefined) {
					opt.set('remarks', decodeURI(param));
				}
			} else {
				var sstr = b64decsafe(url0);
				var team = sstr.split('@');
				opt.set('type', "SS");
				var part1 = team[0].split(':');
				var part2 = team[1].split(':');
				opt.set('address', part2[0]);
				opt.set('port', part2[1]);
				opt.set('password', part1[1]);
				opt.set('ss_encrypt_method', part1[0]);
				opt.set('ss_plugin', "none");
				//opt.set('ss_plugin_opts', "");
				if (param !== undefined) {
					opt.set('remarks', decodeURI(param));
				}
			}
		} else if (ssu[0] === "trojan" || ssu[0] === "trojan-plus") {
			var stype = "Trojan-Plus";
			var m = parseNodeUrl(ssrurl);
			console.log(m.search);
			var password = m.passwd;
			if (password === "") {
				s.innerHTML = "<font color='red'><%:Invalid Share URL Format%></font>";
				return false;
			}
			var queryParam = {};
			if (m.search.length > 1) {
				var query = m.search.split('?');
				var queryParams = query[1];
				var queryArray = queryParams.split('&');
				var params;
				for (i = 0; i < queryArray.length; i++) {
					params = queryArray[i].split('=');
					queryParam[decodeURIComponent(params[0]).toLowerCase()] = decodeURIComponent(params[1] || '');
				}
			}
			if (queryParam.mux || queryParam.ws || queryParam.h2 || queryParam.ss || queryParam.plugin) {
				stype = "Trojan-Go";
			}
			opt.set('type', stype);
			opt.set('address', m.hostname);
			opt.set('port', m.port || "443");
			opt.set(!opt.client && stype === "Trojan-Go" ? 'passwords' : 'password', decodeURIComponent(password));
			var tls = true;
			if (stype === "Trojan-Go") {
				tls = queryParam.plugin === undefined;
			}
			if (tls === false) { alert("TODO: plugin params for trojan-go."); }
			opt.set('tls', tls);
			if (tls) {
				opt.set('tls_serverName', queryParam.peer || queryParam.sni || '');
				opt.set('tls_allowInsecure', queryParam.allowinsecure === '1');
			}
			
			if (stype === "Trojan-Go") {
				var tran = 'original';
				var ws = null;
				var h2 = null;
				if (queryParam.type) {
					ws = queryParam.type.indexOf('ws') !== -1;
					h2 = queryParam.type.indexOf('h2') !== -1;
				}
				if (ws && h2) {
					tran = 'h2+ws'
				} else {
					if (ws) tran = 'ws';
					if (h2) tran = 'h2';
				}
				opt.set('trojan_transport', 'tran');
				if (ws) {
					opt.set('ws_host', queryParam.wshost || '');
					opt.set('ws_path', queryParam.wspath || '/');
				}
				if (h2) {
					opt.set('h2_host', queryParam.h2host || '');
					opt.set('h2_path', queryParam.h2path || '/');
				}
				var ss = queryParam.ss === '1';
				opt.set('ss_aead', ss);
				if (ss) {
					opt.set('ss_aead_method', queryParam.ssmethod.toLowerCase() || '');
					opt.set('ss_aead_pwd', queryParam.sspasswd || '');
				}
			}
			opt.set('mux', queryParam.mux === '1');
			if (m.hash) {
				opt.set('remarks', decodeURI(m.hash.substr(1)));
			}
		} else if (ssu[0] === "trojan-go") {
			var m = parseNodeUrl(ssrurl);
			console.log(m.search);
			var password = m.passwd;
			if (password === "") {
				s.innerHTML = "<font color='red'><%:Invalid Share URL Format%></font>";
				return false;
			}
			var queryParam = {};
			if (m.search.length > 1) {
				var query = m.search.split('?');
				var queryParams = query[1];
				var queryArray = queryParams.split('&');
				for (i = 0; i < queryArray.length; i++) {
					var params = queryArray[i].split('=');
					queryParam[decodeURIComponent(params[0]).toLowerCase()] = decodeURIComponent(params[1] || '');
				}
			}
			opt.set('type', 'Trojan-Go');
			opt.set('address', m.hostname);
			opt.set('port', m.port || "443");
			opt.set(opt.client ? 'password' : 'passwords', decodeURIComponent(password));
			opt.set('tls', '1');
			opt.set('tls_allowInsecure', '0');
			opt.set('tls_serverName', queryParam.peer || queryParam.sni || '');
			var plugin = queryParam.plugin !== undefined;
			if (plugin) {
				opt.set('trojan_transport', 'original');
				var plugin = JSON.parse(queryParam.plugin);
				if (plugin) {
					opt.set('plugin_type', plugin.type);
					if (plugin.type !== "plaintext") {
						opt.set('plugin_cmd', plugin.command);
						opt.set('plugin_option', plugin.option);
						opt.setlist('plugin_arg', plugin.arg);
					}
				} else
					alert(queryParam.plugin);
			}
			var tran = 'original';
			var or = queryParam.type === undefined || queryParam.type === 'original';
			var ws = null;
			var h2 = null;
			if (queryParam.type) {
				ws = queryParam.type.indexOf('ws') !== -1;
				h2 = queryParam.type.indexOf('h2') !== -1;
			}
			if (ws && h2) {
				tran = 'h2+ws'
			} else {
				if (ws) tran = 'ws';
				if (h2) tran = 'h2';
			}
			opt.set('trojan_transport', tran);
			if (ws) {
				opt.set('ws_host', queryParam.host || '');
				opt.set('ws_path', queryParam.path || '/');
			}
			if (h2){
				opt.set('h2_host', queryParam.host || '');
				opt.set('h2_path', queryParam.path || '/');
			}
			var enc = {};
			var ss = false;
			if (queryParam.encryption) {
				var r = queryParam.encryption.match(/^(ss);([^;:]*)[;:](.*)$/),
				enc = {type: r[1], method: r[2], password: r[3]};
			}
			ss = enc.type === 'ss';
			opt.set('ss_aead', ss);
			if (ss) {
				opt.set('ss_aead_method', enc.method.toLowerCase() || '');
				opt.set('ss_aead_pwd', enc.password || '');
			}
			opt.set('mux', '1');
			if (m.hash) {
				opt.set('remarks', decodeURI(m.hash.substr(1)));
			}
		} else if (ssu[0] === "vmess") {
			var sstr = b64DecodeUnicode(ssu[1]);
			var ploc = sstr.indexOf("/?");
			<% if has_v2ray then %>
			opt.set('type', "V2ray");
			<% elseif has_xray then %>
			opt.set('type', "Xray");
			<% end %>
			opt.set('protocol', "vmess");
			var url0, param = "";
			if (ploc > 0) {
				url0 = sstr.substr(0, ploc);
				param = sstr.substr(ploc + 2);
			}
			var ssm = JSON.parse(sstr);
			console.log(ssm);
			opt.set('remarks', ssm.ps);
			opt.set('address', ssm.add);
			opt.set('port', ssm.port);
			opt.set('alter_id', ssm.aid);
			opt.set('uuid', ssm.id);
			opt.set('tls', ssm.tls === "tls");
			if (ssm.tls === "tls") {
				var tls_serverName = ssm.host;
				if (ssm.sni) {
					tls_serverName = ssm.sni
				}
				opt.set('tls_serverName', tls_serverName);
			}
			ssm.net = ssm.net.toLowerCase();
			if (ssm.net === "kcp" || ssm.net === "mkcp")
				ssm.net = "mkcp"
			opt.set('transport', ssm.net);
			if (ssm.net === "tcp") {
				opt.set('tcp_guise', (ssm.host && ssm.path) ? "http" : "none");
				if (ssm.host && ssm.path) {
					opt.set('tcp_guise_http_host', ssm.host);
					opt.set('tcp_guise_http_path', ssm.path);
				}
			} else if (ssm.net === "ws") {
				opt.set('ws_host', ssm.host);
				opt.set('ws_path', ssm.path);
			} else if (ssm.net === "h2") {
				opt.set('h2_host', ssm.host);
				opt.set('h2_path', ssm.path);
			} else if (ssm.net === "quic") {
				opt.set('quic_security', ssm.securty);
				opt.set('quic_key', ssm.key);
			} else if (ssm.net === "kcp" || ssm.net === "mkcp") {
				opt.set('mkcp_guise', ssm.type);
			} else if (ssm.net === "grpc") {
				opt.set('grpc_serviceName', ssm.path);
			}
		} else if (ssu[0] === "vless") {
			<% if has_xray then %>
			opt.set('type', "Xray");
			<% elseif has_v2ray then %>
			opt.set('type', "V2ray");
			<% end %>
			opt.set('protocol', "vless");
			var m = parseNodeUrl(ssrurl);
			console.log(m.search);
			var password = m.passwd;
			if (password === "") {
				s.innerHTML = "<font color='red'><%:Invalid Share URL Format%></font>";
				return false;
			}
			opt.set('uuid', password);
			opt.set('address', m.hostname);
			opt.set('port', m.port || "443");
			var queryParam = {};
			if (m.search.length > 1) {
				var query = m.search.split('?');
				var queryParams = query[1];
				var queryArray = queryParams.split('&');
				var params;
				for (i = 0; i < queryArray.length; i++) {
					params = queryArray[i].split('=');
					queryParam[decodeURIComponent(params[0])] = decodeURIComponent(params[1] || '');
				}
			}
			
			opt.set('encryption', queryParam.encryption);
			if (queryParam.security) {
				if (queryParam.security == "tls" || queryParam.security == "xtls") {
					opt.set('tls', true);
					if (queryParam.security == "xtls") {
						opt.set('xtls', true);
						opt.set('flow', queryParam.flow || "xtls-rprx-direct");
					}
					opt.set('tls_serverName', queryParam.sni || '');
					
					opt.set('tls_allowInsecure', true);
					if (queryParam.allowinsecure === '0') {
						opt.set('tls_allowInsecure', false);
					}
				}
			}
			
			queryParam.type = queryParam.type.toLowerCase();
			if (queryParam.type === "kcp" || queryParam.type === "mkcp")
				queryParam.type = "mkcp"
			opt.set('transport', queryParam.type);
			if (queryParam.type === "tcp") {
				opt.set('tcp_guise', queryParam.headerType || "none");
				if (queryParam.headerType && queryParam.headerType != "none") {
					opt.set('tcp_guise_http_host', queryParam.host || "");
					opt.set('tcp_guise_http_path', queryParam.path || "");
				}
			} else if (queryParam.type === "ws") {
				opt.set('ws_host', queryParam.host || "");
				opt.set('ws_path', queryParam.path || "");
			} else if (queryParam.type === "h2") {
				opt.set('h2_host', queryParam.host || "");
				opt.set('h2_path', queryParam.path || "");
			} else if (queryParam.type === "quic") {
				opt.set('quic_guise', queryParam.headerType || "none");
				opt.set('quic_security', queryParam.quicSecurity);
				opt.set('quic_key', queryParam.key);
			} else if (queryParam.type === "kcp" || queryParam.type === "mkcp") {
				opt.set('mkcp_guise', queryParam.headerType || "none");
			} else if (queryParam.type === "grpc") {
				opt.set('grpc_serviceName', (queryParam.serviceName || queryParam.path) || "");
			}
			
			if (m.hash) {
				opt.set('remarks', decodeURI(m.hash.substr(1)));
			}
		} else if (ssu[0] === "brook") {
			var stype = "Brook";
			var m = parseNodeUrl(ssrurl);
			console.log(m);
			
			var from_protocol = m.host;
			var protocol = from_protocol.split('server').join('client');
			
			var queryParam = {};
			if (m.search.length > 1) {
				var query = m.search.split('?');
				var queryParams = query[1];
				var queryArray = queryParams.split('&');
				var params;
				for (i = 0; i < queryArray.length; i++) {
					params = queryArray[i].split('=');
					queryParam[decodeURIComponent(params[0])] = decodeURIComponent(params[1] || '');
				}
			}
			
			var password = queryParam.password;
			if (password === "") {
				s.innerHTML = "<font color='red'><%:Invalid Share URL Format%></font>";
				return false;
			}
			
			opt.set('type', stype);
			opt.set('brook_protocol', protocol);
			opt.set('password', password);
			
			if (protocol == 'wsclient' || protocol == 'wssclient') {
				opt.set('brook_protocol', 'wsclient');
				var wsserver = queryParam[from_protocol].split('://');
				wsserver = wsserver[1].split('/');
				var path = wsserver[1] && '/' + wsserver[1] || '/ws';
				var server = wsserver[0].split(':');
				opt.set('address', server[0]);
				opt.set('port', server[1]);
				opt.set('ws_path', path);
				if (protocol == 'wssclient') {
					opt.set('brook_tls', true);
				}
			} else {
				var server = queryParam[from_protocol].split(':');
				if (server.length < 2) {
					s.innerHTML = "<font color='red'><%:Invalid Share URL Format%></font>";
					return false;
				}
				opt.set('address', server[0]);
				opt.set('port', server[1]);
			}
			
			if (m.hash) {
				opt.set('remarks', decodeURI(m.hash.substr(1)));
			}
		} else {
			s.innerHTML = "<font color='red'><%:Invalid Share URL Format%></font>: " + ssu[0];
			return false;
		}
		s.innerHTML = "<font color='green'><%:Import Finished %></font>";
		return false;
	}

//]]></script>
<input type="button" class="btn cbi-button cbi-button-apply" value='<%:From Share URL%>' onclick="return fromUrl(this, '<%=self.option%>', '<%=self.value%>')" />
<input type="button" class="btn cbi-button cbi-button-apply" value='<%:Build Share URL%>' onclick="return buildUrl(this, '<%=self.option%>', '<%=self.value%>')" />
<span id="<%=self.option%>-status"></span>
<%+cbi/valuefooter%>
