From 55d1ac0402a2f9cc546566485ad07cb1f8321b5d Mon Sep 17 00:00:00 2001 From: dnobori Date: Sun, 7 Jul 2019 21:25:52 +0900 Subject: [PATCH] v4.30-9695-beta --- WARNING.TXT | 19 + src/BuildUtil/UnixBuildSoftwares.cs | 29 +- src/BuildUtil/VpnBuilder.cs | 20 + src/BuildUtil/VpnBuilderConfig.cs | 2 +- src/BuildUtil/Win32BuildUtil.cs | 10 + src/Cedar/Admin.c | 1466 +- src/Cedar/Admin.h | 40 +- src/Cedar/CM.c | 6 + src/Cedar/Cedar.h | 15 +- src/Cedar/CedarType.h | 4 + src/Cedar/Client.c | 72 +- src/Cedar/Client.h | 1 + src/Cedar/Command.c | 9 + src/Cedar/Connection.c | 16 + src/Cedar/Connection.h | 5 + src/Cedar/DDNS.c | 3 + src/Cedar/DDNS.h | 2 + src/Cedar/EtherLog.c | 4 +- src/Cedar/Hub.c | 9 +- src/Cedar/Hub.h | 3 +- src/Cedar/IPsec_EtherIP.c | 2 +- src/Cedar/IPsec_IPC.c | 28 +- src/Cedar/IPsec_IPC.h | 19 +- src/Cedar/IPsec_PPP.c | 8 +- src/Cedar/Interop_OpenVPN.c | 39 +- src/Cedar/Interop_OpenVPN.h | 1 + src/Cedar/Listener.c | 6 + src/Cedar/Nat.c | 14 +- src/Cedar/Protocol.c | 2775 ++- src/Cedar/Protocol.h | 105 + src/Cedar/Radius.c | 112 +- src/Cedar/Radius.h | 6 + src/Cedar/Remote.c | 10 +- src/Cedar/Remote.h | 1 + src/Cedar/SM.c | 10 + src/Cedar/SMInner.h | 1 + src/Cedar/SW.c | 9 + src/Cedar/Server.c | 109 +- src/Cedar/Server.h | 4 + src/Cedar/Session.c | 55 +- src/Cedar/Session.h | 13 +- src/Cedar/UdpAccel.c | 326 +- src/Cedar/UdpAccel.h | 24 +- src/Cedar/VLanWin32.c | 4 +- src/CurrentBuild.txt | 8 +- src/Ham/generated_manual_cn.html | 9861 +++++++++++ src/Ham/generated_manual_ja.html | 9862 +++++++++++ src/Mayaqua/Encrypt.c | 1063 +- src/Mayaqua/Encrypt.h | 26 + src/Mayaqua/FileIO.c | 6 + src/Mayaqua/Kernel.c | 91 + src/Mayaqua/Kernel.h | 2 + src/Mayaqua/MayaType.h | 7 +- src/Mayaqua/Memory.c | 81 +- src/Mayaqua/Memory.h | 6 + src/Mayaqua/Microsoft.c | 54 + src/Mayaqua/Microsoft.h | 3 + src/Mayaqua/Network.c | 599 +- src/Mayaqua/Network.h | 25 +- src/Mayaqua/Pack.c | 1010 +- src/Mayaqua/Pack.h | 84 +- src/Mayaqua/Str.c | 2110 +++ src/Mayaqua/Str.h | 255 + src/Mayaqua/Table.c | 2 + src/Mayaqua/Unix.c | 23 + src/Mayaqua/Unix.h | 1 + src/SEVPN.sln | 2 - src/See/Packet.c | 68 +- src/WARNING.TXT | 19 + .../DriverPackages/See/x64/See_x64.sys | Bin 49864 -> 52424 bytes .../DriverPackages/See/x86/See_x86.sys | Bin 54984 -> 57032 bytes src/bin/hamcore/lang.config | 17 - src/bin/hamcore/openvpn_sample.ovpn | 47 +- src/bin/hamcore/strtable_cn.stb | 19 +- src/bin/hamcore/strtable_en.stb | 22 +- src/bin/hamcore/strtable_ja.stb | 24 +- src/bin/hamcore/vpnserver_api_doc.html | 14648 ++++++++++++++++ src/bin/hamcore/warning_cn.txt | 2 + src/bin/hamcore/warning_en.txt | 2 + src/bin/hamcore/warning_ja.txt | 2 + src/bin/hamcore/wwwroot/admin/README.md | 22 + .../hamcore/wwwroot/admin/default/.gitignore | 1 + .../wwwroot/admin/default/.vscode/launch.json | 16 + .../admin/default/.vscode/settings.json | 5 + .../wwwroot/admin/default/.vscode/tasks.json | 45 + .../hamcore/wwwroot/admin/default/hub.html | 23 + .../wwwroot/admin/default/include_footer.html | 4 + .../wwwroot/admin/default/include_head.html | 9 + .../wwwroot/admin/default/include_menu.html | 29 + .../hamcore/wwwroot/admin/default/index.html | 45 + .../admin/default/out_webpack/bundle.js | 2144 +++ .../admin/default/out_webpack/ts/index.d.ts | 10 + .../default/out_webpack/ts/index.d.ts.map | 1 + .../admin/default/out_webpack/ts/main.d.ts | 11 + .../default/out_webpack/ts/main.d.ts.map | 1 + .../default/out_webpack/ts/vpnadmin.d.ts | 2 + .../default/out_webpack/ts/vpnadmin.d.ts.map | 1 + .../wwwroot/admin/default/package-lock.json | 4709 +++++ .../wwwroot/admin/default/package.json | 27 + .../wwwroot/admin/default/src/ts/main.ts | 201 + .../hamcore/wwwroot/admin/default/theme.css | 18 + .../wwwroot/admin/default/tsconfig.json | 68 + .../admin/default/tsconfig_webpack.json | 68 + .../hamcore/wwwroot/admin/default/tslint.json | 20 + .../wwwroot/admin/default/webpack.config.js | 38 + src/bin/hamcore/wwwroot/admin/index.html | 15 + src/bin/hamcore/wwwroot/index.html | 57 + src/bin/vpnweb.cab | Bin 206819 -> 206821 bytes src/bin/vpnweb.ocx | Bin 341816 -> 341816 bytes src/makefiles/freebsd_32bit.mak | 2 +- src/makefiles/freebsd_64bit.mak | 2 +- src/makefiles/linux_32bit.mak | 2 +- src/makefiles/linux_64bit.mak | 2 +- src/makefiles/macos_32bit.mak | 2 +- src/makefiles/macos_64bit.mak | 2 +- src/makefiles/openbsd_32bit.mak | 2 +- src/makefiles/openbsd_64bit.mak | 2 +- src/makefiles/solaris_32bit.mak | 2 +- src/makefiles/solaris_64bit.mak | 2 +- src/vpnweb/vpnweb.h | 2 +- src/vpnweb/vpnweb_i.c | 2 +- src/vpnweb/vpnweb_p.c | 2 +- 122 files changed, 52298 insertions(+), 785 deletions(-) create mode 100644 src/Ham/generated_manual_cn.html create mode 100644 src/Ham/generated_manual_ja.html delete mode 100644 src/bin/hamcore/lang.config create mode 100644 src/bin/hamcore/vpnserver_api_doc.html create mode 100644 src/bin/hamcore/wwwroot/admin/README.md create mode 100644 src/bin/hamcore/wwwroot/admin/default/.gitignore create mode 100644 src/bin/hamcore/wwwroot/admin/default/.vscode/launch.json create mode 100644 src/bin/hamcore/wwwroot/admin/default/.vscode/settings.json create mode 100644 src/bin/hamcore/wwwroot/admin/default/.vscode/tasks.json create mode 100644 src/bin/hamcore/wwwroot/admin/default/hub.html create mode 100644 src/bin/hamcore/wwwroot/admin/default/include_footer.html create mode 100644 src/bin/hamcore/wwwroot/admin/default/include_head.html create mode 100644 src/bin/hamcore/wwwroot/admin/default/include_menu.html create mode 100644 src/bin/hamcore/wwwroot/admin/default/index.html create mode 100644 src/bin/hamcore/wwwroot/admin/default/out_webpack/bundle.js create mode 100644 src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/index.d.ts create mode 100644 src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/index.d.ts.map create mode 100644 src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/main.d.ts create mode 100644 src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/main.d.ts.map create mode 100644 src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/vpnadmin.d.ts create mode 100644 src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/vpnadmin.d.ts.map create mode 100644 src/bin/hamcore/wwwroot/admin/default/package-lock.json create mode 100644 src/bin/hamcore/wwwroot/admin/default/package.json create mode 100644 src/bin/hamcore/wwwroot/admin/default/src/ts/main.ts create mode 100644 src/bin/hamcore/wwwroot/admin/default/theme.css create mode 100644 src/bin/hamcore/wwwroot/admin/default/tsconfig.json create mode 100644 src/bin/hamcore/wwwroot/admin/default/tsconfig_webpack.json create mode 100644 src/bin/hamcore/wwwroot/admin/default/tslint.json create mode 100644 src/bin/hamcore/wwwroot/admin/default/webpack.config.js create mode 100644 src/bin/hamcore/wwwroot/admin/index.html create mode 100644 src/bin/hamcore/wwwroot/index.html diff --git a/WARNING.TXT b/WARNING.TXT index 01c37e0a..f562dcec 100644 --- a/WARNING.TXT +++ b/WARNING.TXT @@ -104,6 +104,25 @@ be disabled anytime by setting up so on the VPN-client side. 2. VPN Software +The notes in this section are not specific to SoftEther VPN or VPN Gate, but +apply to general system software. SoftEther VPN Client, SoftEther VPN Server, +SoftEther VPN Bridge, and VPN Gate Relay Service will be installed on your +computer as system services. System services always run in the background. +System services usually do not appear on the computer display. Then your +computer system is booted, system services automatically start in the +background even before you or other users log in. To check whether +PacketiX-related system service is running, check the process list or the +background service list of your OS (called as "Services" in Windows, or +"Daemons" in UNIX.) You can activate, deactivate, start, or stop system +services using the functions of the OS anytime. PacketiX-related GUI tools for +managing system services communicate with these system services. After you +terminate these management GUI tools, PacketiX-related system services will +continue to run in the background. System services consume CPU time, computer +power, memory and disk space. Because system services consume power, your +electricity charges and amount of thermal of your computer increase as result. +In addition, there is a possibility that the mechanical parts of the life of +your computer is reduced. + 2.1. SoftEther VPN Client If you use SoftEther VPN Client on Windows, the Virtual Network Adapter device driver will be installed on Windows. The Virtual Network Adapter is diff --git a/src/BuildUtil/UnixBuildSoftwares.cs b/src/BuildUtil/UnixBuildSoftwares.cs index fcf502fa..ad353210 100644 --- a/src/BuildUtil/UnixBuildSoftwares.cs +++ b/src/BuildUtil/UnixBuildSoftwares.cs @@ -694,6 +694,9 @@ namespace BuildUtil sr.WriteLine("\t@echo \"You can choose your prefered language of {0} at any time.\"", BuildHelper.GetSoftwareTitle(this.Software)); sr.WriteLine("\t@echo \"To switch the current language, open and edit the 'lang.config' file.\""); + sr.WriteLine("\t@echo"); + sr.WriteLine("\t@echo"); + sr.WriteLine("\t@echo \"Note: the administrative password is not set on the VPN Server. Please set your own administrative password as soon as possible by vpncmd or the GUI manager.\""); sr.WriteLine("\t@echo"); sr.WriteLine("\t@echo"); @@ -707,6 +710,7 @@ namespace BuildUtil sr.WriteLine("\t@echo \"And please execute './vpncmd' to run the SoftEther VPN Command-Line Utility to configure {0}.\"", BuildHelper.GetSoftwareTitle(this.Software)); #endif sr.WriteLine("\t@echo"); + #if !BU_SOFTETHER sr.WriteLine("\t@echo \"Of course, you can use the VPN Server Manager GUI Application for Windows on the other Windows PC in order to configure the {0} remotely.\"", BuildHelper.GetSoftwareTitle(this.Software)); #else @@ -715,7 +719,6 @@ namespace BuildUtil #if !BU_SOFTETHER #else - sr.WriteLine("\t@echo"); sr.WriteLine("\t@echo"); sr.WriteLine("\t@echo \"*** For Windows users ***\""); sr.WriteLine("\t@echo \"You can download the SoftEther VPN Server Manager for Windows\""); @@ -730,6 +733,30 @@ namespace BuildUtil sr.WriteLine("\t@echo"); #endif + sr.WriteLine("\t@echo"); + + sr.WriteLine("\t@echo"); +#if !BU_SOFTETHER + sr.WriteLine("\t@echo \"*** SoftEther VPN Server HTML5 Web Administration Console (NEW) ***\""); +#else + sr.WriteLine("\t@echo \"*** PacketiX VPN Server HTML5 Web Administration Console (NEW) ***\""); +#endif + sr.WriteLine("\t@echo \"This VPN Server / Bridge has the built-in HTML5 Web Administration Console.\""); + sr.WriteLine("\t@echo"); + sr.WriteLine("\t@echo \"After you start the server daemon, you can open the HTML5 Web Administration Console is available at\""); + sr.WriteLine("\t@echo"); +#if !BU_SOFTETHER + sr.WriteLine("\t@echo \"https://127.0.0.1:8888/\""); + sr.WriteLine("\t@echo \" or\""); + sr.WriteLine("\t@echo \"https://ip_address_of_the_vpn_server:8888/\""); +#else + sr.WriteLine("\t@echo \"https://127.0.0.1:5555/\""); + sr.WriteLine("\t@echo \"or\""); + sr.WriteLine("\t@echo \"https://ip_address_of_the_vpn_server:5555/\""); +#endif + sr.WriteLine("\t@echo"); + sr.WriteLine("\t@echo \"This HTML5 page is obviously under construction, and your HTML5 development contribution is very appreciated.\""); + sr.WriteLine("\t@echo"); sr.WriteLine("\t@echo \"--------------------------------------------------------------------\""); sr.WriteLine("\t@echo"); diff --git a/src/BuildUtil/VpnBuilder.cs b/src/BuildUtil/VpnBuilder.cs index 801e1cd3..7c135793 100644 --- a/src/BuildUtil/VpnBuilder.cs +++ b/src/BuildUtil/VpnBuilder.cs @@ -552,6 +552,24 @@ namespace BuildUtil } } + // Delete node_modules file + public static void DeleteNodeModulesFilesFromHamCoreBuilder(HamCoreBuilder b) + { + List removeFiles = new List(); + foreach (HamCoreBuilderFileEntry f in b.FileList) + { + string name = f.Name; + if (name.IndexOf(@"\node_modules\", StringComparison.InvariantCultureIgnoreCase) != -1) + { + removeFiles.Add(name); + } + } + foreach (string file in removeFiles) + { + b.DeleteFile(file); + } + } + // Build Hamcore file public static void BuildHamcore() { @@ -594,6 +612,7 @@ namespace BuildUtil Con.WriteLine("* Building hamcore ..."); DeleteSVNFilesFromHamCoreBuilder(b); + DeleteNodeModulesFilesFromHamCoreBuilder(b); try { @@ -619,6 +638,7 @@ namespace BuildUtil } DeleteSVNFilesFromHamCoreBuilder(b); + DeleteNodeModulesFilesFromHamCoreBuilder(b); try { diff --git a/src/BuildUtil/VpnBuilderConfig.cs b/src/BuildUtil/VpnBuilderConfig.cs index f84f7c0a..ee9573b2 100644 --- a/src/BuildUtil/VpnBuilderConfig.cs +++ b/src/BuildUtil/VpnBuilderConfig.cs @@ -421,7 +421,7 @@ namespace BuildUtil { // Windows public static readonly OS Windows = new OS("windows", "Windows", - "Windows 98 / 98 SE / ME / NT 4.0 SP6a / 2000 SP4 / XP SP2, SP3 / Vista SP1, SP2 / 7 SP1 / 8 / 8.1 / 10 / Server 2003 SP2 / Server 2008 SP1, SP2 / Hyper-V Server 2008 / Server 2008 R2 SP1 / Hyper-V Server 2008 R2 / Server 2012 / Hyper-V Server 2012 / Server 2012 R2 / Hyper-V Server 2012 R2 / Server 2016", + "Windows 98 / 98 SE / ME / NT 4.0 SP6a / 2000 SP4 / XP SP2, SP3 / Vista SP1, SP2 / 7 SP1 / 8 / 8.1 / 10 / Server 2003 SP2 / Server 2008 SP1, SP2 / Hyper-V Server 2008 / Server 2008 R2 SP1 / Hyper-V Server 2008 R2 / Server 2012 / Hyper-V Server 2012 / Server 2012 R2 / Hyper-V Server 2012 R2 / Server 2016 / Server 2019", new Cpu[] { CpuList.intel, diff --git a/src/BuildUtil/Win32BuildUtil.cs b/src/BuildUtil/Win32BuildUtil.cs index e621b231..3d80fe2d 100644 --- a/src/BuildUtil/Win32BuildUtil.cs +++ b/src/BuildUtil/Win32BuildUtil.cs @@ -581,6 +581,16 @@ namespace BuildUtil return false; } + if (Str.InStr(srcPath, @"\node_modules\", false)) + { + return false; + } + + if (Str.InStr(srcPath, @"\wwwroot\", false)) + { + return true; + } + foreach (string ext in exts) { if (srcPath.EndsWith(ext, StringComparison.InvariantCultureIgnoreCase)) diff --git a/src/Cedar/Admin.c b/src/Cedar/Admin.c index 3ff53474..f622f67b 100644 --- a/src/Cedar/Admin.c +++ b/src/Cedar/Admin.c @@ -373,6 +373,1140 @@ CAPSLIST *ScGetCapsEx(RPC *rpc) return t; } +// Process server side include +BUF *AdminWebProcessServerSideInclude(BUF *src_txt, char *filename, UINT depth) +{ + char *src_str; + UINT src_str_size; + UINT i, len; + BUF *ret = NULL; + UINT pos = 0; + char dirname[MAX_PATH]; + if (src_txt == NULL || filename == NULL || depth >= 4) + { + return CloneBuf(src_txt); + } + if (EndWith(filename, ".html") == false) + { + // We process only .html files + return CloneBuf(src_txt); + } + + GetDirNameFromFilePath(dirname, sizeof(dirname), filename); + + src_str_size = src_txt->Size + 1; + src_str = ZeroMalloc(src_str_size); + + Copy(src_str, src_txt->Buf, src_txt->Size); + + len = StrLen(src_str); + + ret = NewBuf(); + + for (i = 0;i < len;i++) + { + char *start_tag = ""; + UINT x; + + Zero(inc_filename, sizeof(inc_filename)); + + StrCpy(inc_filename, sizeof(inc_filename), src_str + i + StrLen(start_tag) + 1); + inc_filename[b - (i + StrLen(start_tag) + 1)] = 0; + + x = SearchStrEx(src_str, end_tag, b + 1, true); + + if ((x != INFINITE) && (x >= (b + 1))) + { + BUF *inc_buf; + char full_inc_filename[MAX_PATH]; + + if (StartWith(inc_filename, "/")) + { + Format(full_inc_filename, sizeof(full_inc_filename), "|wwwroot/%s", inc_filename + 1); + } + else + { + StrCpy(full_inc_filename, sizeof(full_inc_filename), dirname); + StrCat(full_inc_filename, sizeof(full_inc_filename), "/"); + StrCat(full_inc_filename, sizeof(full_inc_filename), inc_filename); + } + + Debug("dirname = %s, full_inc_filename (src) = %s\n\n", dirname, full_inc_filename); + NormalizePath(full_inc_filename, sizeof(full_inc_filename), full_inc_filename); + + if (StartWith(full_inc_filename, "|wwwroot/") == false + && StartWith(full_inc_filename, "|wwwroot\\") == false) + { + char tmp[MAX_PATH]; + Format(tmp, sizeof(tmp), "|wwwroot/%s", full_inc_filename); + StrCpy(full_inc_filename, sizeof(full_inc_filename), tmp); + } + + Debug("inc_filename = %s\nfull_inc_filename = %s\n\n", inc_filename, full_inc_filename); + + inc_buf = ReadDump(full_inc_filename); + + if (inc_buf != NULL) + { + BUF *inc_buf2; + + inc_buf2 = AdminWebProcessServerSideInclude(inc_buf, full_inc_filename, depth + 1); + + BufSkipUtf8Bom(inc_buf2); + WriteBufBufWithOffset(ret, inc_buf2); + + FreeBuf(inc_buf); + FreeBuf(inc_buf2); + } + else + { + Debug("Loading SSI '%s' error.\n", inc_buf); + } + + i = (x + StrLen(end_tag) - 1); + + is_ssi = true; + } + } + } + } + + if (is_ssi == false) + { + WriteBufChar(ret, src_str[i]); + } + } + + Free(src_str); + + return ret; +} + +// Handle the file request +bool AdminWebHandleFileRequest(ADMIN *a, CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_src, char *query_string, char *virtual_root_dir, char *physical_root_dir) +{ + bool ret = false; + char url[MAX_PATH]; + UINT i, len; + if (a == NULL || c == NULL || s == NULL || h == NULL || url == NULL || query_string == NULL || + virtual_root_dir == NULL || physical_root_dir == NULL) + { + return false; + } + + StrCpy(url, sizeof(url), url_src); + + len = StrLen(url); + for (i = 0;i < len;i++) + { + if (url[i] == '\\') + { + url[i] = '/'; + } + } + + // Is dangerous URL? + if (InStr(url, "..") || InStr(url, "//") || InStr(url, "\\\\") || InStr(url, "/\\") || InStr(url, "\\/")) + { + ret = AdminWebSend404Error(s, h); + } + else + { + char filename[MAX_PATH]; + bool is_index_file = false; + + BUF *b = AdminWebTryFindAndReadFile(virtual_root_dir, physical_root_dir, url, + filename, sizeof(filename), &is_index_file); + + if (b == NULL) + { + ret = AdminWebSend404Error(s, h); + } + else + { + if (is_index_file && EndWith(url, "/") == false) + { + char url2[MAX_PATH]; + StrCpy(url2, sizeof(url2), url); + StrCat(url2, sizeof(url2), "/"); + ret = AdminWebSend302Redirect(s, url2, query_string, h); + } + else if (is_index_file == false && EndWith(url, "/")) + { + char url2[MAX_PATH]; + TrimEndWith(url2, sizeof(url2), url, "/"); + ret = AdminWebSend302Redirect(s, url2, query_string, h); + } + else + { + BUF *b2 = AdminWebProcessServerSideInclude(b, filename, 0); + char *mime = GetMimeTypeFromFileName(filename); + + if (mime == NULL) + { + mime = "application/octet-stream"; + } + + ret = AdminWebSendBody(s, 200, "OK", b2->Buf, b2->Size, mime, NULL, NULL, h); + + FreeBuf(b2); + } + FreeBuf(b); + } + } + + return ret; +} + +// Try to find a file, and if exists return the file contents +BUF *AdminWebTryFindAndReadFile(char *vroot, char *proot, char *url, char *ret_filename, UINT ret_filename_size, bool *is_index_html) +{ + char tmp[MAX_PATH]; + char tmp2[MAX_PATH]; + UINT vroot_len; + UINT url_len; + char relative_path[MAX_PATH]; + BUF *b; + if (vroot == NULL || proot == NULL || url == NULL || ret_filename == NULL || is_index_html == NULL) + { + return NULL; + } + + *is_index_html = false; + + if (StartWith(url, vroot) == false) + { + return NULL; + } + + vroot_len = StrLen(vroot); + url_len = StrLen(url); + + StrCpy(relative_path, sizeof(relative_path), url + vroot_len); + + if (StartWith(relative_path, "/")) + { + char tmp3[MAX_PATH]; + + StrCpy(tmp3, sizeof(tmp3), relative_path + 1); + StrCpy(relative_path, sizeof(relative_path), tmp3); + } + + CombinePath(tmp, sizeof(tmp), proot, relative_path); + + // index.html + CombinePath(tmp2, sizeof(tmp2), tmp, "index.html"); + b = AdminWebTryOneFile(tmp2, ret_filename, ret_filename_size); + if (b != NULL) + { + *is_index_html = true; + return b; + } + + // dirname/filename + StrCpy(tmp2, sizeof(tmp2), tmp); + b = AdminWebTryOneFile(tmp2, ret_filename, ret_filename_size); + if (b != NULL) + { + return b; + } + + return NULL; +} +BUF *AdminWebTryOneFile(char *filename, char *ret_filename, UINT ret_filename_size) +{ + BUF *b; + if (filename == NULL || ret_filename == NULL) + { + return NULL; + } + + b = ReadDump(filename); + if (b == NULL) + { + return NULL; + } + + StrCpy(ret_filename, ret_filename_size, filename); + + return b; +} + +// Send a 401 Unauthorized error +bool AdminWebSendUnauthorized(SOCK *s, HTTP_HEADER *http_request_headers) +{ + char *http_401_str = "\r\n\r\n401 Unauthorized\r\n\r\n

" CEDAR_SERVER_STR ": Administrative authentication required.

\r\n

This VPN Server could not verify that you are authorized to access to the \r\nserver in administrative mode.

\r\n

For web browser logins:
You must supply the HTTP basic \r\nauthentication credential as following.

\r\n
    \r\n\t
  • To login to the VPN server as the entire server administrator, specify empty or "administrator" as the username field, and specify the server administrative \r\n\tpassword as the password field.
  • \r\n\t
  • To login to a particular Virtual Hub as the hub administrator, specify \r\n\tthe hub name as the username field, and specify the hub administrative \r\n\tpassword as the password field.
  • \r\n
\r\n

For JSON-RPC client logins:
Instead to HTTP basic \r\nauthentication, you can also specify the HTTP header parameters as following.

\r\n
    \r\n\t
  • X-VPNADMIN-HUBNAME: Empty to login to the VPN Server as the entire \r\n\tserver administrator, or specify the target Virtual Hub name as the hub \r\n\tadministrator.
  • \r\n\t
  • X-VPNADMIN-PASSWORD: Specify the administrative password.
  • \r\n
\r\n\r\n"; + bool ret; + // Validate arguments + if (s == NULL || http_request_headers == NULL) + { + return false; + } + + // Creating a Data + ret = AdminWebSendBody(s, 401, "Unauthorized", http_401_str, StrLen(http_401_str), HTTP_CONTENT_TYPE, + "WWW-Authenticate", + "Basic realm=\"Username 'administrator' for entire VPN Server privilege, or specify Virtual Hub name as the username for specified Virtual Hub administrative privilege.\"", + http_request_headers); + + return ret; +} + +// Send reply +bool AdminWebSendBody(SOCK *s, UINT status_code, char *status_string, UCHAR *data, UINT data_size, char *content_type, char *add_header_name, char *add_header_value, + HTTP_HEADER *request_headers) +{ + HTTP_HEADER *h; + char date_str[MAX_SIZE]; + char error_code_str[16]; + bool ret = false; + HTTP_VALUE *origin; + if (s == NULL || status_string == NULL || (data_size != 0 && data == NULL) || request_headers == NULL) + { + return false; + } + if (content_type == NULL) + { + content_type = "text/html; charset=utf-8"; + } + + ToStr(error_code_str, status_code); + GetHttpDateStr(date_str, sizeof(date_str), SystemTime64()); + + h = NewHttpHeader("HTTP/1.1", error_code_str, status_string); + + if (StrCmpi(request_headers->Method, "OPTIONS") == 0) + { + AddHttpValue(h, NewHttpValue("Allow", "OPTIONS, GET, POST")); + } + + AddHttpValue(h, NewHttpValue("Cache-Control", "no-cache")); + AddHttpValue(h, NewHttpValue("Content-Type", content_type)); + AddHttpValue(h, NewHttpValue("Date", date_str)); + AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive")); + AddHttpValue(h, NewHttpValue("Access-Control-Allow-Methods", "OPTIONS,GET,POST")); + AddHttpValue(h, NewHttpValue("Access-Control-Allow-Headers", "X-VPNADMIN-HUBNAME,X-VPNADMIN-PASSWORD")); + AddHttpValue(h, NewHttpValue("Access-Control-Allow-Credentials", "true")); + + origin = GetHttpValue(request_headers, "Origin"); + if (origin != NULL) + { + AddHttpValue(h, NewHttpValue("Access-Control-Allow-Origin", origin->Data)); + } + + if (add_header_name != NULL && add_header_value != NULL) + { + AddHttpValue(h, NewHttpValue(add_header_name, add_header_value)); + } + + ret = PostHttp(s, h, data, data_size); + + FreeHttpHeader(h); + + return ret; +} + +// Send 404 error +bool AdminWebSend404Error(SOCK *s, HTTP_HEADER *request_headers) +{ + char *body = "\r\n404 Not Found

Not Found

The requested URL was not found on this server.

\r\n"; + if (s == NULL || request_headers == NULL) + { + return false; + } + + return AdminWebSendBody(s, 404, "Not Found", body, StrLen(body), NULL, NULL, NULL, request_headers); +} + +// Send 302 redirect +bool AdminWebSend302Redirect(SOCK *s, char *url, char *query_string, HTTP_HEADER *request_headers) +{ + bool ret = false; + char *txt; + UINT txt_size; + char *url2; + UINT url2_size; + char *body = "Object moved\r\n

Object moved to here.

\r\n"; + if (s == NULL || url == NULL || request_headers == NULL) + { + return false; + } + + url2_size = (StrSize(url) + StrSize(query_string) + MAX_SIZE) * 2; + url2 = ZeroMalloc(url2_size); + + StrCpy(url2, url2_size, url); + if (IsEmptyStr(query_string) == false) + { + StrCat(url2, url2_size, "?"); + StrCat(url2, url2_size, query_string); + } + + txt_size = (StrSize(body) + StrSize(url2) + MAX_SIZE) * 2; + txt = ZeroMalloc(txt_size); + + ReplaceStrEx(txt, txt_size, body, "$URL$", url2, false); + + ret = AdminWebSendBody(s, 302, "Found", txt, StrLen(txt), NULL, "Location", url2, request_headers); + + Free(txt); + + Free(url2); + + return ret; +} + +// "/admin" web page POST handler +void AdminWebProcPost(CONNECTION *c, SOCK *s, HTTP_HEADER *h, UINT post_data_size, char *url_target) +{ + ADMIN *a; + UCHAR *data; + char url[MAX_PATH]; + char query_string[MAX_SIZE]; + UINT i; + if (c == NULL || s == NULL || h == NULL || url_target == NULL) + { + return; + } + + a = JsonRpcAuthLogin(c->Cedar, s, h); + if (a == NULL) + { + RecvAllWithDiscard(s, post_data_size, s->SecureMode); + AdminWebSendUnauthorized(s, h); + return; + } + + if (post_data_size > a->MaxJsonRpcRecvSize) + { + Disconnect(s); + return; + } + + data = ZeroMalloc(post_data_size + 1); + + if (RecvAll(s, data, post_data_size, s->SecureMode)) + { + c->JsonRpcAuthed = true; + + // Divide url_target into URL and query string + StrCpy(url, sizeof(url), url_target); + Zero(query_string, sizeof(query_string)); + i = SearchStr(url, "?", 0); + if (i != INFINITE) + { + StrCpy(query_string, sizeof(query_string), url + i + 1); + url[i] = 0; + } + + AdminWebHandleFileRequest(a, c, s, h, url, query_string, "/admin", "|wwwroot/admin"); + } + + Free(data); + Free(a); +} + +// "/admin" web page GET handler +void AdminWebProcGet(CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_target) +{ + ADMIN *a; + char url[MAX_PATH]; + char query_string[MAX_SIZE]; + UINT i; + if (c == NULL || s == NULL || h == NULL || url_target == NULL) + { + return; + } + + a = JsonRpcAuthLogin(c->Cedar, s, h); + if (a == NULL) + { + AdminWebSendUnauthorized(s, h); + return; + } + + c->JsonRpcAuthed = true; + + // Divide url_target into URL and query string + StrCpy(url, sizeof(url), url_target); + Zero(query_string, sizeof(query_string)); + i = SearchStr(url, "?", 0); + if (i != INFINITE) + { + StrCpy(query_string, sizeof(query_string), url + i + 1); + url[i] = 0; + } + + AdminWebHandleFileRequest(a, c, s, h, url, query_string, "/admin", "|wwwroot/admin"); + + Free(a); +} + +// New JSON-RPC Result +JSON_VALUE *JsonRpcNewResponse(PACK *p) +{ + JSON_VALUE *jv; + JSON_OBJECT *jo; + JSON_VALUE *jv2; + + if (p == NULL) + { + return NULL; + } + + jv = JsonNewObject(); + jo = JsonValueGetObject(jv); + + jv2 = PackToJson(p); + + JsonSet(jo, "result", jv2); + + return jv; +} + +// New JSON-RPC Error +JSON_VALUE *JsonRpcNewError(int code, wchar_t *message) +{ + wchar_t msg[MAX_PATH]; + JSON_VALUE *jv; + JSON_OBJECT *jo; + JSON_VALUE *jv2; + JSON_OBJECT *jo2; + + if (UniIsEmptyStr(message)) + { + UniFormat(msg, sizeof(msg), L"Error code %u", code); + } + else + { + UniFormat(msg, sizeof(msg), L"Error code %u: %s", code, message); + } + + jv = JsonNewObject(); + jo = JsonValueGetObject(jv); + + jv2 = JsonNewObject(); + jo2 = JsonValueGetObject(jv2); + + JsonSet(jo, "error", jv2); + + JsonSetNumber(jo2, "code", (UINT64)code); + JsonSetUniStr(jo2, "message", msg); + + return jv; +} + +// JSON-RPC process request object +JSON_VALUE *JsonRpcProcRequestObject(ADMIN *admin, CONNECTION *c, SOCK *s, JSON_VALUE *json_req, char *method_name) +{ + PACK *pack_request; + JSON_VALUE *ret = NULL; + if (c == NULL || s == NULL || json_req == NULL || admin == NULL) + { + return NULL; + } + + pack_request = JsonToPack(json_req); + + PackAddStr(pack_request, "function_name", method_name); + + if (pack_request != NULL) + { + RPC *rpc; + PACK *pack_response; + UINT err; + + // RPC Server + rpc = StartRpcServer(s, AdminDispatch, admin); + + admin->Rpc = rpc; + + pack_response = CallRpcDispatcher(rpc, pack_request); + + if (pack_response == NULL) + { + pack_response = PackError(ERR_NOT_SUPPORTED); + } + + RpcFreeEx(rpc, true); + + FreePack(pack_request); + + // Construct response object + err = GetErrorFromPack(pack_response); + if (err != 0) + { + // Return the error + ret = JsonRpcNewError(err, _E(err)); + } + else + { + // Return the PACK + ret = JsonRpcNewResponse(pack_response); + } + + SLog(admin->Server->Cedar, "LS_API_RPC_CALL", + &s->RemoteIP, s->RemotePort, s->RemoteHostname, + method_name, err, _E(err)); + + FreePack(pack_response); + } + + return ret; +} + +// JSON-RPC HTTP user authentication +bool HttpParseBasicAuthHeader(HTTP_HEADER *h, char *username, UINT username_size, char *password, UINT password_size) +{ + bool ret = false; + HTTP_VALUE *auth_value; + HTTP_VALUE *vpnadmin_hubname; + HTTP_VALUE *vpnadmin_password; + if (h == NULL || username == NULL || password == NULL) + { + return false; + } + + auth_value = GetHttpValue(h, "Authorization"); + vpnadmin_hubname = GetHttpValue(h, "X-VPNADMIN-HUBNAME"); + vpnadmin_password = GetHttpValue(h, "X-VPNADMIN-PASSWORD"); + + if (vpnadmin_password != NULL) + { + if (vpnadmin_hubname == NULL) + { + StrCpy(username, username_size, ""); + } + else + { + StrCpy(username, username_size, vpnadmin_hubname->Data); + } + + StrCpy(password, password_size, vpnadmin_password->Data); + + ret = true; + } + + if (ret == false && auth_value != NULL) + { + char key[32], value[MAX_SIZE]; + + if (GetKeyAndValue(auth_value->Data, key, sizeof(key), value, sizeof(value), " \t")) + { + if (StrCmpi(key, "Basic") == 0 && IsEmptyStr(value) == false) + { + UINT b64_dest_size = StrSize(value) * 2 + 256; + char *b64_dest = ZeroMalloc(b64_dest_size); + + Decode64(b64_dest, value); + + if (IsEmptyStr(b64_dest) == false) + { + if (b64_dest[0] == ':') + { + // Empty username + StrCpy(username, username_size, ""); + StrCpy(password, password_size, b64_dest + 1); + ret = true; + } + else + { + if (GetKeyAndValue(b64_dest, username, username_size, password, password_size, ":")) + { + ret = true; + } + } + } + + Free(b64_dest); + } + } + } + + return ret; +} + +// JSON-RPC Login +ADMIN *JsonRpcAuthLogin(CEDAR *c, SOCK *sock, HTTP_HEADER *h) +{ + ADMIN *a = NULL; + char username[MAX_HUBNAME_LEN + 1]; + char password[MAX_PASSWORD_LEN + 1]; + SERVER *s; + char empty_pw_hash[SHA1_SIZE]; + + if (c == NULL || h == NULL || sock == NULL) + { + return NULL; + } + + s = c->Server; + + HashAdminPassword(empty_pw_hash, ""); + + Zero(username, sizeof(username)); + Zero(password, sizeof(password)); + + if (HttpParseBasicAuthHeader(h, username, sizeof(username), password, sizeof(password))) + { + char pw_hash[SHA1_SIZE]; + bool is_server_admin = false; + bool is_hub_admin = false; + char hub_name[MAX_HUBNAME_LEN + 1]; + + HashAdminPassword(pw_hash, password); + + Zero(hub_name, sizeof(hub_name)); + + // Check if the server administrator password is empty. If yes, login always success. + if (Cmp(s->HashedPassword, empty_pw_hash, SHA1_SIZE) == 0) + { + is_server_admin = true; + } + else + { + if (IsEmptyStr(username) || StrCmpi(username, ADMINISTRATOR_USERNAME) == 0) + { + // If the username is empty or 'administrator', verify with the server admin password. + if (Cmp(s->HashedPassword, pw_hash, SHA1_SIZE) == 0) + { + is_server_admin = true; + } + } + } + + if (is_server_admin == false) + { + HUB *h; + // Hub admin mode + LockHubList(c); + { + h = GetHub(c, username); + } + UnlockHubList(c); + + if (h != NULL) + { + Lock(h->lock); + { + if (Cmp(pw_hash, h->HashedPassword, SHA1_SIZE) == 0) + { + is_hub_admin = true; + + StrCpy(hub_name, sizeof(hub_name), h->Name); + } + } + Unlock(h->lock); + + ReleaseHub(h); + } + } + + if (is_server_admin || is_hub_admin) + { + if (CheckAdminSourceAddress(sock, hub_name)) + { + a = ZeroMalloc(sizeof(ADMIN)); + + a->Server = s; + a->ServerAdmin = is_server_admin; + a->ClientBuild = c->Build; + + if (is_hub_admin) + { + StrCpy(a->dummy1, sizeof(a->dummy1), hub_name); + a->HubName = a->dummy1; + } + } + } + } + + if (a != NULL) + { + char admin_mode[256]; + if (a->ServerAdmin) + { + a->MaxJsonRpcRecvSize = ADMIN_RPC_MAX_POST_SIZE_BY_SERVER_ADMIN; + } + else + { + a->MaxJsonRpcRecvSize = ADMIN_RPC_MAX_POST_SIZE_BY_HUB_ADMIN; + } + + if (IsEmptyStr(a->HubName)) + { + StrCpy(admin_mode, sizeof(admin_mode), + "Entire VPN Server Admin Mode"); + } + else + { + Format(admin_mode, sizeof(admin_mode), + "Virtual Hub Admin Mode for '%s'", + a->HubName); + } + + SLog(s->Cedar, "LS_API_AUTH_OK", + &sock->RemoteIP, sock->RemotePort, sock->RemoteHostname, + admin_mode, username, h->Method, h->Target); + } + else + { + SLog(s->Cedar, "LS_API_AUTH_ERROR", + &sock->RemoteIP, sock->RemotePort, sock->RemoteHostname, + username, h->Method, h->Target); + } + + + return a; +} + +// Query string to JSON list value +JSON_VALUE *QueryStringToJsonListValue(char *qs) +{ + TOKEN_LIST *t; + UINT i; + LIST *distinct_list = NULL; + JSON_VALUE *v = NULL; + JSON_OBJECT *o = NULL; + if (qs == NULL) + { + return NULL; + } + + t = ParseTokenWithoutNullStr(qs, "&"); + if (t == NULL) + { + return NULL; + } + + distinct_list = NewStrList(); + + v = JsonNewObject(); + o = JsonValueGetObject(v); + + for (i = 0;i < t->NumTokens;i++) + { + char *token = t->Token[i]; + UINT pos; + + pos = SearchStr(token, "=", 0); + if (pos != INFINITE) + { + char *key_decoded; + char *value_decoded; + char *key = CopyStr(token); + char *value = CopyStr(token + pos + 1); + + key[pos] = 0; + key_decoded = UrlDecode(key); + value_decoded = UrlDecode(value); + + if (key_decoded != NULL && value_decoded != NULL) + { + if (AddStrToStrListDistinct(distinct_list, key_decoded)) + { + JsonSetStr(o, key_decoded, value_decoded); + } + } + + Free(value_decoded); + Free(key_decoded); + Free(key); + Free(value); + } + } + + FreeToken(t); + + FreeStrList(distinct_list); + + return v; +} + +// Construct new JSON-RPC dummy request +JSON_VALUE *ConstructDummyJsonRpcRequest(char *method_name, JSON_VALUE *p) +{ + JSON_VALUE *ret; + JSON_OBJECT *ret_object; + UCHAR rand[16]; + char id_str[64]; + + Rand(rand, sizeof(rand)); + + BinToStr(id_str, sizeof(id_str), rand, sizeof(rand)); + + ret = JsonNewObject(); + ret_object = JsonObject(ret); + + JsonSetStr(ret_object, "jsonrpc", "2.0"); + JsonSetStr(ret_object, "method", method_name); + JsonSet(ret_object, "params", p); + JsonSetStr(ret_object, "id", id_str); + + return ret; +} + +// JSON-RPC Options Dispatch +void JsonRpcProcOptions(CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_target) +{ + if (c == NULL || s == NULL || h == NULL || url_target == NULL) + { + return; + } + + c->JsonRpcAuthed = true; + + + AdminWebSendBody(s, 200, "OK", NULL, 0, NULL, NULL, NULL, h); +} + +// JSON-RPC GET Dispatch +void JsonRpcProcGet(CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_target) +{ + ADMIN *a; + char url[MAX_PATH]; + char query_string[MAX_SIZE]; + UINT i; + bool reply_sent = false; + if (c == NULL || s == NULL || h == NULL || url_target == NULL) + { + return; + } + + a = JsonRpcAuthLogin(c->Cedar, s, h); + if (a == NULL) + { + AdminWebSendUnauthorized(s, h); + return; + } + + c->JsonRpcAuthed = true; + + + // Divide url_target into URL and query string + StrCpy(url, sizeof(url), url_target); + Zero(query_string, sizeof(query_string)); + i = SearchStr(url, "?", 0); + if (i != INFINITE) + { + StrCpy(query_string, sizeof(query_string), url + i + 1); + url[i] = 0; + } + + if (StartWith(url, "/api/")) + { + // Call a method + JSON_VALUE *params_value = NULL; + JSON_OBJECT *params_object = NULL; + UINT i; + char method_name[MAX_PATH]; + + StrCpy(method_name, sizeof(method_name), url + 5); + + i = SearchStr(method_name, "/", 0); + if (i != INFINITE) + { + method_name[i] = 0; + } + + if (IsEmptyStr(method_name) == false) + { + // Call a method + params_value = QueryStringToJsonListValue(query_string); + + if (params_value != NULL) + { + JSON_VALUE *json_ret = NULL; + char id[96]; + char *ret_str = NULL; + + GetDateTimeStrMilli64(id, sizeof(id), LocalTime64()); + + params_object = JsonObject(params_value); + + // Process the request + json_ret = JsonRpcProcRequestObject(a, c, s, params_value, method_name); + + if (json_ret == NULL) + { + json_ret = JsonRpcNewError(ERR_INTERNAL_ERROR, L"Internal error"); + } + + JsonSetStr(JsonObject(json_ret), "jsonrpc", "2.0"); + JsonSetStr(JsonObject(json_ret), "id", id); + + ret_str = JsonToStr(json_ret); + + AdminWebSendBody(s, 200, "OK", ret_str, StrLen(ret_str), "text/plain; charset=UTF-8", NULL, NULL, h); + + Free(ret_str); + JsonFree(json_ret); + JsonFree(params_value); + } + } + } + + + if (reply_sent == false) + { + BUF *html_buf = ReadDump("|vpnserver_api_doc.html"); + + if (html_buf != NULL) + { + AdminWebSendBody(s, 200, "OK", html_buf->Buf, html_buf->Size, "text/html; charset=UTF-8", NULL, NULL, h); + + FreeBuf(html_buf); + } + else + { + AdminWebSend404Error(s, h); + } + } + + if (a->LogFileList != NULL) + { + FreeEnumLogFile(a->LogFileList); + } + Free(a); +} + +// JSON-RPC POST Dispatch +void JsonRpcProcPost(CONNECTION *c, SOCK *s, HTTP_HEADER *h, UINT post_data_size) +{ + ADMIN *a; + UCHAR *data; + if (c == NULL || s == NULL || h == NULL) + { + return; + } + + a = JsonRpcAuthLogin(c->Cedar, s, h); + if (a == NULL) + { + RecvAllWithDiscard(s, post_data_size, s->SecureMode); + AdminWebSendUnauthorized(s, h); + return; + } + + if (post_data_size > a->MaxJsonRpcRecvSize) + { + Disconnect(s); + return; + } + + data = ZeroMalloc(post_data_size + 1); + + if (RecvAll(s, data, post_data_size, s->SecureMode)) + { + // Parse JSON + JSON_VALUE *json_req = StrToJson(data); + JSON_OBJECT *json_req_object = JsonObject(json_req); + JSON_VALUE *json_ret = NULL; + char *res = NULL; + char *request_id = NULL; + char *method_name = NULL; + + c->JsonRpcAuthed = true; + + + if (json_req == NULL || json_req_object == NULL) + { + // Parse error + json_ret = JsonRpcNewError(ERR_INVALID_PARAMETER, L"Parameter is invalid: JSON-RPC Parse Error"); + } + else + { + // check the JSON-RPC version + char *ver_str = JsonGetStr(json_req_object, "jsonrpc"); + if (StrCmpi(ver_str, "2.0") != 0) + { + // Invalid version + json_ret = JsonRpcNewError(ERR_INVALID_PARAMETER, L"JSON-RPC version is invalid"); + } + else + { + JSON_VALUE *params_value = NULL; + JSON_OBJECT *params_object = NULL; + + // Get Request ID + request_id = JsonGetStr(json_req_object, "id"); + + // Get method name + method_name = JsonGetStr(json_req_object, "method"); + + // Get parameters + params_value = JsonGet(json_req_object, "params"); + params_object = JsonObject(params_value); + + if (IsEmptyStr(method_name)) + { + // method is empty + json_ret = JsonRpcNewError(ERR_INVALID_PARAMETER, L"JSON-RPC method name is empty"); + } + else if (params_value == NULL || params_object == NULL) + { + // params is empty + json_ret = JsonRpcNewError(ERR_INVALID_PARAMETER, L"JSON-RPC parameter is empty"); + } + else + { + // Process the request + json_ret = JsonRpcProcRequestObject(a, c, s, params_value, method_name); + } + } + } + + if (json_ret == NULL) + { + json_ret = JsonRpcNewError(ERR_INTERNAL_ERROR, L"Internal error"); + } + + JsonSetStr(JsonObject(json_ret), "jsonrpc", "2.0"); + if (request_id == NULL) + { + request_id = "0"; + } + JsonSetStr(JsonObject(json_ret), "id", request_id); + + res = JsonToStr(json_ret); + + AdminWebSendBody(s, 200, "OK", res, StrLen(res), "application/json", NULL, NULL, h); + + Free(res); + + JsonFree(json_ret); + JsonFree(json_req); + } + + Free(data); + + if (a->LogFileList != NULL) + { + FreeEnumLogFile(a->LogFileList); + } + Free(a); +} + // Dispatch routine for Administration RPC PACK *AdminDispatch(RPC *rpc, char *name, PACK *p) { @@ -1103,11 +2237,6 @@ UINT StMakeOpenVpnConfigFile(ADMIN *a, RPC_READ_LOG_FILE *t) UCHAR *zero_buffer; UINT zero_buffer_size = 128 * 1024; char name_tmp[MAX_SIZE]; - X *dummy_x = NULL; - K *dummy_private_k = NULL; - K *dummy_public_k = NULL; - BUF *dummy_x_buf = NULL; - BUF *dummy_k_buf = NULL; zero_buffer = ZeroMalloc(zero_buffer_size); @@ -1145,34 +2274,6 @@ UINT StMakeOpenVpnConfigFile(ADMIN *a, RPC_READ_LOG_FILE *t) WriteBufChar(x_buf, 0); SeekBufToBegin(x_buf); - // Generate a dummy certificate - if (x != NULL) - { - if (RsaGen(&dummy_private_k, &dummy_public_k, x->bits)) - { - NAME *name; - wchar_t cn[128]; - - UniToStr64(cn, Rand64()); - - name = NewName(cn, cn, cn, L"US", NULL, NULL); - - dummy_x = NewRootX(dummy_public_k, dummy_private_k, name, GetDaysUntil2038Ex(), NULL); - - FreeName(name); - - dummy_x_buf = XToBuf(dummy_x, true); - SeekBufToEnd(dummy_x_buf); - WriteBufChar(dummy_x_buf, 0); - SeekBufToBegin(dummy_x_buf); - - dummy_k_buf = KToBuf(dummy_private_k, true, NULL); - SeekBufToEnd(dummy_k_buf); - WriteBufChar(dummy_k_buf, 0); - SeekBufToBegin(dummy_k_buf); - } - } - FreeX(x); Zero(hostname, sizeof(hostname)); Zero(tag_before_hostname, sizeof(tag_before_hostname)); @@ -1290,18 +2391,6 @@ UINT StMakeOpenVpnConfigFile(ADMIN *a, RPC_READ_LOG_FILE *t) "$CA$", x_buf->Buf, false); } - if (dummy_x_buf != NULL) - { - ReplaceStrEx((char *)config_l3_buf->Buf, config_l3_buf->Size, (char *)config_l3_buf->Buf, - "$CERT$", dummy_x_buf->Buf, false); - } - - if (dummy_k_buf != NULL) - { - ReplaceStrEx((char *)config_l3_buf->Buf, config_l3_buf->Size, (char *)config_l3_buf->Buf, - "$KEY$", dummy_k_buf->Buf, false); - } - Format(name_tmp, sizeof(name_tmp), "%sopenvpn_remote_access_l3.ovpn", my_hostname); ZipAddFileSimple(p, name_tmp, LocalTime64(), 0, config_l3_buf->Buf, StrLen(config_l3_buf->Buf)); @@ -1322,18 +2411,6 @@ UINT StMakeOpenVpnConfigFile(ADMIN *a, RPC_READ_LOG_FILE *t) "$CA$", x_buf->Buf, false); } - if (dummy_x_buf != NULL) - { - ReplaceStrEx((char *)config_l2_buf->Buf, config_l2_buf->Size, (char *)config_l2_buf->Buf, - "$CERT$", dummy_x_buf->Buf, false); - } - - if (dummy_k_buf != NULL) - { - ReplaceStrEx((char *)config_l2_buf->Buf, config_l2_buf->Size, (char *)config_l2_buf->Buf, - "$KEY$", dummy_k_buf->Buf, false); - } - Format(name_tmp, sizeof(name_tmp), "%sopenvpn_site_to_site_bridge_l2.ovpn", my_hostname); ZipAddFileSimple(p, name_tmp, LocalTime64(), 0, config_l2_buf->Buf, StrLen(config_l2_buf->Buf)); @@ -1354,13 +2431,6 @@ UINT StMakeOpenVpnConfigFile(ADMIN *a, RPC_READ_LOG_FILE *t) FreeBuf(readme_pdf_buf); FreeBuf(x_buf); - FreeX(dummy_x); - FreeK(dummy_private_k); - FreeK(dummy_public_k); - - FreeBuf(dummy_k_buf); - FreeBuf(dummy_x_buf); - Free(zero_buffer); } @@ -1954,8 +3024,20 @@ UINT StReadLogFile(ADMIN *a, RPC_READ_LOG_FILE *t) // Check the permission to read the log file if (a->LogFileList == NULL) { - // Cache not found - return ERR_OBJECT_NOT_FOUND; + // Enum the log files first + RPC_ENUM_LOG_FILE elf; + UINT elf_ret; + + Zero(&elf, sizeof(elf)); + + elf_ret = StEnumLogFile(a, &elf); + + FreeRpcEnumLogFile(&elf); + + if (elf_ret != ERR_NO_ERROR) + { + return elf_ret; + } } if (CheckLogFileNameFromEnumList(a->LogFileList, logfilename, servername) == false) { @@ -2020,6 +3102,10 @@ UINT StReadLogFile(ADMIN *a, RPC_READ_LOG_FILE *t) ALog(a, NULL, "LA_READ_LOG_FILE", servername, logfilename); } + StrCpy(t->FilePath, sizeof(t->FilePath), logfilename); + StrCpy(t->ServerName, sizeof(t->ServerName), servername); + t->Offset = offset; + return ERR_NO_ERROR; } @@ -2310,7 +3396,7 @@ UINT StSetCrl(ADMIN *a, RPC_CRL *t) if (crl == NULL) { - ret = ERR_INTERNAL_ERROR; + ret = ERR_OBJECT_NOT_FOUND; } else { @@ -2379,7 +3465,7 @@ UINT StGetCrl(ADMIN *a, RPC_CRL *t) if (crl == NULL) { - ret = ERR_INTERNAL_ERROR; + ret = ERR_OBJECT_NOT_FOUND; } else { @@ -2439,7 +3525,7 @@ UINT StDelCrl(ADMIN *a, RPC_CRL *t) if (crl == NULL) { - ret = ERR_INTERNAL_ERROR; + ret = ERR_OBJECT_NOT_FOUND; } else { @@ -3336,6 +4422,7 @@ UINT StGetHubAdminOptions(ADMIN *a, RPC_ADMIN_OPTION *t) StrCpy(e->Name, sizeof(e->Name), a->Name); e->Value = a->Value; + UniStrCpy(e->Descrption, sizeof(e->Descrption), GetHubAdminOptionHelpString(e->Name)); } } UnlockList(h->AdminOptionList); @@ -3368,6 +4455,7 @@ UINT StGetDefaultHubAdminOptions(ADMIN *a, RPC_ADMIN_OPTION *t) StrCpy(a->Name, sizeof(a->Name), admin_options[i].Name); a->Value = admin_options[i].Value; + UniStrCpy(a->Descrption, sizeof(a->Descrption), GetHubAdminOptionHelpString(a->Name)); } return ERR_NO_ERROR; @@ -3872,6 +4960,7 @@ UINT SiEnumIpTable(SERVER *s, char *hubname, RPC_ENUM_IP_TABLE *t) StrCpy(e->SessionName, sizeof(e->SessionName), table->Session->Name); e->Ip = IPToUINT(&table->Ip); Copy(&e->IpV6, &table->Ip, sizeof(IP)); + Copy(&e->IpAddress, &table->Ip, sizeof(IP)); e->DhcpAllocated = table->DhcpAllocated; e->CreatedTime = TickToTime(table->CreatedTime); e->UpdatedTime = TickToTime(table->UpdatedTime); @@ -4323,6 +5412,8 @@ UINT StGetSessionStatus(ADMIN *a, RPC_SESSION_STATUS *t) Copy(&t->ClientIp6, &s->Connection->ClientIp.ipv6_addr, sizeof(t->ClientIp6)); } + CopyIP(&t->ClientIpAddress, &s->Connection->ClientIp); + StrCpy(t->ClientHostName, sizeof(t->ClientHostName), s->Connection->ClientHostname); } } @@ -5485,30 +6576,33 @@ UINT StSetAccessList(ADMIN *a, RPC_ENUM_ACCESS_LIST *t) UINT i; // Confirm whether the access list of form which cannot handle by the old client already exists - if (a->ClientBuild < 6560) + if (a->ClientBuild != 0) { - for (i = 0;i < LIST_NUM(h->AccessList);i++) + if (a->ClientBuild < 6560) { - ACCESS *access = LIST_DATA(h->AccessList, i); - if (access->IsIPv6 || - access->Jitter != 0 || access->Loss != 0 || access->Delay != 0) + for (i = 0;i < LIST_NUM(h->AccessList);i++) { - ret = ERR_VERSION_INVALID; - break; + ACCESS *access = LIST_DATA(h->AccessList, i); + if (access->IsIPv6 || + access->Jitter != 0 || access->Loss != 0 || access->Delay != 0) + { + ret = ERR_VERSION_INVALID; + break; + } } } - } - if (a->ClientBuild < 8234) - { - for (i = 0;i < LIST_NUM(h->AccessList);i++) + if (a->ClientBuild < 8234) { - ACCESS *access = LIST_DATA(h->AccessList, i); - - if (IsEmptyStr(access->RedirectUrl) == false) + for (i = 0;i < LIST_NUM(h->AccessList);i++) { - ret = ERR_VERSION_INVALID; - break; + ACCESS *access = LIST_DATA(h->AccessList, i); + + if (IsEmptyStr(access->RedirectUrl) == false) + { + ret = ERR_VERSION_INVALID; + break; + } } } } @@ -6612,6 +7706,7 @@ UINT StGetCa(ADMIN *a, RPC_HUB_GET_CA *t) FreeRpcHubGetCa(t); Zero(t, sizeof(RPC_HUB_GET_CA)); + t->Key = key; StrCpy(t->HubName, sizeof(t->HubName), hubname); CHECK_RIGHT; @@ -7207,6 +8302,7 @@ UINT StGetSecureNATStatus(ADMIN *a, RPC_NAT_STATUS *t) ReleaseHub(h); + StrCpy(t->HubName, sizeof(t->HubName), hubname); ret = ERR_NO_ERROR; return ret; @@ -7446,8 +8542,8 @@ UINT StGetSecureNATOption(ADMIN *a, VH_OPTION *t) } Zero(t, sizeof(VH_OPTION)); - StrCpy(t->HubName, sizeof(t->HubName), hubname); Copy(t, h->SecureNATOption, sizeof(VH_OPTION)); + StrCpy(t->HubName, sizeof(t->HubName), hubname); t->ApplyDhcpPushRoutes = true; ReleaseHub(h); @@ -8058,6 +9154,13 @@ UINT StSetHub(ADMIN *a, RPC_CREATE_HUB *t) return ERR_NOT_SUPPORTED; } + // For JSON-RPC + if (StrLen(t->AdminPasswordPlainText) != 0) + { + Hash(t->HashedPassword, t->AdminPasswordPlainText, StrLen(t->AdminPasswordPlainText), true); + HashPassword(t->SecurePassword, ADMINISTRATOR_USERNAME, t->AdminPasswordPlainText); + } + if (IsZero(t->HashedPassword, sizeof(t->HashedPassword)) == false && IsZero(t->SecurePassword, sizeof(t->SecurePassword)) == false) { @@ -8228,6 +9331,15 @@ UINT StCreateHub(ADMIN *a, RPC_CREATE_HUB *t) ALog(a, NULL, "LA_CREATE_HUB", t->HubName); + // For JSON-RPC + if ((IsZero(t->HashedPassword, sizeof(t->HashedPassword)) && + IsZero(t->SecurePassword, sizeof(t->SecurePassword))) || + StrLen(t->AdminPasswordPlainText) != 0) + { + Hash(t->HashedPassword, t->AdminPasswordPlainText, StrLen(t->AdminPasswordPlainText), true); + HashPassword(t->SecurePassword, ADMINISTRATOR_USERNAME, t->AdminPasswordPlainText); + } + h = NewHub(c, t->HubName, &o); Copy(h->HashedPassword, t->HashedPassword, SHA1_SIZE); Copy(h->SecurePassword, t->SecurePassword, SHA1_SIZE); @@ -8636,6 +9748,15 @@ UINT StSetFarmSetting(ADMIN *a, RPC_FARM *t) return ERR_NOT_SUPPORTED; } + if (IsZero(t->MemberPassword, sizeof(t->MemberPassword))) + { + if (IsEmptyStr(t->MemberPasswordPlaintext) == false) + { + // For JSON-RPC + HashAdminPassword(t->MemberPassword, t->MemberPasswordPlaintext); + } + } + ALog(a, NULL, "LA_SET_FARM_SETTING"); IncrementServerConfigRevision(a->Server); @@ -8652,6 +9773,12 @@ UINT StSetServerPassword(ADMIN *a, RPC_SET_PASSWORD *t) SERVER_ADMIN_ONLY; + if (IsZero(t->HashedPassword, sizeof(t->HashedPassword))) + { + // For JSON-RPC + HashAdminPassword(t->HashedPassword, t->PlainTextPassword); + } + Copy(a->Server->HashedPassword, t->HashedPassword, SHA1_SIZE); ALog(a, NULL, "LA_SET_SERVER_PASSWORD"); @@ -9016,6 +10143,8 @@ void InDDnsClientStatus(DDNS_CLIENT_STATUS *t, PACK *p) PackGetStr(p, "DnsSuffix", t->DnsSuffix, sizeof(t->DnsSuffix)); PackGetStr(p, "CurrentIPv4", t->CurrentIPv4, sizeof(t->CurrentIPv4)); PackGetStr(p, "CurrentIPv6", t->CurrentIPv6, sizeof(t->CurrentIPv6)); + PackGetUniStr(p, "ErrStr_IPv4", t->ErrStr_IPv4, sizeof(t->ErrStr_IPv4)); + PackGetUniStr(p, "ErrStr_IPv6", t->ErrStr_IPv6, sizeof(t->ErrStr_IPv6)); } void OutDDnsClientStatus(PACK *p, DDNS_CLIENT_STATUS *t) { @@ -9032,6 +10161,8 @@ void OutDDnsClientStatus(PACK *p, DDNS_CLIENT_STATUS *t) PackAddStr(p, "DnsSuffix", t->DnsSuffix); PackAddStr(p, "CurrentIPv4", t->CurrentIPv4); PackAddStr(p, "CurrentIPv6", t->CurrentIPv6); + PackAddUniStr(p, "ErrStr_IPv4", t->ErrStr_IPv4); + PackAddUniStr(p, "ErrStr_IPv6", t->ErrStr_IPv6); } // INTERNET_SETTING @@ -9183,6 +10314,7 @@ void OutRpcEnumEtherIpId(PACK *p, RPC_ENUM_ETHERIP_ID *t) PackAddInt(p, "NumItem", t->NumItem); + PackSetCurrentJsonGroupName(p, "Settings"); for (i = 0;i < t->NumItem;i++) { ETHERIP_ID *e = &t->IdList[i]; @@ -9192,6 +10324,7 @@ void OutRpcEnumEtherIpId(PACK *p, RPC_ENUM_ETHERIP_ID *t) PackAddStrEx(p, "UserName", e->UserName, i, t->NumItem); PackAddStrEx(p, "Password", e->Password, i, t->NumItem); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcEnumEtherIpId(RPC_ENUM_ETHERIP_ID *t) { @@ -9362,6 +10495,7 @@ void OutRpcEnumEthVLan(PACK *p, RPC_ENUM_ETH_VLAN *t) return; } + PackSetCurrentJsonGroupName(p, "Devices"); for (i = 0;i < t->NumItem;i++) { RPC_ENUM_ETH_VLAN_ITEM *e = &t->Items[i]; @@ -9374,6 +10508,7 @@ void OutRpcEnumEthVLan(PACK *p, RPC_ENUM_ETH_VLAN *t) PackAddBoolEx(p, "Support", e->Support, i, t->NumItem); PackAddBoolEx(p, "Enabled", e->Enabled, i, t->NumItem); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcEnumEthVLan(RPC_ENUM_ETH_VLAN *t) { @@ -9421,6 +10556,7 @@ void OutRpcEnumLogFile(PACK *p, RPC_ENUM_LOG_FILE *t) PackAddInt(p, "NumItem", t->NumItem); + PackSetCurrentJsonGroupName(p, "LogFiles"); for (i = 0;i < t->NumItem;i++) { RPC_ENUM_LOG_FILE_ITEM *e = &t->Items[i]; @@ -9428,8 +10564,9 @@ void OutRpcEnumLogFile(PACK *p, RPC_ENUM_LOG_FILE *t) PackAddStrEx(p, "FilePath", e->FilePath, i, t->NumItem); PackAddStrEx(p, "ServerName", e->ServerName, i, t->NumItem); PackAddIntEx(p, "FileSize", e->FileSize, i, t->NumItem); - PackAddInt64Ex(p, "UpdatedTime", e->UpdatedTime, i, t->NumItem); + PackAddTime64Ex(p, "UpdatedTime", e->UpdatedTime, i, t->NumItem); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcEnumLogFile(RPC_ENUM_LOG_FILE *t) { @@ -9564,12 +10701,13 @@ void InRpcAcList(RPC_AC_LIST *t, PACK *p) o = NewAcList(); PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName)); - num = PackGetInt(p, "NumItem"); + num = PackGetIndexCount(p, "IpAddress"); for (i = 0;i < num;i++) { AC *ac = ZeroMalloc(sizeof(AC)); + ac->Id = PackGetIntEx(p, "Id", i); ac->Deny = PackGetBoolEx(p, "Deny", i); PackGetIpEx(p, "IpAddress", &ac->IpAddress, i); ac->Masked = PackGetBoolEx(p, "Masked", i); @@ -9605,10 +10743,12 @@ void OutRpcAcList(PACK *p, RPC_AC_LIST *t) PackAddStr(p, "HubName", t->HubName); + PackSetCurrentJsonGroupName(p, "ACList"); for (i = 0;i < num;i++) { AC *ac = LIST_DATA(o, i); + PackAddIntEx(p, "Id", ac->Id, i, num); PackAddBoolEx(p, "Deny", ac->Deny, i, num); PackAddIpEx(p, "IpAddress", &ac->IpAddress, i, num); PackAddBoolEx(p, "Masked", ac->Masked, i, num); @@ -9617,6 +10757,7 @@ void OutRpcAcList(PACK *p, RPC_AC_LIST *t) PackAddIntEx(p, "Priority", ac->Priority, i, num); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcAcList(RPC_AC_LIST *t) { @@ -9687,6 +10828,7 @@ void OutRpcEnumCrl(PACK *p, RPC_ENUM_CRL *t) PackAddStr(p, "HubName", t->HubName); PackAddInt(p, "NumItem", t->NumItem); + PackSetCurrentJsonGroupName(p, "CRLList"); for (i = 0;i < t->NumItem;i++) { RPC_ENUM_CRL_ITEM *e = &t->Items[i]; @@ -9694,6 +10836,7 @@ void OutRpcEnumCrl(PACK *p, RPC_ENUM_CRL *t) PackAddIntEx(p, "Key", e->Key, i, t->NumItem); PackAddUniStrEx(p, "CrlInfo", e->CrlInfo, i, t->NumItem); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcEnumCrl(RPC_ENUM_CRL *t) { @@ -9866,6 +11009,7 @@ void OutRpcEnumL3Table(PACK *p, RPC_ENUM_L3TABLE *t) PackAddInt(p, "NumItem", t->NumItem); PackAddStr(p, "Name", t->Name); + PackSetCurrentJsonGroupName(p, "L3Table"); for (i = 0;i < t->NumItem;i++) { RPC_L3TABLE *e = &t->Items[i]; @@ -9875,6 +11019,7 @@ void OutRpcEnumL3Table(PACK *p, RPC_ENUM_L3TABLE *t) PackAddIp32Ex(p, "GatewayAddress", e->GatewayAddress, i, t->NumItem); PackAddIntEx(p, "Metric", e->Metric, i, t->NumItem); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcEnumL3Table(RPC_ENUM_L3TABLE *t) { @@ -9948,6 +11093,7 @@ void OutRpcEnumL3If(PACK *p, RPC_ENUM_L3IF *t) PackAddInt(p, "NumItem", t->NumItem); PackAddStr(p, "Name", t->Name); + PackSetCurrentJsonGroupName(p, "L3IFList"); for (i = 0;i < t->NumItem;i++) { RPC_L3IF *f = &t->Items[i]; @@ -9956,6 +11102,7 @@ void OutRpcEnumL3If(PACK *p, RPC_ENUM_L3IF *t) PackAddIp32Ex(p, "IpAddress", f->IpAddress, i, t->NumItem); PackAddIp32Ex(p, "SubnetMask", f->SubnetMask, i, t->NumItem); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcEnumL3If(RPC_ENUM_L3IF *t) { @@ -10056,6 +11203,7 @@ void OutRpcEnumL3Sw(PACK *p, RPC_ENUM_L3SW *t) PackAddInt(p, "NumItem", t->NumItem); + PackSetCurrentJsonGroupName(p, "L3SWList"); for (i = 0;i < t->NumItem;i++) { RPC_ENUM_L3SW_ITEM *s = &t->Items[i]; @@ -10066,6 +11214,7 @@ void OutRpcEnumL3Sw(PACK *p, RPC_ENUM_L3SW *t) PackAddBoolEx(p, "Active", s->Active, i, t->NumItem); PackAddBoolEx(p, "Online", s->Online, i, t->NumItem); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcEnumL3Sw(RPC_ENUM_L3SW *t) { @@ -10110,12 +11259,14 @@ void OutRpcEnumEth(PACK *p, RPC_ENUM_ETH *t) PackAddInt(p, "NumItem", t->NumItem); + PackSetCurrentJsonGroupName(p, "EthList"); for (i = 0;i < t->NumItem;i++) { RPC_ENUM_ETH_ITEM *e = &t->Items[i]; PackAddStrEx(p, "DeviceName", e->DeviceName, i, t->NumItem); PackAddUniStrEx(p, "NetworkConnectionName", e->NetworkConnectionName, i, t->NumItem); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcEnumEth(RPC_ENUM_ETH *t) { @@ -10191,6 +11342,7 @@ void OutRpcEnumLocalBridge(PACK *p, RPC_ENUM_LOCALBRIDGE *t) PackAddInt(p, "NumItem", t->NumItem); + PackSetCurrentJsonGroupName(p, "LocalBridgeList"); for (i = 0;i < t->NumItem;i++) { RPC_LOCALBRIDGE *e = &t->Items[i]; @@ -10201,6 +11353,7 @@ void OutRpcEnumLocalBridge(PACK *p, RPC_ENUM_LOCALBRIDGE *t) PackAddBoolEx(p, "Active", e->Active, i, t->NumItem); PackAddBoolEx(p, "TapMode", e->TapMode, i, t->NumItem); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcEnumLocalBridge(RPC_ENUM_LOCALBRIDGE *t) { @@ -10430,8 +11583,11 @@ void SiEnumLocalSession(SERVER *s, char *hubname, RPC_ENUM_SESSION *t) StrCpy(e->Name, sizeof(e->Name), s->Name); StrCpy(e->Username, sizeof(e->Username), s->Username); e->Ip = IPToUINT(&s->Connection->ClientIp); + CopyIP(&e->ClientIP, &s->Connection->ClientIp); StrCpy(e->Hostname, sizeof(e->Hostname), s->Connection->ClientHostname); e->MaxNumTcp = s->MaxConnection; + e->CreatedTime = Tick64ToTime64(s->CreatedTime); + e->LastCommTime = Tick64ToTime64(s->LastCommTime); e->LinkMode = s->LinkModeServer; e->SecureNATMode = s->SecureNATMode; e->BridgeMode = s->BridgeMode; @@ -10527,6 +11683,8 @@ void OutRpcEnumLicenseKey(PACK *p, RPC_ENUM_LICENSE_KEY *t) } PackAddInt(p, "NumItem", t->NumItem); + + PackSetCurrentJsonGroupName(p, "LicenseKeyList"); for (i = 0;i < t->NumItem;i++) { RPC_ENUM_LICENSE_KEY_ITEM *e = &t->Items[i]; @@ -10535,12 +11693,13 @@ void OutRpcEnumLicenseKey(PACK *p, RPC_ENUM_LICENSE_KEY *t) PackAddStrEx(p, "LicenseKey", e->LicenseKey, i, t->NumItem); PackAddStrEx(p, "LicenseId", e->LicenseId, i, t->NumItem); PackAddStrEx(p, "LicenseName", e->LicenseName, i, t->NumItem); - PackAddInt64Ex(p, "Expires", e->Expires, i, t->NumItem); + PackAddTime64Ex(p, "Expires", e->Expires, i, t->NumItem); PackAddIntEx(p, "Status", e->Status, i, t->NumItem); PackAddIntEx(p, "ProductId", e->ProductId, i, t->NumItem); PackAddInt64Ex(p, "SystemId", e->SystemId, i, t->NumItem); PackAddIntEx(p, "SerialId", e->SerialId, i, t->NumItem); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcEnumLicenseKey(RPC_ENUM_LICENSE_KEY *t) { @@ -10590,17 +11749,17 @@ void OutRpcLicenseStatus(PACK *p, RPC_LICENSE_STATUS *t) PackAddInt(p, "EditionId", t->EditionId); PackAddStr(p, "EditionStr", t->EditionStr); PackAddInt64(p, "SystemId", t->SystemId); - PackAddInt64(p, "SystemExpires", t->SystemExpires); + PackAddTime64(p, "SystemExpires", t->SystemExpires); PackAddInt(p, "NumClientConnectLicense", t->NumClientConnectLicense); PackAddInt(p, "NumBridgeConnectLicense", t->NumBridgeConnectLicense); // v3.0 PackAddBool(p, "NeedSubscription", t->NeedSubscription); PackAddBool(p, "AllowEnterpriseFunction", t->AllowEnterpriseFunction); - PackAddInt64(p, "SubscriptionExpires", t->SubscriptionExpires); + PackAddTime64(p, "SubscriptionExpires", t->SubscriptionExpires); PackAddBool(p, "IsSubscriptionExpired", t->IsSubscriptionExpired); PackAddInt(p, "NumUserCreationLicense", t->NumUserCreationLicense); - PackAddInt64(p, "ReleaseDate", t->ReleaseDate); + PackAddTime64(p, "ReleaseDate", t->ReleaseDate); } // RPC_ADMIN_OPTION @@ -10614,7 +11773,7 @@ void InRpcAdminOption(RPC_ADMIN_OPTION *t, PACK *p) } Zero(t, sizeof(RPC_ADMIN_OPTION)); - t->NumItem = PackGetInt(p, "NumItem"); + t->NumItem = PackGetIndexCount(p, "Name"); t->Items = ZeroMalloc(sizeof(ADMIN_OPTION) * t->NumItem); PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName)); @@ -10625,6 +11784,7 @@ void InRpcAdminOption(RPC_ADMIN_OPTION *t, PACK *p) PackGetStrEx(p, "Name", o->Name, sizeof(o->Name), i); o->Value = PackGetIntEx(p, "Value", i); + PackGetUniStrEx(p, "Descrption", o->Descrption, sizeof(o->Descrption), i); } } void OutRpcAdminOption(PACK *p, RPC_ADMIN_OPTION *t) @@ -10640,13 +11800,16 @@ void OutRpcAdminOption(PACK *p, RPC_ADMIN_OPTION *t) PackAddStr(p, "HubName", t->HubName); + PackSetCurrentJsonGroupName(p, "AdminOptionList"); for (i = 0;i < t->NumItem;i++) { ADMIN_OPTION *o = &t->Items[i]; PackAddStrEx(p, "Name", o->Name, i, t->NumItem); PackAddIntEx(p, "Value", o->Value, i, t->NumItem); + PackAddUniStrEx(p, "Descrption", o->Descrption, i, t->NumItem); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcAdminOption(RPC_ADMIN_OPTION *t) { @@ -10813,7 +11976,7 @@ void OutRpcServerInfo(PACK *p, RPC_SERVER_INFO *t) PackAddInt(p, "ServerBuildInt", t->ServerBuildInt); PackAddStr(p, "ServerHostName", t->ServerHostName); PackAddInt(p, "ServerType", t->ServerType); - PackAddInt64(p, "ServerBuildDate", t->ServerBuildDate); + PackAddTime64(p, "ServerBuildDate", t->ServerBuildDate); PackAddStr(p, "ServerFamilyName", t->ServerFamilyName); OutRpcOsInfo(p, &t->OsInfo); } @@ -10888,13 +12051,13 @@ void OutRpcServerStatus(PACK *p, RPC_SERVER_STATUS *t) PackAddInt(p, "NumIpTables", t->NumIpTables); PackAddInt(p, "NumUsers", t->NumUsers); PackAddInt(p, "NumGroups", t->NumGroups); - PackAddInt64(p, "CurrentTime", t->CurrentTime); + PackAddTime64(p, "CurrentTime", t->CurrentTime); PackAddInt64(p, "CurrentTick", t->CurrentTick); PackAddInt(p, "AssignedBridgeLicenses", t->AssignedBridgeLicenses); PackAddInt(p, "AssignedClientLicenses", t->AssignedClientLicenses); PackAddInt(p, "AssignedBridgeLicensesTotal", t->AssignedBridgeLicensesTotal); PackAddInt(p, "AssignedClientLicensesTotal", t->AssignedClientLicensesTotal); - PackAddInt64(p, "StartTime", t->StartTime); + PackAddTime64(p, "StartTime", t->StartTime); OutRpcTraffic(p, &t->Traffic); @@ -10957,12 +12120,14 @@ void OutRpcListenerList(PACK *p, RPC_LISTENER_LIST *t) return; } + PackSetCurrentJsonGroupName(p, "ListenerList"); for (i = 0;i < t->NumPort;i++) { PackAddIntEx(p, "Ports", t->Ports[i], i, t->NumPort); PackAddBoolEx(p, "Enables", t->Enables[i], i, t->NumPort); PackAddBoolEx(p, "Errors", t->Errors[i], i, t->NumPort); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcListenerList(RPC_LISTENER_LIST *t) { @@ -11031,6 +12196,7 @@ void InRpcSetPassword(RPC_SET_PASSWORD *t, PACK *p) Zero(t, sizeof(RPC_SET_PASSWORD)); PackGetData2(p, "HashedPassword", t->HashedPassword, sizeof(t->HashedPassword)); + PackGetStr(p, "PlainTextPassword", t->PlainTextPassword, sizeof(t->PlainTextPassword)); } void OutRpcSetPassword(PACK *p, RPC_SET_PASSWORD *t) { @@ -11041,6 +12207,7 @@ void OutRpcSetPassword(PACK *p, RPC_SET_PASSWORD *t) } PackAddData(p, "HashedPassword", t->HashedPassword, sizeof(t->HashedPassword)); + PackAddStr(p, "PlainTextPassword", t->PlainTextPassword); } // RPC_FARM @@ -11065,6 +12232,7 @@ void InRpcFarm(RPC_FARM *t, PACK *p) PackGetStr(p, "ControllerName", t->ControllerName, sizeof(t->ControllerName)); t->ControllerPort = PackGetInt(p, "ControllerPort"); PackGetData2(p, "MemberPassword", t->MemberPassword, sizeof(t->MemberPassword)); + PackGetStr(p, "MemberPasswordPlaintext", t->MemberPasswordPlaintext, sizeof(t->MemberPasswordPlaintext)); t->Weight = PackGetInt(p, "Weight"); t->ControllerOnly = PackGetBool(p, "ControllerOnly"); } @@ -11086,6 +12254,7 @@ void OutRpcFarm(PACK *p, RPC_FARM *t) PackAddStr(p, "ControllerName", t->ControllerName); PackAddInt(p, "ControllerPort", t->ControllerPort); PackAddData(p, "MemberPassword", t->MemberPassword, sizeof(t->MemberPassword)); + PackAddStr(p, "MemberPasswordPlaintext", t->MemberPasswordPlaintext); PackAddInt(p, "Weight", t->Weight); PackAddBool(p, "ControllerOnly", t->ControllerOnly); } @@ -11171,7 +12340,7 @@ void OutRpcFarmInfo(PACK *p, RPC_FARM_INFO *t) PackAddInt(p, "Id", t->Id); PackAddBool(p, "Controller", t->Controller); - PackAddInt64(p, "ConnectedTime", t->ConnectedTime); + PackAddTime64(p, "ConnectedTime", t->ConnectedTime); PackAddIp32(p, "Ip", t->Ip); PackAddStr(p, "Hostname", t->Hostname); PackAddInt(p, "Point", t->Point); @@ -11180,11 +12349,15 @@ void OutRpcFarmInfo(PACK *p, RPC_FARM_INFO *t) PackAddIntEx(p, "Ports", t->Ports[i], i, t->NumPort); } PackAddX(p, "ServerCert", t->ServerCert); + + PackSetCurrentJsonGroupName(p, "HubsList"); for (i = 0;i < t->NumFarmHub;i++) { PackAddStrEx(p, "HubName", t->FarmHubs[i].HubName, i, t->NumFarmHub); PackAddBoolEx(p, "DynamicHub", t->FarmHubs[i].DynamicHub, i, t->NumFarmHub); } + PackSetCurrentJsonGroupName(p, NULL); + PackAddInt(p, "NumSessions", t->NumSessions); PackAddInt(p, "NumTcpConnections", t->NumTcpConnections); PackAddInt(p, "Weight", t->Weight); @@ -11241,13 +12414,14 @@ void OutRpcEnumFarm(PACK *p, RPC_ENUM_FARM *t) return; } + PackSetCurrentJsonGroupName(p, "FarmMemberList"); for (i = 0;i < t->NumFarm;i++) { RPC_ENUM_FARM_ITEM *e = &t->Farms[i]; PackAddIntEx(p, "Id", e->Id, i, t->NumFarm); PackAddBoolEx(p, "Controller", e->Controller, i, t->NumFarm); - PackAddInt64Ex(p, "ConnectedTime", e->ConnectedTime, i, t->NumFarm); + PackAddTime64Ex(p, "ConnectedTime", e->ConnectedTime, i, t->NumFarm); PackAddIp32Ex(p, "Ip", e->Ip, i, t->NumFarm); PackAddStrEx(p, "Hostname", e->Hostname, i, t->NumFarm); PackAddIntEx(p, "Point", e->Point, i, t->NumFarm); @@ -11257,6 +12431,7 @@ void OutRpcEnumFarm(PACK *p, RPC_ENUM_FARM *t) PackAddIntEx(p, "AssignedClientLicense", e->AssignedClientLicense, i, t->NumFarm); PackAddIntEx(p, "AssignedBridgeLicense", e->AssignedBridgeLicense, i, t->NumFarm); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcEnumFarm(RPC_ENUM_FARM *t) { @@ -11302,9 +12477,9 @@ void OutRpcFarmConnectionStatus(PACK *p, RPC_FARM_CONNECTION_STATUS *t) PackAddInt(p, "Port", t->Port); PackAddBool(p, "Online", t->Online); PackAddInt(p, "LastError", t->LastError); - PackAddInt64(p, "StartedTime", t->StartedTime); - PackAddInt64(p, "CurrentConnectedTime", t->CurrentConnectedTime); - PackAddInt64(p, "FirstConnectedTime", t->FirstConnectedTime); + PackAddTime64(p, "StartedTime", t->StartedTime); + PackAddTime64(p, "CurrentConnectedTime", t->CurrentConnectedTime); + PackAddTime64(p, "FirstConnectedTime", t->FirstConnectedTime); PackAddInt(p, "NumConnected", t->NumConnected); PackAddInt(p, "NumTry", t->NumTry); PackAddInt(p, "NumFailed", t->NumFailed); @@ -11402,6 +12577,7 @@ void InRpcCreateHub(RPC_CREATE_HUB *t, PACK *p) PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName)); PackGetData2(p, "HashedPassword", t->HashedPassword, sizeof(t->HashedPassword)); PackGetData2(p, "SecurePassword", t->SecurePassword, sizeof(t->SecurePassword)); + PackGetStr(p, "AdminPasswordPlainText", t->AdminPasswordPlainText, sizeof(t->AdminPasswordPlainText)); t->Online = PackGetBool(p, "Online"); InRpcHubOption(&t->HubOption, p); t->HubType = PackGetInt(p, "HubType"); @@ -11418,6 +12594,7 @@ void OutRpcCreateHub(PACK *p, RPC_CREATE_HUB *t) PackAddData(p, "HashedPassword", t->HashedPassword, sizeof(t->HashedPassword)); PackAddData(p, "SecurePassword", t->SecurePassword, sizeof(t->SecurePassword)); PackAddBool(p, "Online", t->Online); + PackAddStr(p, "AdminPasswordPlainText", t->AdminPasswordPlainText); OutRpcHubOption(p, &t->HubOption); PackAddInt(p, "HubType", t->HubType); } @@ -11466,6 +12643,7 @@ void OutRpcEnumHub(PACK *p, RPC_ENUM_HUB *t) return; } + PackSetCurrentJsonGroupName(p, "HubList"); for (i = 0;i < t->NumHub;i++) { RPC_ENUM_HUB_ITEM *e = &t->Hubs[i]; @@ -11478,14 +12656,15 @@ void OutRpcEnumHub(PACK *p, RPC_ENUM_HUB *t) PackAddIntEx(p, "NumGroups", e->NumGroups, i, t->NumHub); PackAddIntEx(p, "NumMacTables", e->NumMacTables, i, t->NumHub); PackAddIntEx(p, "NumIpTables", e->NumIpTables, i, t->NumHub); - PackAddInt64Ex(p, "LastCommTime", e->LastCommTime, i, t->NumHub); - PackAddInt64Ex(p, "CreatedTime", e->CreatedTime, i, t->NumHub); - PackAddInt64Ex(p, "LastLoginTime", e->LastLoginTime, i, t->NumHub); + PackAddTime64Ex(p, "LastCommTime", e->LastCommTime, i, t->NumHub); + PackAddTime64Ex(p, "CreatedTime", e->CreatedTime, i, t->NumHub); + PackAddTime64Ex(p, "LastLoginTime", e->LastLoginTime, i, t->NumHub); PackAddIntEx(p, "NumLogin", e->NumLogin, i, t->NumHub); PackAddBoolEx(p, "IsTrafficFilled", e->IsTrafficFilled, i, t->NumHub); OutRpcTrafficEx(&e->Traffic, p, i, t->NumHub); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcEnumHub(RPC_ENUM_HUB *t) { @@ -11556,6 +12735,7 @@ void OutRpcEnumConnection(PACK *p, RPC_ENUM_CONNECTION *t) return; } + PackSetCurrentJsonGroupName(p, "ConnectionList"); for (i = 0;i < t->NumConnection;i++) { RPC_ENUM_CONNECTION_ITEM *e = &t->Connections[i]; @@ -11564,9 +12744,10 @@ void OutRpcEnumConnection(PACK *p, RPC_ENUM_CONNECTION *t) PackAddIntEx(p, "Port", e->Port, i, t->NumConnection); PackAddStrEx(p, "Name", e->Name, i, t->NumConnection); PackAddStrEx(p, "Hostname", e->Hostname, i, t->NumConnection); - PackAddInt64Ex(p, "ConnectedTime", e->ConnectedTime, i, t->NumConnection); + PackAddTime64Ex(p, "ConnectedTime", e->ConnectedTime, i, t->NumConnection); PackAddIntEx(p, "Type", e->Type, i, t->NumConnection); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcEnumConnetion(RPC_ENUM_CONNECTION *t) { @@ -11636,7 +12817,7 @@ void OutRpcConnectionInfo(PACK *p, RPC_CONNECTION_INFO *t) PackAddStr(p, "Name", t->Name); PackAddIp32(p, "Ip", t->Ip); PackAddInt(p, "Port", t->Port); - PackAddInt64(p, "ConnectedTime", t->ConnectedTime); + PackAddTime64(p, "ConnectedTime", t->ConnectedTime); PackAddStr(p, "Hostname", t->Hostname); PackAddStr(p, "ServerStr", t->ServerStr); PackAddStr(p, "ClientStr", t->ClientStr); @@ -11721,9 +12902,9 @@ void OutRpcHubStatus(PACK *p, RPC_HUB_STATUS *t) PackAddInt(p, "NumIpTables", t->NumIpTables); PackAddBool(p, "SecureNATEnabled", t->SecureNATEnabled); OutRpcTraffic(p, &t->Traffic); - PackAddInt64(p, "LastCommTime", t->LastCommTime); - PackAddInt64(p, "CreatedTime", t->CreatedTime); - PackAddInt64(p, "LastLoginTime", t->LastLoginTime); + PackAddTime64(p, "LastCommTime", t->LastCommTime); + PackAddTime64(p, "CreatedTime", t->CreatedTime); + PackAddTime64(p, "LastLoginTime", t->LastLoginTime); PackAddInt(p, "NumLogin", t->NumLogin); } @@ -11838,6 +13019,7 @@ void OutRpcHubEnumCa(PACK *p, RPC_HUB_ENUM_CA *t) } PackAddStr(p, "HubName", t->HubName); + PackSetCurrentJsonGroupName(p, "CAList"); for (i = 0;i < t->NumCa;i++) { RPC_HUB_ENUM_CA_ITEM *e = &t->Ca[i]; @@ -11845,8 +13027,9 @@ void OutRpcHubEnumCa(PACK *p, RPC_HUB_ENUM_CA *t) PackAddIntEx(p, "Key", e->Key, i, t->NumCa); PackAddUniStrEx(p, "SubjectName", e->SubjectName, i, t->NumCa); PackAddUniStrEx(p, "IssuerName", e->IssuerName, i, t->NumCa); - PackAddInt64Ex(p, "Expires", e->Expires, i, t->NumCa); + PackAddTime64Ex(p, "Expires", e->Expires, i, t->NumCa); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcHubEnumCa(RPC_HUB_ENUM_CA *t) { @@ -12013,6 +13196,7 @@ void InRpcEnumLink(RPC_ENUM_LINK *t, PACK *p) e->ConnectedTime = PackGetInt64Ex(p, "ConnectedTime", i); e->Connected = PackGetBoolEx(p, "Connected", i); e->LastError = PackGetIntEx(p, "LastError", i); + PackGetStrEx(p, "LinkHubName", e->HubName, sizeof(e->HubName), i); } } void OutRpcEnumLink(PACK *p, RPC_ENUM_LINK *t) @@ -12026,6 +13210,7 @@ void OutRpcEnumLink(PACK *p, RPC_ENUM_LINK *t) PackAddStr(p, "HubName", t->HubName); + PackSetCurrentJsonGroupName(p, "LinkList"); for (i = 0;i < t->NumLink;i++) { RPC_ENUM_LINK_ITEM *e = &t->Links[i]; @@ -12034,10 +13219,12 @@ void OutRpcEnumLink(PACK *p, RPC_ENUM_LINK *t) PackAddStrEx(p, "ConnectedHubName", e->HubName, i, t->NumLink); PackAddStrEx(p, "Hostname", e->Hostname, i, t->NumLink); PackAddBoolEx(p, "Online", e->Online, i, t->NumLink); - PackAddInt64Ex(p, "ConnectedTime", e->ConnectedTime, i, t->NumLink); + PackAddTime64Ex(p, "ConnectedTime", e->ConnectedTime, i, t->NumLink); PackAddBoolEx(p, "Connected", e->Connected, i, t->NumLink); PackAddIntEx(p, "LastError", e->LastError, i, t->NumLink); + PackAddStrEx(p, "TargetHubName", e->HubName, i, t->NumLink); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcEnumLink(RPC_ENUM_LINK *t) { @@ -12311,12 +13498,14 @@ void OutRpcEnumAccessList(PACK *p, RPC_ENUM_ACCESS_LIST *a) } PackAddStr(p, "HubName", a->HubName); + PackSetCurrentJsonGroupName(p, "AccessList"); for (i = 0;i < a->NumAccess;i++) { ACCESS *e = &a->Accesses[i]; OutRpcAccessEx(p, e, i, a->NumAccess); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcEnumAccessList(RPC_ENUM_ACCESS_LIST *a) { @@ -12330,7 +13519,7 @@ void FreeRpcEnumAccessList(RPC_ENUM_ACCESS_LIST *a) } // AUTHDATA -void *InRpcAuthData(PACK *p, UINT *authtype) +void *InRpcAuthData(PACK *p, UINT *authtype, char *username) { wchar_t tmp[MAX_SIZE]; AUTHPASSWORD *pw; @@ -12339,6 +13528,7 @@ void *InRpcAuthData(PACK *p, UINT *authtype) AUTHRADIUS *radius; AUTHNT *nt; BUF *b; + char plain_pw[MAX_SIZE]; // Validate arguments if (p == NULL) { @@ -12357,6 +13547,16 @@ void *InRpcAuthData(PACK *p, UINT *authtype) pw = ZeroMalloc(sizeof(AUTHPASSWORD)); PackGetData2(p, "HashedKey", pw->HashedKey, sizeof(pw->HashedKey)); PackGetData2(p, "NtLmSecureHash", pw->NtLmSecureHash, sizeof(pw->NtLmSecureHash)); + + if (PackGetStr(p, "Auth_Password", plain_pw, sizeof(plain_pw))) + { + if (IsZero(pw->HashedKey, sizeof(pw->HashedKey))) + { + HashPassword(pw->HashedKey, username, plain_pw); + GenerateNtPasswordHash(pw->NtLmSecureHash, plain_pw); + } + } + return pw; case AUTHTYPE_USERCERT: @@ -12474,7 +13674,7 @@ void InRpcSetUser(RPC_SET_USER *t, PACK *p) t->CreatedTime = PackGetInt64(p, "CreatedTime"); t->UpdatedTime = PackGetInt64(p, "UpdatedTime"); t->ExpireTime = PackGetInt64(p, "ExpireTime"); - t->AuthData = InRpcAuthData(p, &t->AuthType); + t->AuthData = InRpcAuthData(p, &t->AuthType, t->Name); t->NumLogin = PackGetInt(p, "NumLogin"); InRpcTraffic(&t->Traffic, p); @@ -12498,9 +13698,9 @@ void OutRpcSetUser(PACK *p, RPC_SET_USER *t) PackAddStr(p, "GroupName", t->GroupName); PackAddUniStr(p, "Realname", t->Realname); PackAddUniStr(p, "Note", t->Note); - PackAddInt64(p, "CreatedTime", t->CreatedTime); - PackAddInt64(p, "UpdatedTime", t->UpdatedTime); - PackAddInt64(p, "ExpireTime", t->ExpireTime); + PackAddTime64(p, "CreatedTime", t->CreatedTime); + PackAddTime64(p, "UpdatedTime", t->UpdatedTime); + PackAddTime64(p, "ExpireTime", t->ExpireTime); OutRpcAuthData(p, t->AuthData, t->AuthType); PackAddInt(p, "NumLogin", t->NumLogin); OutRpcTraffic(p, &t->Traffic); @@ -12571,6 +13771,7 @@ void OutRpcEnumUser(PACK *p, RPC_ENUM_USER *t) } PackAddStr(p, "HubName", t->HubName); + PackSetCurrentJsonGroupName(p, "UserList"); for (i = 0;i < t->NumUser;i++) { RPC_ENUM_USER_ITEM *e = &t->Users[i]; @@ -12580,7 +13781,7 @@ void OutRpcEnumUser(PACK *p, RPC_ENUM_USER *t) PackAddUniStrEx(p, "Realname", e->Realname, i, t->NumUser); PackAddUniStrEx(p, "Note", e->Note, i, t->NumUser); PackAddIntEx(p, "AuthType", e->AuthType, i, t->NumUser); - PackAddInt64Ex(p, "LastLoginTime", e->LastLoginTime, i, t->NumUser); + PackAddTime64Ex(p, "LastLoginTime", e->LastLoginTime, i, t->NumUser); PackAddIntEx(p, "NumLogin", e->NumLogin, i, t->NumUser); PackAddBoolEx(p, "DenyAccess", e->DenyAccess, i, t->NumUser); @@ -12588,8 +13789,9 @@ void OutRpcEnumUser(PACK *p, RPC_ENUM_USER *t) OutRpcTrafficEx(&e->Traffic, p, i, t->NumUser); PackAddBoolEx(p, "IsExpiresFilled", e->IsExpiresFilled, i, t->NumUser); - PackAddInt64Ex(p, "Expires", e->Expires, i, t->NumUser); + PackAddTime64Ex(p, "Expires", e->Expires, i, t->NumUser); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcEnumUser(RPC_ENUM_USER *t) { @@ -12686,6 +13888,7 @@ void OutRpcEnumGroup(PACK *p, RPC_ENUM_GROUP *t) PackAddStr(p, "HubName", t->HubName); + PackSetCurrentJsonGroupName(p, "GroupList"); for (i = 0;i < t->NumGroup;i++) { RPC_ENUM_GROUP_ITEM *e = &t->Groups[i]; @@ -12696,6 +13899,7 @@ void OutRpcEnumGroup(PACK *p, RPC_ENUM_GROUP *t) PackAddIntEx(p, "NumUsers", e->NumUsers, i, t->NumGroup); PackAddBoolEx(p, "DenyAccess", e->DenyAccess, i, t->NumGroup); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcEnumGroup(RPC_ENUM_GROUP *t) { @@ -12755,6 +13959,7 @@ void InRpcEnumSession(RPC_ENUM_SESSION *t, PACK *p) PackGetStrEx(p, "Name", e->Name, sizeof(e->Name), i); PackGetStrEx(p, "Username", e->Username, sizeof(e->Username), i); e->Ip = PackGetIntEx(p, "Ip", i); + PackGetIpEx(p, "ClientIP", &e->ClientIP, i); PackGetStrEx(p, "Hostname", e->Hostname, sizeof(e->Hostname), i); e->MaxNumTcp = PackGetIntEx(p, "MaxNumTcp", i); e->CurrentNumTcp = PackGetIntEx(p, "CurrentNumTcp", i); @@ -12773,6 +13978,8 @@ void InRpcEnumSession(RPC_ENUM_SESSION *t, PACK *p) e->IsDormantEnabled = PackGetBoolEx(p, "IsDormantEnabled", i); e->IsDormant = PackGetBoolEx(p, "IsDormant", i); e->LastCommDormant = PackGetInt64Ex(p, "LastCommDormant", i); + e->CreatedTime = PackGetInt64Ex(p, "CreatedTime", i); + e->LastCommTime = PackGetInt64Ex(p, "LastCommTime", i); } } void OutRpcEnumSession(PACK *p, RPC_ENUM_SESSION *t) @@ -12785,6 +13992,7 @@ void OutRpcEnumSession(PACK *p, RPC_ENUM_SESSION *t) } PackAddStr(p, "HubName", t->HubName); + PackSetCurrentJsonGroupName(p, "SessionList"); for (i = 0;i < t->NumSession;i++) { RPC_ENUM_SESSION_ITEM *e = &t->Sessions[i]; @@ -12792,6 +14000,7 @@ void OutRpcEnumSession(PACK *p, RPC_ENUM_SESSION *t) PackAddStrEx(p, "Name", e->Name, i, t->NumSession); PackAddStrEx(p, "Username", e->Username, i, t->NumSession); PackAddIp32Ex(p, "Ip", e->Ip, i, t->NumSession); + PackAddIpEx(p, "ClientIP", &e->ClientIP, i, t->NumSession); PackAddStrEx(p, "Hostname", e->Hostname, i, t->NumSession); PackAddIntEx(p, "MaxNumTcp", e->MaxNumTcp, i, t->NumSession); PackAddIntEx(p, "CurrentNumTcp", e->CurrentNumTcp, i, t->NumSession); @@ -12809,8 +14018,11 @@ void OutRpcEnumSession(PACK *p, RPC_ENUM_SESSION *t) PackAddDataEx(p, "UniqueId", e->UniqueId, sizeof(e->UniqueId), i, t->NumSession); PackAddBoolEx(p, "IsDormantEnabled", e->IsDormantEnabled, i, t->NumSession); PackAddBoolEx(p, "IsDormant", e->IsDormant, i, t->NumSession); - PackAddInt64Ex(p, "LastCommDormant", e->LastCommDormant, i, t->NumSession); + PackAddTime64Ex(p, "LastCommDormant", e->LastCommDormant, i, t->NumSession); + PackAddTime64Ex(p, "CreatedTime", e->CreatedTime, i, t->NumSession); + PackAddTime64Ex(p, "LastCommTime", e->LastCommTime, i, t->NumSession); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcEnumSession(RPC_ENUM_SESSION *t) { @@ -12941,6 +14153,7 @@ void InRpcSessionStatus(RPC_SESSION_STATUS *t, PACK *p) t->ClientIp = PackGetIp32(p, "SessionStatus_ClientIp"); PackGetData2(p, "SessionStatus_ClientIp6", t->ClientIp6, sizeof(t->ClientIp6)); PackGetStr(p, "SessionStatus_ClientHostName", t->ClientHostName, sizeof(t->ClientHostName)); + PackGetIp(p, "Client_Ip_Address", &t->ClientIpAddress); InRpcClientGetConnectionStatus(&t->Status, p); InRpcNodeInfo(&t->NodeInfo, p); @@ -12961,6 +14174,7 @@ void OutRpcSessionStatus(PACK *p, RPC_SESSION_STATUS *t) PackAddIp32(p, "SessionStatus_ClientIp", t->ClientIp); PackAddData(p, "SessionStatus_ClientIp6", t->ClientIp6, sizeof(t->ClientIp6)); PackAddStr(p, "SessionStatus_ClientHostName", t->ClientHostName); + PackAddIp(p, "Client_Ip_Address", &t->ClientIpAddress); OutRpcClientGetConnectionStatus(p, &t->Status); OutRpcNodeInfo(p, &t->NodeInfo); @@ -13041,6 +14255,7 @@ void OutRpcEnumMacTable(PACK *p, RPC_ENUM_MAC_TABLE *t) PackAddStr(p, "HubName", t->HubName); + PackSetCurrentJsonGroupName(p, "MacTable"); for (i = 0;i < t->NumMacTable;i++) { RPC_ENUM_MAC_TABLE_ITEM *e = &t->MacTables[i]; @@ -13049,11 +14264,12 @@ void OutRpcEnumMacTable(PACK *p, RPC_ENUM_MAC_TABLE *t) PackAddStrEx(p, "SessionName", e->SessionName, i, t->NumMacTable); PackAddDataEx(p, "MacAddress", e->MacAddress, sizeof(e->MacAddress), i, t->NumMacTable); PackAddIntEx(p, "VlanId", e->VlanId, i, t->NumMacTable); - PackAddInt64Ex(p, "CreatedTime", e->CreatedTime, i, t->NumMacTable); - PackAddInt64Ex(p, "UpdatedTime", e->UpdatedTime, i, t->NumMacTable); + PackAddTime64Ex(p, "CreatedTime", e->CreatedTime, i, t->NumMacTable); + PackAddTime64Ex(p, "UpdatedTime", e->UpdatedTime, i, t->NumMacTable); PackAddBoolEx(p, "RemoteItem", e->RemoteItem, i, t->NumMacTable); PackAddStrEx(p, "RemoteHostname", e->RemoteHostname, i, t->NumMacTable); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcEnumMacTable(RPC_ENUM_MAC_TABLE *t) { @@ -13092,6 +14308,7 @@ void InRpcEnumIpTable(RPC_ENUM_IP_TABLE *t, PACK *p) { UINTToIP(&e->IpV6, e->Ip); } + PackGetIp(p, "IpAddress", &e->IpAddress); e->DhcpAllocated = PackGetBoolEx(p, "DhcpAllocated", i); e->CreatedTime = PackGetInt64Ex(p, "CreatedTime", i); e->UpdatedTime = PackGetInt64Ex(p, "UpdatedTime", i); @@ -13110,6 +14327,7 @@ void OutRpcEnumIpTable(PACK *p, RPC_ENUM_IP_TABLE *t) PackAddStr(p, "HubName", t->HubName); + PackSetCurrentJsonGroupName(p, "IpTable"); for (i = 0;i < t->NumIpTable;i++) { RPC_ENUM_IP_TABLE_ITEM *e = &t->IpTables[i]; @@ -13118,12 +14336,14 @@ void OutRpcEnumIpTable(PACK *p, RPC_ENUM_IP_TABLE *t) PackAddStrEx(p, "SessionName", e->SessionName, i, t->NumIpTable); PackAddIp32Ex(p, "Ip", e->Ip, i, t->NumIpTable); PackAddIpEx(p, "IpV6", &e->IpV6, i, t->NumIpTable); + PackAddIpEx(p, "IpAddress", &e->IpAddress, i, t->NumIpTable); PackAddBoolEx(p, "DhcpAllocated", e->DhcpAllocated, i, t->NumIpTable); - PackAddInt64Ex(p, "CreatedTime", e->CreatedTime, i, t->NumIpTable); - PackAddInt64Ex(p, "UpdatedTime", e->UpdatedTime, i, t->NumIpTable); + PackAddTime64Ex(p, "CreatedTime", e->CreatedTime, i, t->NumIpTable); + PackAddTime64Ex(p, "UpdatedTime", e->UpdatedTime, i, t->NumIpTable); PackAddBoolEx(p, "RemoteItem", e->RemoteItem, i, t->NumIpTable); PackAddStrEx(p, "RemoteHostname", e->RemoteHostname, i, t->NumIpTable); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcEnumIpTable(RPC_ENUM_IP_TABLE *t) { diff --git a/src/Cedar/Admin.h b/src/Cedar/Admin.h index ca260270..59a9f2cf 100644 --- a/src/Cedar/Admin.h +++ b/src/Cedar/Admin.h @@ -129,6 +129,8 @@ struct ADMIN LIST *LogFileList; // Accessible log file list UINT ClientBuild; // Build number of the client RPC_WINVER ClientWinVer; // Windows version of client + UINT MaxJsonRpcRecvSize; // Max JSON-RPC Receive Size + char dummy1[MAX_HUBNAME_LEN + 1]; // hubname buffer (dummy) }; // Test @@ -215,7 +217,8 @@ struct RPC_INT // Set Password struct RPC_SET_PASSWORD { - UCHAR HashedPassword[SHA1_SIZE]; // Hashed password + UCHAR HashedPassword[SHA1_SIZE]; // Hashed password (for traditional RPC) + char PlainTextPassword[MAX_SIZE]; // Plaintext password (for JSON-RPC) }; // Server farm configuration * @@ -228,6 +231,7 @@ struct RPC_FARM char ControllerName[MAX_HOST_NAME_LEN + 1]; // Controller name UINT ControllerPort; // Controller port UCHAR MemberPassword[SHA1_SIZE]; // Member password + char MemberPasswordPlaintext[MAX_SIZE]; // Member password (plaintext) UINT Weight; // Performance ratio bool ControllerOnly; // Only controller function }; @@ -333,6 +337,7 @@ struct RPC_CREATE_HUB char HubName[MAX_HUBNAME_LEN + 1]; // HUB Name UCHAR HashedPassword[SHA1_SIZE]; // Administrative password UCHAR SecurePassword[SHA1_SIZE]; // Administrator password + char AdminPasswordPlainText[MAX_SIZE]; // Password (plaintext) bool Online; // Online flag RPC_HUB_OPTION HubOption; // HUB options UINT HubType; // Type of HUB @@ -650,6 +655,7 @@ struct RPC_ENUM_SESSION_ITEM char RemoteHostname[MAX_HOST_NAME_LEN + 1]; // Remote server name char Username[MAX_USERNAME_LEN + 1]; // User name UINT Ip; // IP address (IPv4) + IP ClientIP; // IP address (IPv4 / IPv6) char Hostname[MAX_HOST_NAME_LEN + 1]; // Host name UINT MaxNumTcp; // Maximum number of TCP connections UINT CurrentNumTcp; // Number of currentl TCP connections @@ -666,6 +672,8 @@ struct RPC_ENUM_SESSION_ITEM bool IsDormantEnabled; // Is the dormant state enabled bool IsDormant; // Is in the dormant state UINT64 LastCommDormant; // Last comm interval in the dormant state + UINT64 CreatedTime; // Creation date and time + UINT64 LastCommTime; // Last communication date and time }; // Disconnect the session @@ -702,8 +710,9 @@ struct RPC_ENUM_IP_TABLE_ITEM { UINT Key; // Key char SessionName[MAX_SESSION_NAME_LEN + 1]; // Session name - UINT Ip; // IP address + UINT Ip; // IPv4 address IP IpV6; // IPv6 address + IP IpAddress; // IPv4 / IPv6 Address bool DhcpAllocated; // Assigned by the DHCP UINT64 CreatedTime; // Creation date and time UINT64 UpdatedTime; // Updating date @@ -990,6 +999,11 @@ struct RPC_AZURE_STATUS }; +// Constants +#define ADMIN_RPC_MAX_POST_SIZE_BY_SERVER_ADMIN MAX_PACK_SIZE +#define ADMIN_RPC_MAX_POST_SIZE_BY_HUB_ADMIN (8 * 1024 * 1024) + + // Function prototype UINT AdminAccept(CONNECTION *c, PACK *p); void HashAdminPassword(void *hash, char *password); @@ -1014,6 +1028,26 @@ BUF *DownloadFileFromServer(RPC *r, char *server_name, char *filepath, UINT tota bool CheckAdminSourceAddress(SOCK *sock, char *hubname); void SiEnumSessionMain(SERVER *s, RPC_ENUM_SESSION *t); bool SiIsEmptyPassword(void *hash_password); +void JsonRpcProcPost(CONNECTION *c, SOCK *s, HTTP_HEADER *h, UINT post_data_size); +void JsonRpcProcGet(CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_target); +void JsonRpcProcOptions(CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_target); +JSON_VALUE *JsonRpcProcRequestObject(ADMIN *admin, CONNECTION *c, SOCK *s, JSON_VALUE *json_req, char *method_name); +JSON_VALUE *JsonRpcNewError(int code, wchar_t *message); +JSON_VALUE *JsonRpcNewResponse(PACK *p); +bool HttpParseBasicAuthHeader(HTTP_HEADER *h, char *username, UINT username_size, char *password, UINT password_size); +ADMIN *JsonRpcAuthLogin(CEDAR *c, SOCK *sock, HTTP_HEADER *h); +JSON_VALUE *QueryStringToJsonListValue(char *qs); +JSON_VALUE *ConstructDummyJsonRpcRequest(char *method_name, JSON_VALUE *p); +void AdminWebProcPost(CONNECTION *c, SOCK *s, HTTP_HEADER *h, UINT post_data_size, char *url_target); +void AdminWebProcGet(CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_target); +bool AdminWebHandleFileRequest(ADMIN *a, CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_src, char *query_string, char *virtual_root_dir, char *physical_root_dir); +BUF *AdminWebProcessServerSideInclude(BUF *src_txt, char *filename, UINT depth); +bool AdminWebSendBody(SOCK *s, UINT status_code, char *status_string, UCHAR *data, UINT data_size, char *content_type, char *add_header_name, char *add_header_value, HTTP_HEADER *request_headers); +bool AdminWebSend404Error(SOCK *s, HTTP_HEADER *request_headers); +bool AdminWebSend302Redirect(SOCK *s, char *url, char *query_string, HTTP_HEADER *request_headers); +BUF *AdminWebTryFindAndReadFile(char *vroot, char *proot, char *url, char *ret_filename, UINT ret_filename_size, bool *is_index_html); +BUF *AdminWebTryOneFile(char *filename, char *ret_filename, UINT ret_filename_size); +bool AdminWebSendUnauthorized(SOCK *s, HTTP_HEADER *http_request_headers); UINT StTest(ADMIN *a, RPC_TEST *t); UINT StGetServerInfo(ADMIN *a, RPC_SERVER_INFO *t); @@ -1387,7 +1421,7 @@ void OutRpcAccess(PACK *p, ACCESS *a); void InRpcEnumAccessList(RPC_ENUM_ACCESS_LIST *a, PACK *p); void OutRpcEnumAccessList(PACK *p, RPC_ENUM_ACCESS_LIST *a); void FreeRpcEnumAccessList(RPC_ENUM_ACCESS_LIST *a); -void *InRpcAuthData(PACK *p, UINT *authtype); +void *InRpcAuthData(PACK *p, UINT *authtype, char *username); void OutRpcAuthData(PACK *p, void *authdata, UINT authtype); void FreeRpcAuthData(void *authdata, UINT authtype); void InRpcSetUser(RPC_SET_USER *t, PACK *p); diff --git a/src/Cedar/CM.c b/src/Cedar/CM.c index a42bb48f..97bd28e4 100644 --- a/src/Cedar/CM.c +++ b/src/Cedar/CM.c @@ -9466,6 +9466,12 @@ void CmPrintStatusToListViewEx(LVB *b, RPC_CLIENT_GET_CONNECTION_STATUS *s, bool LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_UNDERLAY_PROTOCOL"), tmp); } + if (IsEmptyStr(s->ProtocolDetails) == false) + { + StrToUni(tmp, sizeof(tmp), s->ProtocolDetails); + LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_PROTOCOL_DETAILS"), tmp); + } + LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_UDP_ACCEL_ENABLED"), (s->IsUdpAccelerationEnabled ? _UU("CM_ST_YES") : _UU("CM_ST_NO"))); LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_UDP_ACCEL_USING"), (s->IsUsingUdpAcceleration ? _UU("CM_ST_YES") : _UU("CM_ST_NO"))); diff --git a/src/Cedar/Cedar.h b/src/Cedar/Cedar.h index f99e9350..d746c4bb 100644 --- a/src/Cedar/Cedar.h +++ b/src/Cedar/Cedar.h @@ -126,10 +126,10 @@ // Version number -#define CEDAR_VER 429 +#define CEDAR_VER 430 // Build Number -#define CEDAR_BUILD 9680 +#define CEDAR_BUILD 9695 // Beta number //#define BETA_NUMBER 3 @@ -149,11 +149,11 @@ // Specifies the build date #define BUILD_DATE_Y 2019 -#define BUILD_DATE_M 2 -#define BUILD_DATE_D 28 -#define BUILD_DATE_HO 18 -#define BUILD_DATE_MI 39 -#define BUILD_DATE_SE 47 +#define BUILD_DATE_M 7 +#define BUILD_DATE_D 7 +#define BUILD_DATE_HO 19 +#define BUILD_DATE_MI 58 +#define BUILD_DATE_SE 8 // Tolerable time difference #define ALLOW_TIMESTAMP_DIFF (UINT64)(3 * 24 * 60 * 60 * 1000) @@ -438,6 +438,7 @@ #define AUTHTYPE_ROOTCERT 3 // Root certificate which is issued by trusted Certificate Authority #define AUTHTYPE_RADIUS 4 // Radius authentication #define AUTHTYPE_NT 5 // Windows NT authentication +#define AUTHTYPE_OPENVPN_CERT 98 // TLS client certificate authentication #define AUTHTYPE_TICKET 99 // Ticket authentication // Constant of the client side diff --git a/src/Cedar/CedarType.h b/src/Cedar/CedarType.h index 13ea74e5..040790f0 100644 --- a/src/Cedar/CedarType.h +++ b/src/Cedar/CedarType.h @@ -234,6 +234,9 @@ typedef struct BLACK BLACK; typedef struct SEND_SIGNATURE_PARAM SEND_SIGNATURE_PARAM; typedef struct UPDATE_CLIENT UPDATE_CLIENT; typedef struct UPDATE_CLIENT_SETTING UPDATE_CLIENT_SETTING; +typedef struct HTTP_MIME_TYPE HTTP_MIME_TYPE; +typedef struct WS WS; +typedef struct WSP WSP; // ============================================================== @@ -673,6 +676,7 @@ typedef struct IPC_ASYNC IPC_ASYNC; typedef struct IPC_PARAM IPC_PARAM; typedef struct IPC_DHCP_RELESAE_QUEUE IPC_DHCP_RELESAE_QUEUE; typedef struct IPC_MSCHAP_V2_AUTHINFO IPC_MSCHAP_V2_AUTHINFO; +typedef struct IPC_SESSION_SHARED_BUFFER_DATA IPC_SESSION_SHARED_BUFFER_DATA; // ============================================================== diff --git a/src/Cedar/Client.c b/src/Cedar/Client.c index 30bc6e4a..d3234ed4 100644 --- a/src/Cedar/Client.c +++ b/src/Cedar/Client.c @@ -4083,14 +4083,16 @@ void OutRpcClientEnumCa(PACK *p, RPC_CLIENT_ENUM_CA *e) PackAddNum(p, "NumItem", e->NumItem); + PackSetCurrentJsonGroupName(p, "CAList"); for (i = 0;i < e->NumItem;i++) { RPC_CLIENT_ENUM_CA_ITEM *item = e->Items[i]; PackAddIntEx(p, "Key", item->Key, i, e->NumItem); PackAddUniStrEx(p, "SubjectName", item->SubjectName, i, e->NumItem); PackAddUniStrEx(p, "IssuerName", item->IssuerName, i, e->NumItem); - PackAddInt64Ex(p, "Expires", item->Expires, i, e->NumItem); + PackAddTime64Ex(p, "Expires", item->Expires, i, e->NumItem); } + PackSetCurrentJsonGroupName(p, NULL); } // RPC_GET_ISSUER @@ -4361,6 +4363,7 @@ void OutRpcClientEnumSecure(PACK *p, RPC_CLIENT_ENUM_SECURE *e) PackAddNum(p, "NumItem", e->NumItem); + PackSetCurrentJsonGroupName(p, "SecureDeviceList"); for (i = 0;i < e->NumItem;i++) { RPC_CLIENT_ENUM_SECURE_ITEM *item = e->Items[i]; @@ -4370,6 +4373,7 @@ void OutRpcClientEnumSecure(PACK *p, RPC_CLIENT_ENUM_SECURE *e) PackAddStrEx(p, "DeviceName", item->DeviceName, i, e->NumItem); PackAddStrEx(p, "Manufacturer", item->Manufacturer, i, e->NumItem); } + PackSetCurrentJsonGroupName(p, NULL); } // RPC_USE_SECURE @@ -4453,11 +4457,13 @@ void OutRpcEnumObjectInSecure(PACK *p, RPC_ENUM_OBJECT_IN_SECURE *e) PackAddNum(p, "NumItem", e->NumItem); PackAddInt(p, "hWnd", e->hWnd); + PackSetCurrentJsonGroupName(p, "ObjectList"); for (i = 0;i < e->NumItem;i++) { PackAddStrEx(p, "ItemName", e->ItemName[i], i, e->NumItem); PackAddIntEx(p, "ItemType", e->ItemType[i], i, e->NumItem); } + PackSetCurrentJsonGroupName(p, NULL); } // RPC_CLIENT_CREATE_VLAN @@ -4577,6 +4583,7 @@ void OutRpcClientEnumVLan(PACK *p, RPC_CLIENT_ENUM_VLAN *v) PackAddNum(p, "NumItem", v->NumItem); + PackSetCurrentJsonGroupName(p, "VLanList"); for (i = 0;i < v->NumItem;i++) { RPC_CLIENT_ENUM_VLAN_ITEM *item = v->Items[i]; @@ -4586,6 +4593,7 @@ void OutRpcClientEnumVLan(PACK *p, RPC_CLIENT_ENUM_VLAN *v) PackAddStrEx(p, "MacAddress", item->MacAddress, i, v->NumItem); PackAddStrEx(p, "Version", item->Version, i, v->NumItem); } + PackSetCurrentJsonGroupName(p, NULL); } // CLIENT_OPTION @@ -4651,10 +4659,10 @@ void OutRpcClientOption(PACK *p, CLIENT_OPTION *c) PackAddInt(p, "NumRetry", c->NumRetry); PackAddInt(p, "RetryInterval", c->RetryInterval); PackAddInt(p, "MaxConnection", c->MaxConnection); - PackAddInt(p, "UseEncrypt", c->UseEncrypt); - PackAddInt(p, "UseCompress", c->UseCompress); - PackAddInt(p, "HalfConnection", c->HalfConnection); - PackAddInt(p, "NoRoutingTracking", c->NoRoutingTracking); + PackAddBool(p, "UseEncrypt", c->UseEncrypt); + PackAddBool(p, "UseCompress", c->UseCompress); + PackAddBool(p, "HalfConnection", c->HalfConnection); + PackAddBool(p, "NoRoutingTracking", c->NoRoutingTracking); PackAddInt(p, "AdditionalConnectionInterval", c->AdditionalConnectionInterval); PackAddInt(p, "ConnectionDisconnectSpan", c->ConnectionDisconnectSpan); PackAddBool(p, "HideStatusWindow", c->HideStatusWindow); @@ -4866,6 +4874,7 @@ void OutRpcClientEnumAccount(PACK *p, RPC_CLIENT_ENUM_ACCOUNT *e) PackAddNum(p, "NumItem", e->NumItem); + PackSetCurrentJsonGroupName(p, "AccountList"); for (i = 0;i < e->NumItem;i++) { RPC_CLIENT_ENUM_ACCOUNT_ITEM *item = e->Items[i]; @@ -4881,10 +4890,11 @@ void OutRpcClientEnumAccount(PACK *p, RPC_CLIENT_ENUM_ACCOUNT *e) PackAddBoolEx(p, "Connected", item->Connected, i, e->NumItem); PackAddIntEx(p, "Port", item->Port, i, e->NumItem); PackAddStrEx(p, "HubName", item->HubName, i, e->NumItem); - PackAddInt64Ex(p, "CreateDateTime", item->CreateDateTime, i, e->NumItem); - PackAddInt64Ex(p, "UpdateDateTime", item->UpdateDateTime, i, e->NumItem); - PackAddInt64Ex(p, "LastConnectDateTime", item->LastConnectDateTime, i, e->NumItem); + PackAddTime64Ex(p, "CreateDateTime", item->CreateDateTime, i, e->NumItem); + PackAddTime64Ex(p, "UpdateDateTime", item->UpdateDateTime, i, e->NumItem); + PackAddTime64Ex(p, "LastConnectDateTime", item->LastConnectDateTime, i, e->NumItem); } + PackSetCurrentJsonGroupName(p, NULL); } // RPC_CLIENT_DELETE_ACCOUNT @@ -4998,9 +5008,9 @@ void OutRpcClientGetAccount(PACK *p, RPC_CLIENT_GET_ACCOUNT *c) PackAddData(p, "ShortcutKey", c->ShortcutKey, SHA1_SIZE); - PackAddInt64(p, "CreateDateTime", c->CreateDateTime); - PackAddInt64(p, "UpdateDateTime", c->UpdateDateTime); - PackAddInt64(p, "LastConnectDateTime", c->LastConnectDateTime); + PackAddTime64(p, "CreateDateTime", c->CreateDateTime); + PackAddTime64(p, "UpdateDateTime", c->UpdateDateTime); + PackAddTime64(p, "LastConnectDateTime", c->LastConnectDateTime); } // RPC_CLIENT_CONNECT @@ -5103,6 +5113,7 @@ void InRpcClientGetConnectionStatus(RPC_CLIENT_GET_CONNECTION_STATUS *s, PACK *p s->UseCompress = PackGetInt(p, "UseCompress") ? true : false; s->IsRUDPSession = PackGetInt(p, "IsRUDPSession") ? true : false; PackGetStr(p, "UnderlayProtocol", s->UnderlayProtocol, sizeof(s->UnderlayProtocol)); + PackGetStr(p, "ProtocolDetails", s->ProtocolDetails, sizeof(s->ProtocolDetails)); s->IsUdpAccelerationEnabled = PackGetInt(p, "IsUdpAccelerationEnabled") ? true : false; s->IsUsingUdpAcceleration = PackGetInt(p, "IsUsingUdpAcceleration") ? true : false; @@ -5148,32 +5159,33 @@ void OutRpcClientGetConnectionStatus(PACK *p, RPC_CLIENT_GET_CONNECTION_STATUS * PackAddData(p, "SessionKey", c->SessionKey, SHA1_SIZE); - PackAddInt(p, "Active", c->Active); - PackAddInt(p, "Connected", c->Connected); + PackAddBool(p, "Active", c->Active); + PackAddBool(p, "Connected", c->Connected); PackAddInt(p, "SessionStatus", c->SessionStatus); PackAddInt(p, "ServerPort", c->ServerPort); PackAddInt(p, "ServerProductVer", c->ServerProductVer); PackAddInt(p, "ServerProductBuild", c->ServerProductBuild); PackAddInt(p, "NumConnectionsEatablished", c->NumConnectionsEatablished); - PackAddInt(p, "HalfConnection", c->HalfConnection); - PackAddInt(p, "QoS", c->QoS); + PackAddBool(p, "HalfConnection", c->HalfConnection); + PackAddBool(p, "QoS", c->QoS); PackAddInt(p, "MaxTcpConnections", c->MaxTcpConnections); PackAddInt(p, "NumTcpConnections", c->NumTcpConnections); PackAddInt(p, "NumTcpConnectionsUpload", c->NumTcpConnectionsUpload); PackAddInt(p, "NumTcpConnectionsDownload", c->NumTcpConnectionsDownload); - PackAddInt(p, "UseEncrypt", c->UseEncrypt); - PackAddInt(p, "UseCompress", c->UseCompress); - PackAddInt(p, "IsRUDPSession", c->IsRUDPSession); + PackAddBool(p, "UseEncrypt", c->UseEncrypt); + PackAddBool(p, "UseCompress", c->UseCompress); + PackAddBool(p, "IsRUDPSession", c->IsRUDPSession); PackAddStr(p, "UnderlayProtocol", c->UnderlayProtocol); - PackAddInt(p, "IsUdpAccelerationEnabled", c->IsUdpAccelerationEnabled); - PackAddInt(p, "IsUsingUdpAcceleration", c->IsUsingUdpAcceleration); + PackAddStr(p, "ProtocolDetails", c->ProtocolDetails); + PackAddBool(p, "IsUdpAccelerationEnabled", c->IsUdpAccelerationEnabled); + PackAddBool(p, "IsUsingUdpAcceleration", c->IsUsingUdpAcceleration); PackAddBool(p, "IsBridgeMode", c->IsBridgeMode); PackAddBool(p, "IsMonitorMode", c->IsMonitorMode); - PackAddInt64(p, "StartTime", c->StartTime); - PackAddInt64(p, "FirstConnectionEstablisiedTime", c->FirstConnectionEstablisiedTime); - PackAddInt64(p, "CurrentConnectionEstablishTime", c->CurrentConnectionEstablishTime); + PackAddTime64(p, "StartTime", c->StartTime); + PackAddTime64(p, "FirstConnectionEstablisiedTime", c->FirstConnectionEstablisiedTime); + PackAddTime64(p, "CurrentConnectionEstablishTime", c->CurrentConnectionEstablishTime); PackAddInt64(p, "TotalSendSize", c->TotalSendSize); PackAddInt64(p, "TotalRecvSize", c->TotalRecvSize); PackAddInt64(p, "TotalSendSizeReal", c->TotalSendSizeReal); @@ -6124,9 +6136,23 @@ void CiGetSessionStatus(RPC_CLIENT_GET_CONNECTION_STATUS *st, SESSION *s) st->IsRUDPSession = s->IsRUDPSession; // Physical communication protocol StrCpy(st->UnderlayProtocol, sizeof(st->UnderlayProtocol), s->UnderlayProtocol); + // Protocol details + StrCpy(st->ProtocolDetails, sizeof(st->ProtocolDetails), s->ProtocolDetails); + Trim(st->ProtocolDetails); // UDP acceleration function st->IsUdpAccelerationEnabled = s->UseUdpAcceleration; st->IsUsingUdpAcceleration = s->IsUsingUdpAcceleration; + if (s->IpcSessionShared != NULL && IsEmptyStr(s->IpcSessionShared->ProtocolDetails) == false) + { + char tmp[256]; + StrCpy(tmp, sizeof(tmp), s->IpcSessionShared->ProtocolDetails); + Trim(tmp); + StrCat(st->ProtocolDetails, sizeof(st->ProtocolDetails), " "); + StrCat(st->ProtocolDetails, sizeof(st->ProtocolDetails), tmp); + + st->IsUdpAccelerationEnabled = s->IpcSessionShared->EnableUdpAccel; + st->IsUsingUdpAcceleration = s->IpcSessionShared->UsingUdpAccel; + } // Session key Copy(st->SessionKey, s->SessionKey, SHA1_SIZE); // Policy diff --git a/src/Cedar/Client.h b/src/Cedar/Client.h index f57e32e8..6790a91a 100644 --- a/src/Cedar/Client.h +++ b/src/Cedar/Client.h @@ -433,6 +433,7 @@ struct RPC_CLIENT_GET_CONNECTION_STATUS bool UseCompress; // Use of compression bool IsRUDPSession; // R-UDP session char UnderlayProtocol[64]; // Physical communication protocol + char ProtocolDetails[256]; // Protocol Details bool IsUdpAccelerationEnabled; // The UDP acceleration is enabled bool IsUsingUdpAcceleration; // Using the UDP acceleration function char SessionName[MAX_SESSION_NAME_LEN + 1]; // Session name diff --git a/src/Cedar/Command.c b/src/Cedar/Command.c index 71568d43..5b2c67e8 100644 --- a/src/Cedar/Command.c +++ b/src/Cedar/Command.c @@ -14494,6 +14494,12 @@ void CmdPrintStatusToListViewEx(CT *ct, RPC_CLIENT_GET_CONNECTION_STATUS *s, boo CtInsert(ct, _UU("CM_ST_UNDERLAY_PROTOCOL"), tmp); } + if (IsEmptyStr(s->ProtocolDetails) == false) + { + StrToUni(tmp, sizeof(tmp), s->ProtocolDetails); + CtInsert(ct, _UU("CM_ST_PROTOCOL_DETAILS"), tmp); + } + CtInsert(ct, _UU("CM_ST_UDP_ACCEL_ENABLED"), (s->IsUdpAccelerationEnabled ? _UU("CM_ST_YES") : _UU("CM_ST_NO"))); CtInsert(ct, _UU("CM_ST_UDP_ACCEL_USING"), (s->IsUsingUdpAcceleration ? _UU("CM_ST_YES") : _UU("CM_ST_NO"))); @@ -21663,6 +21669,9 @@ UINT PsLicenseAdd(CONSOLE *c, char *cmd_name, wchar_t *str, void *param) FreeParamValueList(o); + c->Write(c, _UU("SM_LICENSE_WARNING")); + c->Write(c, L"\n"); + return 0; } diff --git a/src/Cedar/Connection.c b/src/Cedar/Connection.c index ebd8a6cb..5bdb0a34 100644 --- a/src/Cedar/Connection.c +++ b/src/Cedar/Connection.c @@ -1267,6 +1267,8 @@ void ConnectionSend(CONNECTION *c, UINT64 now) s->TotalSendSizeReal += b->Size; c->CurrentSendQueueSize -= b->Size; + + Free(new_buf); } FreeBlock(b); @@ -1861,6 +1863,18 @@ void ConnectionReceive(CONNECTION *c, CANCEL *c1, CANCEL *c2) { TUBE *t = sock->BulkRecvTube; + //for testing purpose + //if (sock->test_tmp1 == 0) sock->test_tmp1 = now; + //if ((sock->test_tmp1 + 5000ULL) <= now) + //{ + // // bugbug + // if (c->ServerMode == false) + // { + // WHERE; + // Disconnect(sock); + // } + //} + if (s->EnableBulkOnRUDP) { // R-UDP bulk transfer data reception @@ -2789,6 +2803,8 @@ BLOCK *NewBlock(void *data, UINT size, int compress) b = MallocFast(sizeof(BLOCK)); + b->RawFlagRetUdpAccel = 0; + b->IsFlooding = false; b->PriorityQoS = b->Ttl = b->Param1 = 0; diff --git a/src/Cedar/Connection.h b/src/Cedar/Connection.h index 96b7627f..2b1f8091 100644 --- a/src/Cedar/Connection.h +++ b/src/Cedar/Connection.h @@ -252,6 +252,7 @@ struct BLOCK UINT Ttl; // TTL value (Used only in ICMP NAT of Virtual.c) UINT Param1; // Parameter 1 bool IsFlooding; // Is flooding packet + UCHAR RawFlagRetUdpAccel; // Raw flag returned by UDP accel }; // Connection structure @@ -305,6 +306,7 @@ struct CONNECTION void *hWndForUI; // Parent window bool IsInProc; // In-process char InProcPrefix[64]; // Prefix + UINT InProcLayer; // InProc layer UINT AdditionalConnectionFailedCounter; // Additional connection failure counter UINT64 LastCounterResetTick; // Time the counter was reset finally bool WasSstp; // Processed the SSTP @@ -314,6 +316,9 @@ struct CONNECTION UINT LastPacketQueueSize; // The last queue size of packets UINT LastRecvFifoTotalSize; // The last RecvFifo total size UINT LastRecvBlocksNum; // The last ReceivedBlocks num + bool IsJsonRpc; // Is JSON-RPC + bool JsonRpcAuthed; // JSON-RPC Authed + LISTENER *Listener; // Listener ref }; diff --git a/src/Cedar/DDNS.c b/src/Cedar/DDNS.c index c9056dd7..66373dd4 100644 --- a/src/Cedar/DDNS.c +++ b/src/Cedar/DDNS.c @@ -134,6 +134,9 @@ void DCGetStatus(DDNS_CLIENT *c, DDNS_CLIENT_STATUS *st) Copy(&st->InternetSetting, &c->InternetSetting, sizeof(INTERNET_SETTING)); } Unlock(c->Lock); + + UniStrCpy(st->ErrStr_IPv4, sizeof(st->ErrStr_IPv4), _E(st->Err_IPv4)); + UniStrCpy(st->ErrStr_IPv6, sizeof(st->ErrStr_IPv6), _E(st->Err_IPv6)); } // Set the Internet settings diff --git a/src/Cedar/DDNS.h b/src/Cedar/DDNS.h index 3c935d27..d3e1363d 100644 --- a/src/Cedar/DDNS.h +++ b/src/Cedar/DDNS.h @@ -208,6 +208,8 @@ struct DDNS_REGISTER_PARAM struct DDNS_CLIENT_STATUS { UINT Err_IPv4, Err_IPv6; // Last error + wchar_t ErrStr_IPv4[MAX_SIZE]; + wchar_t ErrStr_IPv6[MAX_SIZE]; char CurrentHostName[DDNS_MAX_HOSTNAME + 1]; // Current host name char CurrentFqdn[MAX_SIZE]; // Current FQDN char DnsSuffix[MAX_SIZE]; // DNS suffix diff --git a/src/Cedar/EtherLog.c b/src/Cedar/EtherLog.c index 36bf0932..ea290915 100644 --- a/src/Cedar/EtherLog.c +++ b/src/Cedar/EtherLog.c @@ -662,6 +662,7 @@ void OutRpcEnumDevice(PACK *p, RPC_ENUM_DEVICE *t) PackAddInt(p, "NumItem", t->NumItem); + PackSetCurrentJsonGroupName(p, "DeviceList"); for (i = 0;i < t->NumItem;i++) { RPC_ENUM_DEVICE_ITEM *d = &t->Items[i]; @@ -669,6 +670,7 @@ void OutRpcEnumDevice(PACK *p, RPC_ENUM_DEVICE *t) PackAddStrEx(p, "DeviceName", d->DeviceName, i, t->NumItem); PackAddBoolEx(p, "Active", d->Active, i, t->NumItem); } + PackSetCurrentJsonGroupName(p, NULL); PackAddBool(p, "IsLicenseSupported", t->IsLicenseSupported); } @@ -709,7 +711,7 @@ void OutRpcElLicenseStatus(PACK *p, RPC_EL_LICENSE_STATUS *t) PackAddBool(p, "Valid", t->Valid); PackAddInt64(p, "SystemId", t->SystemId); - PackAddInt64(p, "SystemExpires", t->SystemExpires); + PackAddTime64(p, "SystemExpires", t->SystemExpires); } // Listener thread diff --git a/src/Cedar/Hub.c b/src/Cedar/Hub.c index 7dc3de39..da339c2a 100644 --- a/src/Cedar/Hub.c +++ b/src/Cedar/Hub.c @@ -159,7 +159,7 @@ UINT num_admin_options = sizeof(admin_options) / sizeof(ADMIN_OPTION); // Create an EAP client for the specified Virtual Hub -EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, char *username) +EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, char *username, char *vpn_protocol_state_str) { HUB *hub = NULL; EAP_CLIENT *ret = NULL; @@ -209,6 +209,11 @@ EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, ch if (eap != NULL) { + if (IsEmptyStr(vpn_protocol_state_str) == false) + { + StrCpy(eap->In_VpnProtocolState, sizeof(eap->In_VpnProtocolState), vpn_protocol_state_str); + } + if (use_peap == false) { // EAP @@ -778,6 +783,8 @@ void HubOptionStructToData(RPC_ADMIN_OPTION *ao, HUB_OPTION *o, char *hub_name) { ADMIN_OPTION *a = LIST_DATA(aol, i); + UniStrCpy(a->Descrption, sizeof(a->Descrption), GetHubAdminOptionHelpString(a->Name)); + Copy(&ao->Items[i], a, sizeof(ADMIN_OPTION)); Free(a); diff --git a/src/Cedar/Hub.h b/src/Cedar/Hub.h index 5334dbfd..884c5c3e 100644 --- a/src/Cedar/Hub.h +++ b/src/Cedar/Hub.h @@ -384,6 +384,7 @@ struct ADMIN_OPTION { char Name[MAX_ADMIN_OPTION_NAME_LEN + 1]; // Name UINT Value; // Data + wchar_t Descrption[MAX_SIZE]; // Descrption }; // Certificate Revocation List entry @@ -634,7 +635,7 @@ void CalcTrafficDiff(TRAFFIC *diff, TRAFFIC *old, TRAFFIC *current); bool CheckMaxLoggedPacketsPerMinute(SESSION *s, UINT max_packets, UINT64 now); void VgsSetUserAgentValue(char *str); void VgsSetEmbTag(bool b); -EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, char *username); +EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, char *username, char *vpn_protocol_state_str); #endif // HUB_H diff --git a/src/Cedar/IPsec_EtherIP.c b/src/Cedar/IPsec_EtherIP.c index 7c7d6222..1db912c1 100644 --- a/src/Cedar/IPsec_EtherIP.c +++ b/src/Cedar/IPsec_EtherIP.c @@ -161,7 +161,7 @@ void EtherIPIpcConnectThread(THREAD *t, void *p) &s->ClientIP, s->ClientPort, &s->ServerIP, s->ServerPort, tmp, - s->CryptName, true, mss, NULL); + s->CryptName, true, mss, NULL, NULL, IPC_LAYER_2); if (ipc != NULL) { diff --git a/src/Cedar/IPsec_IPC.c b/src/Cedar/IPsec_IPC.c index 705a9539..82831784 100644 --- a/src/Cedar/IPsec_IPC.c +++ b/src/Cedar/IPsec_IPC.c @@ -314,7 +314,7 @@ IPC *NewIPCByParam(CEDAR *cedar, IPC_PARAM *param, UINT *error_code) param->UserName, param->Password, error_code, ¶m->ClientIp, param->ClientPort, ¶m->ServerIp, param->ServerPort, param->ClientHostname, param->CryptName, - param->BridgeMode, param->Mss, NULL); + param->BridgeMode, param->Mss, NULL, param->ClientCertificate, param->Layer); return ipc; } @@ -323,7 +323,8 @@ IPC *NewIPCByParam(CEDAR *cedar, IPC_PARAM *param, UINT *error_code) IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char *username, char *password, UINT *error_code, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port, char *client_hostname, char *crypt_name, - bool bridge_mode, UINT mss, EAP_CLIENT *eap_client) + bool bridge_mode, UINT mss, EAP_CLIENT *eap_client, X *client_certificate, + UINT layer) { IPC *ipc; UINT dummy_int = 0; @@ -338,6 +339,7 @@ IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char NODE_INFO info; BUF *b; UCHAR mschap_v2_server_response_20[20]; + UINT64 u64; // Validate arguments if (cedar == NULL || username == NULL || password == NULL || client_hostname == NULL) { @@ -371,6 +373,12 @@ IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char ipc->Cedar = cedar; AddRef(cedar->ref); + ipc->Layer = layer; + if (ipc->Layer == 0) + { + ipc->Layer = IPC_LAYER_2; + } + ipc->FlushList = NewTubeFlushList(); StrCpy(ipc->ClientHostname, sizeof(ipc->ClientHostname), client_hostname); @@ -416,7 +424,14 @@ IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char FreePack(p); // Upload the authentication data - p = PackLoginWithPlainPassword(hubname, username, password); + if (client_certificate != NULL) + { + p = PackLoginWithOpenVPNCertificate(hubname, username, client_certificate); + } + else + { + p = PackLoginWithPlainPassword(hubname, username, password); + } PackAddStr(p, "hello", client_name); PackAddInt(p, "client_ver", cedar->Version); PackAddInt(p, "client_build", cedar->Build); @@ -451,6 +466,7 @@ IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char PackAddStr(p, "inproc_postfix", postfix); PackAddStr(p, "inproc_cryptname", crypt_name); + PackAddInt(p, "inproc_layer", ipc->Layer); // Node information Zero(&info, sizeof(info)); @@ -532,6 +548,10 @@ IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char Debug("IPC: Session = %s, Connection = %s, Mac = %s\n", ipc->SessionName, ipc->ConnectionName, macstr); + u64 = PackGetInt64(p, "IpcSessionSharedBuffer"); + ipc->IpcSessionSharedBuffer = (SHARED_BUFFER *)u64; + ipc->IpcSessionShared = ipc->IpcSessionSharedBuffer->Data; + FreePack(p); ReleaseSock(a); @@ -665,6 +685,8 @@ void FreeIPC(IPC *ipc) } ReleaseQueue(ipc->IPv4RecviedQueue); + + ReleaseSharedBuffer(ipc->IpcSessionSharedBuffer); Free(ipc); } diff --git a/src/Cedar/IPsec_IPC.h b/src/Cedar/IPsec_IPC.h index 4a733297..2340788e 100644 --- a/src/Cedar/IPsec_IPC.h +++ b/src/Cedar/IPsec_IPC.h @@ -119,6 +119,9 @@ #define IPC_PASSWORD_MSCHAPV2_TAG "xH7DiNlurDhcYV4a:" +#define IPC_LAYER_2 2 +#define IPC_LAYER_3 3 + // ARP table entry struct IPC_ARP { @@ -138,6 +141,14 @@ struct IPC_DHCP_RELESAE_QUEUE UCHAR MacAddress[6]; }; +// IPC_SESSION_SHARED_BUFFER_DATA +struct IPC_SESSION_SHARED_BUFFER_DATA +{ + char ProtocolDetails[256]; // Protocol Details + bool EnableUdpAccel; + bool UsingUdpAccel; +}; + // IPC_PARAM struct IPC_PARAM { @@ -156,6 +167,8 @@ struct IPC_PARAM UINT Mss; bool IsL3Mode; bool IsOpenVPN; + X *ClientCertificate; + UINT Layer; }; // IPC_ASYNC object @@ -200,6 +213,9 @@ struct IPC TUBE_FLUSH_LIST *FlushList; // Tube Flush List UCHAR MsChapV2_ServerResponse[20]; // Server response DHCP_CLASSLESS_ROUTE_TABLE ClasslessRoute; // Classless routing table + SHARED_BUFFER *IpcSessionSharedBuffer; // A shared buffer between IPC and Session + IPC_SESSION_SHARED_BUFFER_DATA *IpcSessionShared; // A shared data between IPC and Session + UINT Layer; }; // MS-CHAPv2 authentication information @@ -215,7 +231,8 @@ struct IPC_MSCHAP_V2_AUTHINFO IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char *username, char *password, UINT *error_code, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port, char *client_hostname, char *crypt_name, - bool bridge_mode, UINT mss, EAP_CLIENT *eap_client); + bool bridge_mode, UINT mss, EAP_CLIENT *eap_client, X *client_certificate, + UINT layer); IPC *NewIPCByParam(CEDAR *cedar, IPC_PARAM *param, UINT *error_code); IPC *NewIPCBySock(CEDAR *cedar, SOCK *s, void *mac_address); void FreeIPC(IPC *ipc); diff --git a/src/Cedar/IPsec_PPP.c b/src/Cedar/IPsec_PPP.c index d47a5f08..5d04f099 100644 --- a/src/Cedar/IPsec_PPP.c +++ b/src/Cedar/IPsec_PPP.c @@ -299,7 +299,7 @@ void PPPThread(THREAD *thread, void *param) IPToStr(client_ip_tmp, sizeof(client_ip_tmp), &p->ClientIP); - eap = HubNewEapClient(p->Cedar, hub, client_ip_tmp, id); + eap = HubNewEapClient(p->Cedar, hub, client_ip_tmp, id, "L3:PPP"); if (eap) { @@ -1009,7 +1009,8 @@ PPP_PACKET *PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *req) // Attempt to connect with IPC ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password, &error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort, - p->ClientHostname, p->CryptName, false, p->AdjustMss, p->EapClient); + p->ClientHostname, p->CryptName, false, p->AdjustMss, p->EapClient, NULL, + IPC_LAYER_3); if (ipc != NULL) { @@ -1142,7 +1143,8 @@ PPP_PACKET *PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *req) ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password, &error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort, - p->ClientHostname, p->CryptName, false, p->AdjustMss, NULL); + p->ClientHostname, p->CryptName, false, p->AdjustMss, NULL, NULL, + IPC_LAYER_3); if (ipc != NULL) { diff --git a/src/Cedar/Interop_OpenVPN.c b/src/Cedar/Interop_OpenVPN.c index 4c6d8771..dbb203e9 100644 --- a/src/Cedar/Interop_OpenVPN.c +++ b/src/Cedar/Interop_OpenVPN.c @@ -433,7 +433,8 @@ void OvsProcessRecvControlPacket(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN // Create an SSL pipe Lock(s->Cedar->lock); { - c->SslPipe = NewSslPipe(true, s->Cedar->ServerX, s->Cedar->ServerK, s->Dh); + bool cert_verify = true; + c->SslPipe = NewSslPipeEx(true, s->Cedar->ServerX, s->Cedar->ServerK, s->Dh, cert_verify, &c->ClientCert); } Unlock(s->Cedar->lock); @@ -703,8 +704,19 @@ void OvsBeginIPCAsyncConnectionIfEmpty(OPENVPN_SERVER *s, OPENVPN_SESSION *se, O p.BridgeMode = true; } + if (IsEmptyStr(c->ClientKey.Username) || IsEmptyStr(c->ClientKey.Password)) + { + // OpenVPN X.509 certificate authentication is used only when no username / password is specified + if (c->ClientCert.X != NULL) + { + p.ClientCertificate = c->ClientCert.X; + } + } + p.IsOpenVPN = true; + p.Layer = (se->Mode == OPENVPN_MODE_L2) ? IPC_LAYER_2 : IPC_LAYER_3; + // Calculate the MSS p.Mss = OvsCalcTcpMss(s, se, c); Debug("MSS=%u\n", p.Mss); @@ -771,6 +783,26 @@ void OvsSetupSessionParameters(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_C OvsLog(s, se, c, "LO_OPTION_STR_RECV", data->OptionString); + if (c->ClientCert.X != NULL) + { + if (c->ClientCert.X->subject_name != NULL) + { + OvsLog(s, se, c, "LO_CLIENT_CERT", c->ClientCert.X->subject_name->CommonName); + } + else + { + OvsLog(s, se, c, "LO_CLIENT_CERT", "(unknown CN)"); + } + } + else if (!c->ClientCert.PreverifyErr) + { + OvsLog(s, se, c, "LO_CLIENT_NO_CERT"); + } + else + { + OvsLog(s, se, c, "LO_CLIENT_UNVERIFIED_CERT", c->ClientCert.PreverifyErrMessage); + } + Zero(opt_str, sizeof(opt_str)); StrCpy(opt_str, sizeof(opt_str), data->OptionString); if (s->Cedar != NULL && (IsEmptyStr(opt_str) || StartWith(opt_str, "V0 UNDEF") || InStr(opt_str, ",") == false)) @@ -1350,6 +1382,11 @@ void OvsFreeChannel(OPENVPN_CHANNEL *c) FreeMd(c->MdRecv); FreeMd(c->MdSend); + if (c->ClientCert.X != NULL) + { + FreeX(c->ClientCert.X); + } + Free(c); } diff --git a/src/Cedar/Interop_OpenVPN.h b/src/Cedar/Interop_OpenVPN.h index 8db9beca..b23eca5e 100644 --- a/src/Cedar/Interop_OpenVPN.h +++ b/src/Cedar/Interop_OpenVPN.h @@ -248,6 +248,7 @@ struct OPENVPN_CHANNEL bool IsInitiatorServer; // Whether the channel was started from the server side bool RekeyInitiated; // Whether re-keying has already started UINT64 NextRekey; + struct SslClientCertInfo ClientCert; // Client certificate and verification data }; // OpenVPN session diff --git a/src/Cedar/Listener.c b/src/Cedar/Listener.c index 5da5ade6..f57dcf2a 100644 --- a/src/Cedar/Listener.c +++ b/src/Cedar/Listener.c @@ -247,6 +247,9 @@ void TCPAcceptedThread(THREAD *t, void *param) // Create a connection c = NewServerConnection(r->Cedar, s, t); + AddRef(r->ref); + c->Listener = r; + // Register to Cedar as a transient connection AddConnection(c->Cedar, c); @@ -264,8 +267,11 @@ void TCPAcceptedThread(THREAD *t, void *param) ConnectionAccept(c); flag1 = c->flag1; + // Release SLog(r->Cedar, "LS_CONNECTION_END_1", c->Name); + ReleaseListener(c->Listener); + c->Listener = NULL; ReleaseConnection(c); // Release diff --git a/src/Cedar/Nat.c b/src/Cedar/Nat.c index c5f782b8..c5e35af8 100644 --- a/src/Cedar/Nat.c +++ b/src/Cedar/Nat.c @@ -895,18 +895,21 @@ void OutRpcEnumDhcp(PACK *p, RPC_ENUM_DHCP *t) PackAddInt(p, "NumItem", t->NumItem); PackAddStr(p, "HubName", t->HubName); + PackSetCurrentJsonGroupName(p, "DhcpTable"); + for (i = 0;i < t->NumItem;i++) { RPC_ENUM_DHCP_ITEM *e = &t->Items[i]; PackAddIntEx(p, "Id", e->Id, i, t->NumItem); - PackAddInt64Ex(p, "LeasedTime", e->LeasedTime, i, t->NumItem); - PackAddInt64Ex(p, "ExpireTime", e->ExpireTime, i, t->NumItem); + PackAddTime64Ex(p, "LeasedTime", e->LeasedTime, i, t->NumItem); + PackAddTime64Ex(p, "ExpireTime", e->ExpireTime, i, t->NumItem); PackAddDataEx(p, "MacAddress", e->MacAddress, 6, i, t->NumItem); PackAddIp32Ex(p, "IpAddress", e->IpAddress, i, t->NumItem); PackAddIntEx(p, "Mask", e->Mask, i, t->NumItem); PackAddStrEx(p, "Hostname", e->Hostname, i, t->NumItem); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcEnumDhcp(RPC_ENUM_DHCP *t) { @@ -963,6 +966,8 @@ void OutRpcEnumNat(PACK *p, RPC_ENUM_NAT *t) PackAddInt(p, "NumItem", t->NumItem); PackAddStr(p, "HubName", t->HubName); + + PackSetCurrentJsonGroupName(p, "NatTable"); for (i = 0;i < t->NumItem;i++) { RPC_ENUM_NAT_ITEM *e = &t->Items[i]; @@ -975,12 +980,13 @@ void OutRpcEnumNat(PACK *p, RPC_ENUM_NAT *t) PackAddIp32Ex(p, "DestIp", e->DestIp, i, t->NumItem); PackAddStrEx(p, "DestHost", e->DestHost, i, t->NumItem); PackAddIntEx(p, "DestPort", e->DestPort, i, t->NumItem); - PackAddInt64Ex(p, "CreatedTime", e->CreatedTime, i, t->NumItem); - PackAddInt64Ex(p, "LastCommTime", e->LastCommTime, i, t->NumItem); + PackAddTime64Ex(p, "CreatedTime", e->CreatedTime, i, t->NumItem); + PackAddTime64Ex(p, "LastCommTime", e->LastCommTime, i, t->NumItem); PackAddInt64Ex(p, "SendSize", e->SendSize, i, t->NumItem); PackAddInt64Ex(p, "RecvSize", e->RecvSize, i, t->NumItem); PackAddIntEx(p, "TcpStatus", e->TcpStatus, i, t->NumItem); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcEnumNat(RPC_ENUM_NAT *t) { diff --git a/src/Cedar/Protocol.c b/src/Cedar/Protocol.c index 7febcf84..5fd8c12c 100644 --- a/src/Cedar/Protocol.c +++ b/src/Cedar/Protocol.c @@ -106,6 +106,726 @@ static UCHAR ssl_packet_start[3] = {0x17, 0x03, 0x00}; +// MIME list from https://www.freeformatter.com/mime-types-list.html +static HTTP_MIME_TYPE http_mime_types[] = +{ + {".x3d", "application/vnd.hzn-3d-crossword"}, + {".3gp", "video/3gpp"}, + {".3g2", "video/3gpp2"}, + {".mseq", "application/vnd.mseq"}, + {".pwn", "application/vnd.3m.post-it-notes"}, + {".plb", "application/vnd.3gpp.pic-bw-large"}, + {".psb", "application/vnd.3gpp.pic-bw-small"}, + {".pvb", "application/vnd.3gpp.pic-bw-var"}, + {".tcap", "application/vnd.3gpp2.tcap"}, + {".7z", "application/x-7z-compressed"}, + {".abw", "application/x-abiword"}, + {".ace", "application/x-ace-compressed"}, + {".acc", "application/vnd.americandynamics.acc"}, + {".acu", "application/vnd.acucobol"}, + {".atc", "application/vnd.acucorp"}, + {".adp", "audio/adpcm"}, + {".aab", "application/x-authorware-bin"}, + {".aam", "application/x-authorware-map"}, + {".aas", "application/x-authorware-seg"}, + {".air", "application/vnd.adobe.air-application-installer-package+zip"}, + {".swf", "application/x-shockwave-flash"}, + {".fxp", "application/vnd.adobe.fxp"}, + {".pdf", "application/pdf"}, + {".ppd", "application/vnd.cups-ppd"}, + {".dir", "application/x-director"}, + {".xdp", "application/vnd.adobe.xdp+xml"}, + {".xfdf", "application/vnd.adobe.xfdf"}, + {".aac", "audio/x-aac"}, + {".ahead", "application/vnd.ahead.space"}, + {".azf", "application/vnd.airzip.filesecure.azf"}, + {".azs", "application/vnd.airzip.filesecure.azs"}, + {".azw", "application/vnd.amazon.ebook"}, + {".ami", "application/vnd.amiga.ami"}, + {".apk", "application/vnd.android.package-archive"}, + {".cii", "application/vnd.anser-web-certificate-issue-initiation"}, + {".fti", "application/vnd.anser-web-funds-transfer-initiation"}, + {".atx", "application/vnd.antix.game-component"}, + {".dmg", "application/x-apple-diskimage"}, + {".mpkg", "application/vnd.apple.installer+xml"}, + {".aw", "application/applixware"}, + {".les", "application/vnd.hhe.lesson-player"}, + {".swi", "application/vnd.aristanetworks.swi"}, + {".s", "text/x-asm"}, + {".atomcat", "application/atomcat+xml"}, + {".atomsvc", "application/atomsvc+xml"}, + {".atom", "application/atom+xml"}, + {".ac", "application/pkix-attr-cert"}, + {".aif", "audio/x-aiff"}, + {".avi", "video/x-msvideo"}, + {".aep", "application/vnd.audiograph"}, + {".dxf", "image/vnd.dxf"}, + {".dwf", "model/vnd.dwf"}, + {".par", "text/plain-bas"}, + {".bcpio", "application/x-bcpio"}, + {".bin", "application/octet-stream"}, + {".bmp", "image/bmp"}, + {".torrent", "application/x-bittorrent"}, + {".cod", "application/vnd.rim.cod"}, + {".mpm", "application/vnd.blueice.multipass"}, + {".bmi", "application/vnd.bmi"}, + {".sh", "application/x-sh"}, + {".btif", "image/prs.btif"}, + {".rep", "application/vnd.businessobjects"}, + {".bz", "application/x-bzip"}, + {".bz2", "application/x-bzip2"}, + {".csh", "application/x-csh"}, + {".c", "text/x-c"}, + {".cdxml", "application/vnd.chemdraw+xml"}, + {".css", "text/css"}, + {".cdx", "chemical/x-cdx"}, + {".cml", "chemical/x-cml"}, + {".csml", "chemical/x-csml"}, + {".cdbcmsg", "application/vnd.contact.cmsg"}, + {".cla", "application/vnd.claymore"}, + {".c4g", "application/vnd.clonk.c4group"}, + {".sub", "image/vnd.dvb.subtitle"}, + {".cdmia", "application/cdmi-capability"}, + {".cdmic", "application/cdmi-container"}, + {".cdmid", "application/cdmi-domain"}, + {".cdmio", "application/cdmi-object"}, + {".cdmiq", "application/cdmi-queue"}, + {".c11amc", "application/vnd.cluetrust.cartomobile-config"}, + {".c11amz", "application/vnd.cluetrust.cartomobile-config-pkg"}, + {".ras", "image/x-cmu-raster"}, + {".dae", "model/vnd.collada+xml"}, + {".csv", "text/csv"}, + {".cpt", "application/mac-compactpro"}, + {".wmlc", "application/vnd.wap.wmlc"}, + {".cgm", "image/cgm"}, + {".ice", "x-conference/x-cooltalk"}, + {".cmx", "image/x-cmx"}, + {".xar", "application/vnd.xara"}, + {".cmc", "application/vnd.cosmocaller"}, + {".cpio", "application/x-cpio"}, + {".clkx", "application/vnd.crick.clicker"}, + {".clkk", "application/vnd.crick.clicker.keyboard"}, + {".clkp", "application/vnd.crick.clicker.palette"}, + {".clkt", "application/vnd.crick.clicker.template"}, + {".clkw", "application/vnd.crick.clicker.wordbank"}, + {".wbs", "application/vnd.criticaltools.wbs+xml"}, + {".cryptonote", "application/vnd.rig.cryptonote"}, + {".cif", "chemical/x-cif"}, + {".cmdf", "chemical/x-cmdf"}, + {".cu", "application/cu-seeme"}, + {".cww", "application/prs.cww"}, + {".curl", "text/vnd.curl"}, + {".dcurl", "text/vnd.curl.dcurl"}, + {".mcurl", "text/vnd.curl.mcurl"}, + {".scurl", "text/vnd.curl.scurl"}, + {".car", "application/vnd.curl.car"}, + {".pcurl", "application/vnd.curl.pcurl"}, + {".cmp", "application/vnd.yellowriver-custom-menu"}, + {".dssc", "application/dssc+der"}, + {".xdssc", "application/dssc+xml"}, + {".deb", "application/x-debian-package"}, + {".uva", "audio/vnd.dece.audio"}, + {".uvi", "image/vnd.dece.graphic"}, + {".uvh", "video/vnd.dece.hd"}, + {".uvm", "video/vnd.dece.mobile"}, + {".uvu", "video/vnd.uvvu.mp4"}, + {".uvp", "video/vnd.dece.pd"}, + {".uvs", "video/vnd.dece.sd"}, + {".uvv", "video/vnd.dece.video"}, + {".dvi", "application/x-dvi"}, + {".seed", "application/vnd.fdsn.seed"}, + {".dtb", "application/x-dtbook+xml"}, + {".res", "application/x-dtbresource+xml"}, + {".ait", "application/vnd.dvb.ait"}, + {".svc", "application/vnd.dvb.service"}, + {".eol", "audio/vnd.digital-winds"}, + {".djvu", "image/vnd.djvu"}, + {".dtd", "application/xml-dtd"}, + {".mlp", "application/vnd.dolby.mlp"}, + {".wad", "application/x-doom"}, + {".dpg", "application/vnd.dpgraph"}, + {".dra", "audio/vnd.dra"}, + {".dfac", "application/vnd.dreamfactory"}, + {".dts", "audio/vnd.dts"}, + {".dtshd", "audio/vnd.dts.hd"}, + {".dwg", "image/vnd.dwg"}, + {".geo", "application/vnd.dynageo"}, + {".es", "application/ecmascript"}, + {".mag", "application/vnd.ecowin.chart"}, + {".mmr", "image/vnd.fujixerox.edmics-mmr"}, + {".rlc", "image/vnd.fujixerox.edmics-rlc"}, + {".exi", "application/exi"}, + {".mgz", "application/vnd.proteus.magazine"}, + {".epub", "application/epub+zip"}, + {".eml", "message/rfc822"}, + {".nml", "application/vnd.enliven"}, + {".xpr", "application/vnd.is-xpr"}, + {".xif", "image/vnd.xiff"}, + {".xfdl", "application/vnd.xfdl"}, + {".emma", "application/emma+xml"}, + {".ez2", "application/vnd.ezpix-album"}, + {".ez3", "application/vnd.ezpix-package"}, + {".fst", "image/vnd.fst"}, + {".fvt", "video/vnd.fvt"}, + {".fbs", "image/vnd.fastbidsheet"}, + {".fe_launch", "application/vnd.denovo.fcselayout-link"}, + {".f4v", "video/x-f4v"}, + {".flv", "video/x-flv"}, + {".fpx", "image/vnd.fpx"}, + {".npx", "image/vnd.net-fpx"}, + {".flx", "text/vnd.fmi.flexstor"}, + {".fli", "video/x-fli"}, + {".ftc", "application/vnd.fluxtime.clip"}, + {".fdf", "application/vnd.fdf"}, + {".f", "text/x-fortran"}, + {".mif", "application/vnd.mif"}, + {".fm", "application/vnd.framemaker"}, + {".fh", "image/x-freehand"}, + {".fsc", "application/vnd.fsc.weblaunch"}, + {".fnc", "application/vnd.frogans.fnc"}, + {".ltf", "application/vnd.frogans.ltf"}, + {".ddd", "application/vnd.fujixerox.ddd"}, + {".xdw", "application/vnd.fujixerox.docuworks"}, + {".xbd", "application/vnd.fujixerox.docuworks.binder"}, + {".oas", "application/vnd.fujitsu.oasys"}, + {".oa2", "application/vnd.fujitsu.oasys2"}, + {".oa3", "application/vnd.fujitsu.oasys3"}, + {".fg5", "application/vnd.fujitsu.oasysgp"}, + {".bh2", "application/vnd.fujitsu.oasysprs"}, + {".spl", "application/x-futuresplash"}, + {".fzs", "application/vnd.fuzzysheet"}, + {".g3", "image/g3fax"}, + {".gmx", "application/vnd.gmx"}, + {".gtw", "model/vnd.gtw"}, + {".txd", "application/vnd.genomatix.tuxedo"}, + {".ggb", "application/vnd.geogebra.file"}, + {".ggt", "application/vnd.geogebra.tool"}, + {".gdl", "model/vnd.gdl"}, + {".gex", "application/vnd.geometry-explorer"}, + {".gxt", "application/vnd.geonext"}, + {".g2w", "application/vnd.geoplan"}, + {".g3w", "application/vnd.geospace"}, + {".gsf", "application/x-font-ghostscript"}, + {".bdf", "application/x-font-bdf"}, + {".gtar", "application/x-gtar"}, + {".texinfo", "application/x-texinfo"}, + {".gnumeric", "application/x-gnumeric"}, + {".kml", "application/vnd.google-earth.kml+xml"}, + {".kmz", "application/vnd.google-earth.kmz"}, + {".gqf", "application/vnd.grafeq"}, + {".gif", "image/gif"}, + {".gv", "text/vnd.graphviz"}, + {".gac", "application/vnd.groove-account"}, + {".ghf", "application/vnd.groove-help"}, + {".gim", "application/vnd.groove-identity-message"}, + {".grv", "application/vnd.groove-injector"}, + {".gtm", "application/vnd.groove-tool-message"}, + {".tpl", "application/vnd.groove-tool-template"}, + {".vcg", "application/vnd.groove-vcard"}, + {".h261", "video/h261"}, + {".h263", "video/h263"}, + {".h264", "video/h264"}, + {".hpid", "application/vnd.hp-hpid"}, + {".hps", "application/vnd.hp-hps"}, + {".hdf", "application/x-hdf"}, + {".rip", "audio/vnd.rip"}, + {".hbci", "application/vnd.hbci"}, + {".jlt", "application/vnd.hp-jlyt"}, + {".pcl", "application/vnd.hp-pcl"}, + {".hpgl", "application/vnd.hp-hpgl"}, + {".hvs", "application/vnd.yamaha.hv-script"}, + {".hvd", "application/vnd.yamaha.hv-dic"}, + {".hvp", "application/vnd.yamaha.hv-voice"}, + {".sfd-hdstx", "application/vnd.hydrostatix.sof-data"}, + {".stk", "application/hyperstudio"}, + {".hal", "application/vnd.hal+xml"}, + {".htm", "text/html; charset=utf-8"}, + {".html", "text/html; charset=utf-8"}, + {".irm", "application/vnd.ibm.rights-management"}, + {".sc", "application/vnd.ibm.secure-container"}, + {".ics", "text/calendar"}, + {".icc", "application/vnd.iccprofile"}, + {".ico", "image/x-icon"}, + {".igl", "application/vnd.igloader"}, + {".ief", "image/ief"}, + {".ivp", "application/vnd.immervision-ivp"}, + {".ivu", "application/vnd.immervision-ivu"}, + {".rif", "application/reginfo+xml"}, + {".3dml", "text/vnd.in3d.3dml"}, + {".spot", "text/vnd.in3d.spot"}, + {".igs", "model/iges"}, + {".i2g", "application/vnd.intergeo"}, + {".cdy", "application/vnd.cinderella"}, + {".xpw", "application/vnd.intercon.formnet"}, + {".fcs", "application/vnd.isac.fcs"}, + {".ipfix", "application/ipfix"}, + {".cer", "application/pkix-cert"}, + {".pki", "application/pkixcmp"}, + {".crl", "application/pkix-crl"}, + {".pkipath", "application/pkix-pkipath"}, + {".igm", "application/vnd.insors.igm"}, + {".rcprofile", "application/vnd.ipunplugged.rcprofile"}, + {".irp", "application/vnd.irepository.package+xml"}, + {".jad", "text/vnd.sun.j2me.app-descriptor"}, + {".jar", "application/java-archive"}, + {".class", "application/java-vm"}, + {".jnlp", "application/x-java-jnlp-file"}, + {".ser", "application/java-serialized-object"}, + {".java", "text/x-java-source"}, + {".js", "application/javascript"}, + {".json", "application/json"}, + {".joda", "application/vnd.joost.joda-archive"}, + {".jpm", "video/jpm"}, + {".jpg", "image/jpeg"}, + {".jpeg", "image/jpeg"}, + {".pjpeg", "image/pjpeg"}, + {".jpgv", "video/jpeg"}, + {".ktz", "application/vnd.kahootz"}, + {".mmd", "application/vnd.chipnuts.karaoke-mmd"}, + {".karbon", "application/vnd.kde.karbon"}, + {".chrt", "application/vnd.kde.kchart"}, + {".kfo", "application/vnd.kde.kformula"}, + {".flw", "application/vnd.kde.kivio"}, + {".kon", "application/vnd.kde.kontour"}, + {".kpr", "application/vnd.kde.kpresenter"}, + {".ksp", "application/vnd.kde.kspread"}, + {".kwd", "application/vnd.kde.kword"}, + {".htke", "application/vnd.kenameaapp"}, + {".kia", "application/vnd.kidspiration"}, + {".kne", "application/vnd.kinar"}, + {".sse", "application/vnd.kodak-descriptor"}, + {".lasxml", "application/vnd.las.las+xml"}, + {".latex", "application/x-latex"}, + {".lbd", "application/vnd.llamagraphics.life-balance.desktop"}, + {".lbe", "application/vnd.llamagraphics.life-balance.exchange+xml"}, + {".jam", "application/vnd.jam"}, + {"0.123", "application/vnd.lotus-1-2-3"}, + {".apr", "application/vnd.lotus-approach"}, + {".pre", "application/vnd.lotus-freelance"}, + {".nsf", "application/vnd.lotus-notes"}, + {".org", "application/vnd.lotus-organizer"}, + {".scm", "application/vnd.lotus-screencam"}, + {".lwp", "application/vnd.lotus-wordpro"}, + {".lvp", "audio/vnd.lucent.voice"}, + {".m3u", "audio/x-mpegurl"}, + {".m4v", "video/x-m4v"}, + {".hqx", "application/mac-binhex40"}, + {".portpkg", "application/vnd.macports.portpkg"}, + {".mgp", "application/vnd.osgeo.mapguide.package"}, + {".mrc", "application/marc"}, + {".mrcx", "application/marcxml+xml"}, + {".mxf", "application/mxf"}, + {".nbp", "application/vnd.wolfram.player"}, + {".ma", "application/mathematica"}, + {".mathml", "application/mathml+xml"}, + {".mbox", "application/mbox"}, + {".mc1", "application/vnd.medcalcdata"}, + {".mscml", "application/mediaservercontrol+xml"}, + {".cdkey", "application/vnd.mediastation.cdkey"}, + {".mwf", "application/vnd.mfer"}, + {".mfm", "application/vnd.mfmp"}, + {".msh", "model/mesh"}, + {".mads", "application/mads+xml"}, + {".mets", "application/mets+xml"}, + {".mods", "application/mods+xml"}, + {".meta4", "application/metalink4+xml"}, + {".mcd", "application/vnd.mcd"}, + {".flo", "application/vnd.micrografx.flo"}, + {".igx", "application/vnd.micrografx.igx"}, + {".es3", "application/vnd.eszigno3+xml"}, + {".mdb", "application/x-msaccess"}, + {".asf", "video/x-ms-asf"}, + {".exe", "application/x-msdownload"}, + {".cil", "application/vnd.ms-artgalry"}, + {".cab", "application/vnd.ms-cab-compressed"}, + {".ims", "application/vnd.ms-ims"}, + {".application", "application/x-ms-application"}, + {".clp", "application/x-msclip"}, + {".mdi", "image/vnd.ms-modi"}, + {".eot", "application/vnd.ms-fontobject"}, + {".xls", "application/vnd.ms-excel"}, + {".xlam", "application/vnd.ms-excel.addin.macroenabled.12"}, + {".xlsb", "application/vnd.ms-excel.sheet.binary.macroenabled.12"}, + {".xltm", "application/vnd.ms-excel.template.macroenabled.12"}, + {".xlsm", "application/vnd.ms-excel.sheet.macroenabled.12"}, + {".chm", "application/vnd.ms-htmlhelp"}, + {".crd", "application/x-mscardfile"}, + {".lrm", "application/vnd.ms-lrm"}, + {".mvb", "application/x-msmediaview"}, + {".mny", "application/x-msmoney"}, + {".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"}, + {".sldx", "application/vnd.openxmlformats-officedocument.presentationml.slide"}, + {".ppsx", "application/vnd.openxmlformats-officedocument.presentationml.slideshow"}, + {".potx", "application/vnd.openxmlformats-officedocument.presentationml.template"}, + {".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}, + {".xltx", "application/vnd.openxmlformats-officedocument.spreadsheetml.template"}, + {".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"}, + {".dotx", "application/vnd.openxmlformats-officedocument.wordprocessingml.template"}, + {".obd", "application/x-msbinder"}, + {".thmx", "application/vnd.ms-officetheme"}, + {".onetoc", "application/onenote"}, + {".pya", "audio/vnd.ms-playready.media.pya"}, + {".pyv", "video/vnd.ms-playready.media.pyv"}, + {".ppt", "application/vnd.ms-powerpoint"}, + {".ppam", "application/vnd.ms-powerpoint.addin.macroenabled.12"}, + {".sldm", "application/vnd.ms-powerpoint.slide.macroenabled.12"}, + {".pptm", "application/vnd.ms-powerpoint.presentation.macroenabled.12"}, + {".ppsm", "application/vnd.ms-powerpoint.slideshow.macroenabled.12"}, + {".potm", "application/vnd.ms-powerpoint.template.macroenabled.12"}, + {".mpp", "application/vnd.ms-project"}, + {".pub", "application/x-mspublisher"}, + {".scd", "application/x-msschedule"}, + {".xap", "application/x-silverlight-app"}, + {".stl", "application/vnd.ms-pki.stl"}, + {".cat", "application/vnd.ms-pki.seccat"}, + {".vsd", "application/vnd.visio"}, + {".vsdx", "application/vnd.visio2013"}, + {".wm", "video/x-ms-wm"}, + {".wma", "audio/x-ms-wma"}, + {".wax", "audio/x-ms-wax"}, + {".wmx", "video/x-ms-wmx"}, + {".wmd", "application/x-ms-wmd"}, + {".wpl", "application/vnd.ms-wpl"}, + {".wmz", "application/x-ms-wmz"}, + {".wmv", "video/x-ms-wmv"}, + {".wvx", "video/x-ms-wvx"}, + {".wmf", "application/x-msmetafile"}, + {".trm", "application/x-msterminal"}, + {".doc", "application/msword"}, + {".docm", "application/vnd.ms-word.document.macroenabled.12"}, + {".dotm", "application/vnd.ms-word.template.macroenabled.12"}, + {".wri", "application/x-mswrite"}, + {".wps", "application/vnd.ms-works"}, + {".xbap", "application/x-ms-xbap"}, + {".xps", "application/vnd.ms-xpsdocument"}, + {".mid", "audio/midi"}, + {".mpy", "application/vnd.ibm.minipay"}, + {".afp", "application/vnd.ibm.modcap"}, + {".rms", "application/vnd.jcp.javame.midlet-rms"}, + {".tmo", "application/vnd.tmobile-livetv"}, + {".prc", "application/x-mobipocket-ebook"}, + {".mbk", "application/vnd.mobius.mbk"}, + {".dis", "application/vnd.mobius.dis"}, + {".plc", "application/vnd.mobius.plc"}, + {".mqy", "application/vnd.mobius.mqy"}, + {".msl", "application/vnd.mobius.msl"}, + {".txf", "application/vnd.mobius.txf"}, + {".daf", "application/vnd.mobius.daf"}, + {".fly", "text/vnd.fly"}, + {".mpc", "application/vnd.mophun.certificate"}, + {".mpn", "application/vnd.mophun.application"}, + {".mj2", "video/mj2"}, + {".mpga", "audio/mpeg"}, + {".mxu", "video/vnd.mpegurl"}, + {".mpeg", "video/mpeg"}, + {".m21", "application/mp21"}, + {".mp4a", "audio/mp4"}, + {".mp4", "video/mp4"}, + {".mp4", "application/mp4"}, + {".m3u8", "application/vnd.apple.mpegurl"}, + {".mus", "application/vnd.musician"}, + {".msty", "application/vnd.muvee.style"}, + {".mxml", "application/xv+xml"}, + {".ngdat", "application/vnd.nokia.n-gage.data"}, + {".n-gage", "application/vnd.nokia.n-gage.symbian.install"}, + {".ncx", "application/x-dtbncx+xml"}, + {".nc", "application/x-netcdf"}, + {".nlu", "application/vnd.neurolanguage.nlu"}, + {".dna", "application/vnd.dna"}, + {".nnd", "application/vnd.noblenet-directory"}, + {".nns", "application/vnd.noblenet-sealer"}, + {".nnw", "application/vnd.noblenet-web"}, + {".rpst", "application/vnd.nokia.radio-preset"}, + {".rpss", "application/vnd.nokia.radio-presets"}, + {".n3", "text/n3"}, + {".edm", "application/vnd.novadigm.edm"}, + {".edx", "application/vnd.novadigm.edx"}, + {".ext", "application/vnd.novadigm.ext"}, + {".gph", "application/vnd.flographit"}, + {".ecelp4800", "audio/vnd.nuera.ecelp4800"}, + {".ecelp7470", "audio/vnd.nuera.ecelp7470"}, + {".ecelp9600", "audio/vnd.nuera.ecelp9600"}, + {".oda", "application/oda"}, + {".ogx", "application/ogg"}, + {".oga", "audio/ogg"}, + {".ogv", "video/ogg"}, + {".dd2", "application/vnd.oma.dd2+xml"}, + {".oth", "application/vnd.oasis.opendocument.text-web"}, + {".opf", "application/oebps-package+xml"}, + {".qbo", "application/vnd.intu.qbo"}, + {".oxt", "application/vnd.openofficeorg.extension"}, + {".osf", "application/vnd.yamaha.openscoreformat"}, + {".weba", "audio/webm"}, + {".webm", "video/webm"}, + {".odc", "application/vnd.oasis.opendocument.chart"}, + {".otc", "application/vnd.oasis.opendocument.chart-template"}, + {".odb", "application/vnd.oasis.opendocument.database"}, + {".odf", "application/vnd.oasis.opendocument.formula"}, + {".odft", "application/vnd.oasis.opendocument.formula-template"}, + {".odg", "application/vnd.oasis.opendocument.graphics"}, + {".otg", "application/vnd.oasis.opendocument.graphics-template"}, + {".odi", "application/vnd.oasis.opendocument.image"}, + {".oti", "application/vnd.oasis.opendocument.image-template"}, + {".odp", "application/vnd.oasis.opendocument.presentation"}, + {".otp", "application/vnd.oasis.opendocument.presentation-template"}, + {".ods", "application/vnd.oasis.opendocument.spreadsheet"}, + {".ots", "application/vnd.oasis.opendocument.spreadsheet-template"}, + {".odt", "application/vnd.oasis.opendocument.text"}, + {".odm", "application/vnd.oasis.opendocument.text-master"}, + {".ott", "application/vnd.oasis.opendocument.text-template"}, + {".ktx", "image/ktx"}, + {".sxc", "application/vnd.sun.xml.calc"}, + {".stc", "application/vnd.sun.xml.calc.template"}, + {".sxd", "application/vnd.sun.xml.draw"}, + {".std", "application/vnd.sun.xml.draw.template"}, + {".sxi", "application/vnd.sun.xml.impress"}, + {".sti", "application/vnd.sun.xml.impress.template"}, + {".sxm", "application/vnd.sun.xml.math"}, + {".sxw", "application/vnd.sun.xml.writer"}, + {".sxg", "application/vnd.sun.xml.writer.global"}, + {".stw", "application/vnd.sun.xml.writer.template"}, + {".otf", "application/x-font-otf"}, + {".osfpvg", "application/vnd.yamaha.openscoreformat.osfpvg+xml"}, + {".dp", "application/vnd.osgi.dp"}, + {".pdb", "application/vnd.palm"}, + {".p", "text/x-pascal"}, + {".paw", "application/vnd.pawaafile"}, + {".pclxl", "application/vnd.hp-pclxl"}, + {".efif", "application/vnd.picsel"}, + {".pcx", "image/x-pcx"}, + {".psd", "image/vnd.adobe.photoshop"}, + {".prf", "application/pics-rules"}, + {".pic", "image/x-pict"}, + {".chat", "application/x-chat"}, + {".p10", "application/pkcs10"}, + {".p12", "application/x-pkcs12"}, + {".p7m", "application/pkcs7-mime"}, + {".p7s", "application/pkcs7-signature"}, + {".p7r", "application/x-pkcs7-certreqresp"}, + {".p7b", "application/x-pkcs7-certificates"}, + {".p8", "application/pkcs8"}, + {".plf", "application/vnd.pocketlearn"}, + {".pnm", "image/x-portable-anymap"}, + {".pbm", "image/x-portable-bitmap"}, + {".pcf", "application/x-font-pcf"}, + {".pfr", "application/font-tdpfr"}, + {".pgn", "application/x-chess-pgn"}, + {".pgm", "image/x-portable-graymap"}, + {".png", "image/png"}, + {".png", "image/x-citrix-png"}, + {".png", "image/x-png"}, + {".ppm", "image/x-portable-pixmap"}, + {".pskcxml", "application/pskc+xml"}, + {".pml", "application/vnd.ctc-posml"}, + {".ai", "application/postscript"}, + {".pfa", "application/x-font-type1"}, + {".pbd", "application/vnd.powerbuilder6"}, + {".pgp", "application/pgp-encrypted"}, + {".pgp", "application/pgp-signature"}, + {".box", "application/vnd.previewsystems.box"}, + {".ptid", "application/vnd.pvi.ptid1"}, + {".pls", "application/pls+xml"}, + {".str", "application/vnd.pg.format"}, + {".ei6", "application/vnd.pg.osasli"}, + {".dsc", "text/prs.lines.tag"}, + {".psf", "application/x-font-linux-psf"}, + {".qps", "application/vnd.publishare-delta-tree"}, + {".wg", "application/vnd.pmi.widget"}, + {".qxd", "application/vnd.quark.quarkxpress"}, + {".esf", "application/vnd.epson.esf"}, + {".msf", "application/vnd.epson.msf"}, + {".ssf", "application/vnd.epson.ssf"}, + {".qam", "application/vnd.epson.quickanime"}, + {".qfx", "application/vnd.intu.qfx"}, + {".qt", "video/quicktime"}, + {".rar", "application/x-rar-compressed"}, + {".ram", "audio/x-pn-realaudio"}, + {".rmp", "audio/x-pn-realaudio-plugin"}, + {".rsd", "application/rsd+xml"}, + {".rm", "application/vnd.rn-realmedia"}, + {".bed", "application/vnd.realvnc.bed"}, + {".mxl", "application/vnd.recordare.musicxml"}, + {".musicxml", "application/vnd.recordare.musicxml+xml"}, + {".rnc", "application/relax-ng-compact-syntax"}, + {".rdz", "application/vnd.data-vision.rdz"}, + {".rdf", "application/rdf+xml"}, + {".rp9", "application/vnd.cloanto.rp9"}, + {".jisp", "application/vnd.jisp"}, + {".rtf", "application/rtf"}, + {".rtx", "text/richtext"}, + {".link66", "application/vnd.route66.link66+xml"}, + {".rss", "application/rss+xml"}, + {".shf", "application/shf+xml"}, + {".st", "application/vnd.sailingtracker.track"}, + {".svg", "image/svg+xml"}, + {".sus", "application/vnd.sus-calendar"}, + {".sru", "application/sru+xml"}, + {".setpay", "application/set-payment-initiation"}, + {".setreg", "application/set-registration-initiation"}, + {".sema", "application/vnd.sema"}, + {".semd", "application/vnd.semd"}, + {".semf", "application/vnd.semf"}, + {".see", "application/vnd.seemail"}, + {".snf", "application/x-font-snf"}, + {".spq", "application/scvp-vp-request"}, + {".spp", "application/scvp-vp-response"}, + {".scq", "application/scvp-cv-request"}, + {".scs", "application/scvp-cv-response"}, + {".sdp", "application/sdp"}, + {".etx", "text/x-setext"}, + {".movie", "video/x-sgi-movie"}, + {".ifm", "application/vnd.shana.informed.formdata"}, + {".itp", "application/vnd.shana.informed.formtemplate"}, + {".iif", "application/vnd.shana.informed.interchange"}, + {".ipk", "application/vnd.shana.informed.package"}, + {".tfi", "application/thraud+xml"}, + {".shar", "application/x-shar"}, + {".rgb", "image/x-rgb"}, + {".slt", "application/vnd.epson.salt"}, + {".aso", "application/vnd.accpac.simply.aso"}, + {".imp", "application/vnd.accpac.simply.imp"}, + {".twd", "application/vnd.simtech-mindmapper"}, + {".csp", "application/vnd.commonspace"}, + {".saf", "application/vnd.yamaha.smaf-audio"}, + {".mmf", "application/vnd.smaf"}, + {".spf", "application/vnd.yamaha.smaf-phrase"}, + {".teacher", "application/vnd.smart.teacher"}, + {".svd", "application/vnd.svd"}, + {".rq", "application/sparql-query"}, + {".srx", "application/sparql-results+xml"}, + {".gram", "application/srgs"}, + {".grxml", "application/srgs+xml"}, + {".ssml", "application/ssml+xml"}, + {".skp", "application/vnd.koan"}, + {".sgml", "text/sgml"}, + {".sdc", "application/vnd.stardivision.calc"}, + {".sda", "application/vnd.stardivision.draw"}, + {".sdd", "application/vnd.stardivision.impress"}, + {".smf", "application/vnd.stardivision.math"}, + {".sdw", "application/vnd.stardivision.writer"}, + {".sgl", "application/vnd.stardivision.writer-global"}, + {".sm", "application/vnd.stepmania.stepchart"}, + {".sit", "application/x-stuffit"}, + {".sitx", "application/x-stuffitx"}, + {".sdkm", "application/vnd.solent.sdkm+xml"}, + {".xo", "application/vnd.olpc-sugar"}, + {".au", "audio/basic"}, + {".wqd", "application/vnd.wqd"}, + {".sis", "application/vnd.symbian.install"}, + {".smi", "application/smil+xml"}, + {".xsm", "application/vnd.syncml+xml"}, + {".bdm", "application/vnd.syncml.dm+wbxml"}, + {".xdm", "application/vnd.syncml.dm+xml"}, + {".sv4cpio", "application/x-sv4cpio"}, + {".sv4crc", "application/x-sv4crc"}, + {".sbml", "application/sbml+xml"}, + {".tsv", "text/tab-separated-values"}, + {".tiff", "image/tiff"}, + {".tao", "application/vnd.tao.intent-module-archive"}, + {".tar", "application/x-tar"}, + {".tcl", "application/x-tcl"}, + {".tex", "application/x-tex"}, + {".tfm", "application/x-tex-tfm"}, + {".tei", "application/tei+xml"}, + {".txt", "text/plain; charset=utf-8"}, + {".md", "text/markdown; charset=utf-8"}, + {".dxp", "application/vnd.spotfire.dxp"}, + {".sfs", "application/vnd.spotfire.sfs"}, + {".tsd", "application/timestamped-data"}, + {".tpt", "application/vnd.trid.tpt"}, + {".mxs", "application/vnd.triscape.mxs"}, + {".t", "text/troff"}, + {".tra", "application/vnd.trueapp"}, + {".ttf", "application/x-font-ttf"}, + {".ttl", "text/turtle"}, + {".umj", "application/vnd.umajin"}, + {".uoml", "application/vnd.uoml+xml"}, + {".unityweb", "application/vnd.unity"}, + {".ufd", "application/vnd.ufdl"}, + {".uri", "text/uri-list"}, + {".utz", "application/vnd.uiq.theme"}, + {".ustar", "application/x-ustar"}, + {".uu", "text/x-uuencode"}, + {".vcs", "text/x-vcalendar"}, + {".vcf", "text/x-vcard"}, + {".vcd", "application/x-cdlink"}, + {".vsf", "application/vnd.vsf"}, + {".wrl", "model/vrml"}, + {".vcx", "application/vnd.vcx"}, + {".mts", "model/vnd.mts"}, + {".vtu", "model/vnd.vtu"}, + {".vis", "application/vnd.visionary"}, + {".viv", "video/vnd.vivo"}, + {".ccxml", "application/ccxml+xml"}, + {".vxml", "application/voicexml+xml"}, + {".src", "application/x-wais-source"}, + {".wbxml", "application/vnd.wap.wbxml"}, + {".wbmp", "image/vnd.wap.wbmp"}, + {".wav", "audio/x-wav"}, + {".davmount", "application/davmount+xml"}, + {".woff", "application/x-font-woff"}, + {".wspolicy", "application/wspolicy+xml"}, + {".webp", "image/webp"}, + {".wtb", "application/vnd.webturbo"}, + {".wgt", "application/widget"}, + {".hlp", "application/winhlp"}, + {".wml", "text/vnd.wap.wml"}, + {".wmls", "text/vnd.wap.wmlscript"}, + {".wmlsc", "application/vnd.wap.wmlscriptc"}, + {".wpd", "application/vnd.wordperfect"}, + {".stf", "application/vnd.wt.stf"}, + {".wsdl", "application/wsdl+xml"}, + {".xbm", "image/x-xbitmap"}, + {".xpm", "image/x-xpixmap"}, + {".xwd", "image/x-xwindowdump"}, + {".der", "application/x-x509-ca-cert"}, + {".fig", "application/x-xfig"}, + {".xhtml", "application/xhtml+xml"}, + {".xml", "application/xml"}, + {".xdf", "application/xcap-diff+xml"}, + {".xenc", "application/xenc+xml"}, + {".xer", "application/patch-ops-error+xml"}, + {".rl", "application/resource-lists+xml"}, + {".rs", "application/rls-services+xml"}, + {".rld", "application/resource-lists-diff+xml"}, + {".xslt", "application/xslt+xml"}, + {".xop", "application/xop+xml"}, + {".xpi", "application/x-xpinstall"}, + {".xspf", "application/xspf+xml"}, + {".xul", "application/vnd.mozilla.xul+xml"}, + {".xyz", "chemical/x-xyz"}, + {".yaml", "text/yaml"}, + {".yang", "application/yang"}, + {".yin", "application/yin+xml"}, + {".zir", "application/vnd.zul"}, + {".zip", "application/zip"}, + {".zmm", "application/vnd.handheld-entertainment+xml"}, + {".zaz", "application/vnd.zzazz.deck+xml"}, +}; + +// Get HTTP MIME type from filename +char *GetMimeTypeFromFileName(char *filename) +{ + UINT i; + UINT num = sizeof(http_mime_types) / sizeof(HTTP_MIME_TYPE); + if (filename == NULL) + { + return NULL; + } + + for (i = 0;i < num;i++) + { + HTTP_MIME_TYPE *a = &http_mime_types[i]; + + if (EndWith(filename, a->Extension)) + { + return a->MimeType; + } + } + + return NULL; +} + // Download and save intermediate certificates if necessary bool DownloadAndSaveIntermediateCertificatesIfNecessary(X *x) { @@ -1260,6 +1980,7 @@ bool ServerAccept(CONNECTION *c) UINT authtype; POLICY *policy; UINT assigned_vlan_id = 0; + UCHAR assigned_ipc_mac_address[6]; HUB *hub; SESSION *s = NULL; UINT64 user_expires = 0; @@ -1268,12 +1989,17 @@ bool ServerAccept(CONNECTION *c) bool half_connection; UINT adjust_mss; bool use_udp_acceleration_client; + UINT client_udp_acceleration_max_version = 1; + UINT udp_acceleration_version = 1; + UINT client_rudp_bulk_max_version = 1; + UINT rudp_bulk_version = 1; bool support_hmac_on_udp_acceleration_client = false; bool support_udp_accel_fast_disconnect_detect; bool use_hmac_on_udp_acceleration = false; bool supress_return_pack_error = false; IP udp_acceleration_client_ip; - UCHAR udp_acceleration_client_key[UDP_ACCELERATION_COMMON_KEY_SIZE]; + UCHAR udp_acceleration_client_key[UDP_ACCELERATION_COMMON_KEY_SIZE_V1]; + UCHAR udp_acceleration_client_key_v2[UDP_ACCELERATION_COMMON_KEY_SIZE_V2]; UINT udp_acceleration_client_port; bool use_fast_rc4; bool admin_mode = false; @@ -1329,11 +2055,14 @@ bool ServerAccept(CONNECTION *c) Zero(ctoken_hash_str, sizeof(ctoken_hash_str)); + Zero(assigned_ipc_mac_address, sizeof(assigned_ipc_mac_address)); + Zero(mschap_v2_server_response_20, sizeof(mschap_v2_server_response_20)); Zero(&udp_acceleration_client_ip, sizeof(udp_acceleration_client_ip)); udp_acceleration_client_port = 0; Zero(udp_acceleration_client_key, sizeof(udp_acceleration_client_key)); + Zero(udp_acceleration_client_key_v2, sizeof(udp_acceleration_client_key_v2)); Zero(&winver, sizeof(winver)); @@ -1376,6 +2105,11 @@ bool ServerAccept(CONNECTION *c) error_detail_2 = NULL; if (ServerDownloadSignature(c, &error_detail_2) == false) { + if (c->Type == CONNECTION_TYPE_ADMIN_RPC) + { + c->Err = ERR_NO_ERROR; + } + if (error_detail_2 == NULL) { error_detail = "ServerDownloadSignature"; @@ -1639,6 +2373,16 @@ bool ServerAccept(CONNECTION *c) client_id = PackGetInt(p, "client_id"); adjust_mss = PackGetInt(p, "adjust_mss"); use_udp_acceleration_client = PackGetBool(p, "use_udp_acceleration"); + client_udp_acceleration_max_version = PackGetInt(p, "udp_acceleration_max_version"); + if (client_udp_acceleration_max_version == 0) + { + client_udp_acceleration_max_version = 1; + } + client_rudp_bulk_max_version = PackGetInt(p, "rudp_bulk_max_version"); + if (client_rudp_bulk_max_version == 0) + { + client_rudp_bulk_max_version = 1; + } support_hmac_on_udp_acceleration_client = PackGetBool(p, "support_hmac_on_udp_acceleration"); support_udp_accel_fast_disconnect_detect = PackGetBool(p, "support_udp_accel_fast_disconnect_detect"); support_bulk_on_rudp = PackGetBool(p, "support_bulk_on_rudp"); @@ -1659,6 +2403,7 @@ bool ServerAccept(CONNECTION *c) PackGetStr(p, "inproc_postfix", c->InProcPrefix, sizeof(c->InProcPrefix)); Zero(tmp, sizeof(tmp)); PackGetStr(p, "inproc_cryptname", tmp, sizeof(tmp)); + c->InProcLayer = PackGetInt(p, "inproc_layer"); if (c->FirstSock != NULL) { @@ -1666,6 +2411,10 @@ bool ServerAccept(CONNECTION *c) { Format(c->FirstSock->UnderlayProtocol, sizeof(c->FirstSock->UnderlayProtocol), SOCK_UNDERLAY_INPROC_EX, c->InProcPrefix); + + AddProtocolDetailsStr(c->FirstSock->UnderlayProtocol, + sizeof(c->FirstSock->UnderlayProtocol), + c->InProcPrefix); } } @@ -1683,6 +2432,9 @@ bool ServerAccept(CONNECTION *c) } use_udp_acceleration_client = false; + + Format(radius_login_opt.In_VpnProtocolState, sizeof(radius_login_opt.In_VpnProtocolState), + "L%u:%s", c->InProcLayer, c->InProcPrefix); } else { @@ -1696,12 +2448,15 @@ bool ServerAccept(CONNECTION *c) { c->CipherName = CopyStr(c->FirstSock->CipherName); } + + Format(radius_login_opt.In_VpnProtocolState, sizeof(radius_login_opt.In_VpnProtocolState), + "L%u:%s", IPC_LAYER_2, "SEVPN"); } if (support_bulk_on_rudp && c->FirstSock != NULL && c->FirstSock->IsRUDPSocket && c->FirstSock->BulkRecvKey != NULL && c->FirstSock->BulkSendKey != NULL) { - // RAllow UDP bulk transfer if the client side supports + // Allow UDP bulk transfer if the client side supports // in the case of using R-UDP Socket enable_bulk_on_rudp = true; @@ -1716,9 +2471,11 @@ bool ServerAccept(CONNECTION *c) if (use_udp_acceleration_client) { + PackGetData2(p, "udp_acceleration_client_key", udp_acceleration_client_key, UDP_ACCELERATION_COMMON_KEY_SIZE_V1); + PackGetData2(p, "udp_acceleration_client_key_v2", udp_acceleration_client_key_v2, UDP_ACCELERATION_COMMON_KEY_SIZE_V2); + // Get the parameters for the UDP acceleration function - if (PackGetIp(p, "udp_acceleration_client_ip", &udp_acceleration_client_ip) == false || - PackGetData2(p, "udp_acceleration_client_key", udp_acceleration_client_key, UDP_ACCELERATION_COMMON_KEY_SIZE) == false) + if (PackGetIp(p, "udp_acceleration_client_ip", &udp_acceleration_client_ip) == false) { use_udp_acceleration_client = false; } @@ -1786,6 +2543,9 @@ bool ServerAccept(CONNECTION *c) case AUTHTYPE_TICKET: authtype_str = _UU("LH_AUTH_TICKET"); break; + case AUTHTYPE_OPENVPN_CERT: + authtype_str = _UU("LH_AUTH_OPENVPN_CERT"); + break; } IPToStr(ip1, sizeof(ip1), &c->FirstSock->RemoteIP); IPToStr(ip2, sizeof(ip2), &c->FirstSock->LocalIP); @@ -2119,6 +2879,50 @@ bool ServerAccept(CONNECTION *c) } break; + case AUTHTYPE_OPENVPN_CERT: + // For OpenVPN; mostly same as CLIENT_AUTHTYPE_CERT, but without + // signature verification, because it was already performed during TLS handshake. + if (c->IsInProc) + { + // Certificate authentication + cert_size = PackGetDataSize(p, "cert"); + if (cert_size >= 1 && cert_size <= 100000) + { + cert_buf = ZeroMalloc(cert_size); + if (PackGetData(p, "cert", cert_buf)) + { + BUF *b = NewBuf(); + X *x; + WriteBuf(b, cert_buf, cert_size); + x = BufToX(b, false); + if (x != NULL && x->is_compatible_bit) + { + Debug("Got to SamAuthUserByCert %s\n", username); // XXX + // Check whether the certificate is valid. + auth_ret = SamAuthUserByCert(hub, username, x); + if (auth_ret) + { + // Copy the certificate + c->ClientX = CloneX(x); + } + } + FreeX(x); + FreeBuf(b); + } + Free(cert_buf); + } + } + else + { + // OpenVPN certificate authentication cannot be used directly by external clients + Unlock(hub->lock); + ReleaseHub(hub); + FreePack(p); + c->Err = ERR_AUTHTYPE_NOT_SUPPORTED; + goto CLEANUP; + } + break; + default: // Unknown authentication method Unlock(hub->lock); @@ -2206,6 +3010,12 @@ bool ServerAccept(CONNECTION *c) } } + // Check the assigned MAC Address + if (radius_login_opt.Out_IsRadiusLogin) + { + Copy(assigned_ipc_mac_address, radius_login_opt.Out_VirtualMacAddress, 6); + } + if (StrCmpi(username, ADMINISTRATOR_USERNAME) != 0) { // Get the policy @@ -2892,15 +3702,16 @@ bool ServerAccept(CONNECTION *c) // VLAN ID if (assigned_vlan_id != 0) { - if (policy->VLanId == 0) - { - policy->VLanId = assigned_vlan_id; - } + if (policy->VLanId == 0) + { + policy->VLanId = assigned_vlan_id; } + } // Create a Session StrLower(username); - s = NewServerSessionEx(c->Cedar, c, hub, username, policy, c->IsInProc); + s = NewServerSessionEx(c->Cedar, c, hub, username, policy, c->IsInProc, + (c->IsInProc && IsZero(assigned_ipc_mac_address, 6) == false) ? assigned_ipc_mac_address : NULL); s->EnableUdpRecovery = enable_udp_recovery; s->LocalHostSession = local_host_session; @@ -2914,6 +3725,8 @@ bool ServerAccept(CONNECTION *c) s->IsRUDPSession = true; s->RUdpMss = c->FirstSock->RUDP_OptimizedMss; Debug("Optimized MSS Value for R-UDP: %u\n", s->RUdpMss); + AddProtocolDetailsKeyValueInt(s->ProtocolDetails, sizeof(s->ProtocolDetails), + "RUDP_MSS", s->RUdpMss); } if (enable_bulk_on_rudp) @@ -2927,6 +3740,8 @@ bool ServerAccept(CONNECTION *c) StrCpy(s->UnderlayProtocol, sizeof(s->UnderlayProtocol), c->FirstSock->UnderlayProtocol); + AddProtocolDetailsStr(s->ProtocolDetails, sizeof(s->ProtocolDetails), c->FirstSock->ProtocolDetails); + if (server != NULL) { s->NoSendSignature = server->NoSendSignature; @@ -2955,6 +3770,28 @@ bool ServerAccept(CONNECTION *c) s->UseUdpAcceleration = true; s->UdpAccelFastDisconnectDetect = support_udp_accel_fast_disconnect_detect; + + // TODO: determine UDP Accel version + udp_acceleration_version = 1; + if (client_udp_acceleration_max_version >= 2) + { + udp_acceleration_version = 2; + } + } + + // TODO: determine RUDP Bulk version + if (client_rudp_bulk_max_version >= 2) + { + rudp_bulk_version = 2; + } + + s->BulkOnRUDPVersion = rudp_bulk_version; + + if (s->EnableBulkOnRUDP) + { + AddProtocolDetailsKeyValueInt(s->ProtocolDetails, sizeof(s->ProtocolDetails), + "RUDP_Bulk_Ver", + s->BulkOnRUDPVersion); } if (hub->Option != NULL && hub->Option->DisableUdpAcceleration) @@ -2978,6 +3815,7 @@ bool ServerAccept(CONNECTION *c) Debug("UseUdpAcceleration = %u\n", s->UseUdpAcceleration); Debug("UseHMacOnUdpAcceleration = %u\n", s->UseHMacOnUdpAcceleration); + Debug("UdpAccelerationVersion = %u\n", s->UdpAccelerationVersion); if (s->UseUdpAcceleration) { @@ -2993,7 +3831,11 @@ bool ServerAccept(CONNECTION *c) } else { - if (UdpAccelInitServer(s->UdpAccel, udp_acceleration_client_key, &udp_acceleration_client_ip, udp_acceleration_client_port, + s->UdpAccel->Version = udp_acceleration_version; + + if (UdpAccelInitServer(s->UdpAccel, + s->UdpAccel->Version == 2 ? udp_acceleration_client_key_v2 : udp_acceleration_client_key, + &udp_acceleration_client_ip, udp_acceleration_client_port, &c->FirstSock->RemoteIP) == false) { Debug("UdpAccelInitServer Failed.\n"); @@ -3008,6 +3850,21 @@ bool ServerAccept(CONNECTION *c) } s->UdpAccel->UseHMac = s->UseHMacOnUdpAcceleration; + + AddProtocolDetailsKeyValueInt(s->ProtocolDetails, sizeof(s->ProtocolDetails), + "UDPAccel_Ver", + s->UdpAccel->Version); + + if (s->UdpAccel->Version >= 2) + { + AddProtocolDetailsStr(s->ProtocolDetails, sizeof(s->ProtocolDetails), + Aead_ChaCha20Poly1305_Ietf_IsOpenSSL() ? + "ChachaPoly_OpenSSL" : "ChachaPoly_Self"); + } + + AddProtocolDetailsKeyValueInt(s->ProtocolDetails, sizeof(s->ProtocolDetails), + "UDPAccel_MSS", + UdpAccelCalcMss(s->UdpAccel)); } } @@ -3018,6 +3875,8 @@ bool ServerAccept(CONNECTION *c) if (s->AdjustMss != 0) { Debug("AdjustMSS: %u\n", s->AdjustMss); + AddProtocolDetailsKeyValueInt(s->ProtocolDetails, sizeof(s->ProtocolDetails), + "AdjustMSS", s->AdjustMss); } s->IsBridgeMode = (policy->NoBridge == false) || (policy->NoRouting == false); @@ -3064,7 +3923,8 @@ bool ServerAccept(CONNECTION *c) char ip[128]; IPToStr(ip, sizeof(ip), &c->FirstSock->RemoteIP); HLog(hub, "LH_NEW_SESSION", c->Name, s->Name, ip, c->FirstSock->RemotePort, - c->FirstSock->UnderlayProtocol); + c->FirstSock->UnderlayProtocol, + c->FirstSock->ProtocolDetails); } c->Session = s; @@ -3088,7 +3948,7 @@ bool ServerAccept(CONNECTION *c) s->QoS = qos; s->NoReconnectToSession = no_reconnect_to_session; - s->VLanId = policy->VLanId; + s->VLanId = policy->VLanId; // User name s->Username = CopyStr(username); @@ -3489,6 +4349,30 @@ bool ServerAccept(CONNECTION *c) // Add the socket of this connection to the connection list of the session (TCP) sock = c->FirstSock; + + if (sock->IsRUDPSocket && sock->BulkRecvKey != NULL && sock->BulkSendKey != NULL) + { + if (s->BulkRecvKeySize != 0 && s->BulkSendKeySize != 0) + { + // Restore R-UDP bulk send/recv keys for additional connections + Copy(sock->BulkRecvKey->Data, s->BulkRecvKey, s->BulkRecvKeySize); + sock->BulkRecvKey->Size = s->BulkRecvKeySize; + Copy(sock->BulkSendKey->Data, s->BulkSendKey, s->BulkSendKeySize); + sock->BulkSendKey->Size = s->BulkSendKeySize; + + if (false) + { + char tmp1[128]; + char tmp2[128]; + BinToStr(tmp1, sizeof(tmp1), s->BulkRecvKey, s->BulkRecvKeySize); + BinToStr(tmp2, sizeof(tmp2), s->BulkSendKey, s->BulkSendKeySize); + Debug("Restore: s->BulkRecvKey->Size = %u, s->BulkSendKey->Size = %u\n", + s->BulkRecvKeySize, s->BulkSendKeySize); + Debug("Restore:\n%s\n%s\n\n", tmp1, tmp2); + } + } + } + ts = NewTcpSock(sock); SetTimeout(sock, CONNECTING_TIMEOUT); direction = TCP_BOTH; @@ -4393,6 +5277,30 @@ bool ClientAdditionalConnect(CONNECTION *c, THREAD *t) Debug("Additional Connect Succeed!\n"); + if (s->IsRUDPSocket && s->BulkRecvKey != NULL && s->BulkSendKey != NULL) + { + // Restore R-UDP bulk send/recv keys for additional connections + if (c->Session->BulkRecvKeySize != 0 && c->Session->BulkSendKeySize != 0) + { + Copy(s->BulkRecvKey->Data, c->Session->BulkRecvKey, c->Session->BulkRecvKeySize); + s->BulkRecvKey->Size = c->Session->BulkRecvKeySize; + + Copy(s->BulkSendKey->Data, c->Session->BulkSendKey, c->Session->BulkSendKeySize); + s->BulkSendKey->Size = c->Session->BulkSendKeySize; + + if (false) + { + char tmp1[128]; + char tmp2[128]; + BinToStr(tmp1, sizeof(tmp1), s->BulkRecvKey->Data, s->BulkRecvKey->Size); + BinToStr(tmp2, sizeof(tmp2), s->BulkSendKey->Data, s->BulkSendKey->Size); + Debug("Restore: s->BulkRecvKey->Size = %u, s->BulkSendKey->Size = %u\n", + s->BulkRecvKey->Size, s->BulkSendKey->Size); + Debug("Restore:\n%s\n%s\n\n", tmp1, tmp2); + } + } + } + // Success the additional connection // Add to the TcpSockList of the connection ts = NewTcpSock(s); @@ -5128,9 +6036,14 @@ REDIRECTED: // Physical communication protocol StrCpy(c->Session->UnderlayProtocol, sizeof(c->Session->UnderlayProtocol), s->UnderlayProtocol); + AddProtocolDetailsStr(c->Session->ProtocolDetails, sizeof(c->Session->ProtocolDetails), s->ProtocolDetails); + if (c->Session->IsAzureSession) { StrCpy(c->Session->UnderlayProtocol, sizeof(c->Session->UnderlayProtocol), SOCK_UNDERLAY_AZURE); + + AddProtocolDetailsStr(c->Session->ProtocolDetails, sizeof(c->Session->ProtocolDetails), + "VPNAzure"); } if (c->Protocol == CONNECTION_UDP) @@ -5174,28 +6087,62 @@ REDIRECTED: if (s != NULL && s->IsRUDPSocket && s->BulkRecvKey != NULL && s->BulkSendKey != NULL) { // Bulk transfer on R-UDP + sess->EnableHMacOnBulkOfRUDP = PackGetBool(p, "enable_hmac_on_bulk_of_rudp"); + sess->BulkOnRUDPVersion = PackGetInt(p, "rudp_bulk_version"); + if (PackGetBool(p, "enable_bulk_on_rudp")) { // Receive the key - UCHAR key_send[SHA1_SIZE]; - UCHAR key_recv[SHA1_SIZE]; + UCHAR key_send[RUDP_BULK_KEY_SIZE_MAX]; + UCHAR key_recv[RUDP_BULK_KEY_SIZE_MAX]; - if (PackGetData2(p, "bulk_on_rudp_send_key", key_send, SHA1_SIZE) && - PackGetData2(p, "bulk_on_rudp_recv_key", key_recv, SHA1_SIZE)) + UINT key_size = SHA1_SIZE; + + if (sess->BulkOnRUDPVersion == 2) + { + key_size = RUDP_BULK_KEY_SIZE_V2; + } + + if (PackGetData2(p, "bulk_on_rudp_send_key", key_send, key_size) && + PackGetData2(p, "bulk_on_rudp_recv_key", key_recv, key_size)) { sess->EnableBulkOnRUDP = true; - Copy(s->BulkSendKey->Data, key_send, SHA1_SIZE); - Copy(s->BulkRecvKey->Data, key_recv, SHA1_SIZE); + Copy(s->BulkSendKey->Data, key_send, key_size); + Copy(s->BulkRecvKey->Data, key_recv, key_size); + + s->BulkSendKey->Size = key_size; + s->BulkRecvKey->Size = key_size; + + // Backup R-UDP bulk send/recv keys for additional connections + Copy(sess->BulkSendKey, s->BulkSendKey->Data, s->BulkSendKey->Size); + sess->BulkSendKeySize = s->BulkSendKey->Size; + + Copy(sess->BulkRecvKey, s->BulkRecvKey->Data, s->BulkRecvKey->Size); + sess->BulkRecvKeySize = s->BulkRecvKey->Size; + + if (false) + { + char tmp1[128]; + char tmp2[128]; + BinToStr(tmp1, sizeof(tmp1), sess->BulkRecvKey, sess->BulkSendKeySize); + BinToStr(tmp2, sizeof(tmp2), sess->BulkSendKey, sess->BulkRecvKeySize); + Debug("Backup: sess->BulkRecvKeySize = %u, sess->BulkSendKeySize = %u\n", + sess->BulkRecvKeySize, sess->BulkSendKeySize); + Debug("Backup:\n%s\n%s\n\n", tmp1, tmp2); + } + + AddProtocolDetailsKeyValueInt(sess->ProtocolDetails, sizeof(sess->ProtocolDetails), + "RUDP_Bulk_Ver", + sess->BulkOnRUDPVersion); } } - - sess->EnableHMacOnBulkOfRUDP = PackGetBool(p, "enable_hmac_on_bulk_of_rudp"); } Debug("EnableBulkOnRUDP = %u\n", sess->EnableBulkOnRUDP); Debug("EnableHMacOnBulkOfRUDP = %u\n", sess->EnableHMacOnBulkOfRUDP); Debug("EnableUdpRecovery = %u\n", sess->EnableUdpRecovery); + Debug("BulkOnRUDPVersion = %u\n", sess->BulkOnRUDPVersion); sess->UseUdpAcceleration = false; sess->IsUsingUdpAcceleration = false; @@ -5209,8 +6156,14 @@ REDIRECTED: if (PackGetBool(p, "use_udp_acceleration")) { + UINT udp_acceleration_version = PackGetInt(p, "udp_acceleration_version"); IP udp_acceleration_server_ip; + if (udp_acceleration_version == 0) + { + udp_acceleration_version = 1; + } + sess->UdpAccelFastDisconnectDetect = PackGetBool(p, "udp_accel_fast_disconnect_detect"); if (PackGetIp(p, "udp_acceleration_server_ip", &udp_acceleration_server_ip)) @@ -5224,46 +6177,71 @@ REDIRECTED: if (udp_acceleration_server_port != 0) { - UCHAR udp_acceleration_server_key[UDP_ACCELERATION_COMMON_KEY_SIZE]; + UCHAR udp_acceleration_server_key[UDP_ACCELERATION_COMMON_KEY_SIZE_V1]; + UCHAR udp_acceleration_server_key_v2[UDP_ACCELERATION_COMMON_KEY_SIZE_V2]; + UINT server_cookie = PackGetInt(p, "udp_acceleration_server_cookie"); + UINT client_cookie = PackGetInt(p, "udp_acceleration_client_cookie"); + bool encryption = PackGetBool(p, "udp_acceleration_use_encryption"); - if (PackGetData2(p, "udp_acceleration_server_key", udp_acceleration_server_key, UDP_ACCELERATION_COMMON_KEY_SIZE)) + Zero(udp_acceleration_server_key, sizeof(udp_acceleration_server_key)); + Zero(udp_acceleration_server_key_v2, sizeof(udp_acceleration_server_key_v2)); + + PackGetData2(p, "udp_acceleration_server_key", udp_acceleration_server_key, UDP_ACCELERATION_COMMON_KEY_SIZE_V1); + PackGetData2(p, "udp_acceleration_server_key_v2", udp_acceleration_server_key_v2, UDP_ACCELERATION_COMMON_KEY_SIZE_V2); + + if (server_cookie != 0 && client_cookie != 0) { - UINT server_cookie = PackGetInt(p, "udp_acceleration_server_cookie"); - UINT client_cookie = PackGetInt(p, "udp_acceleration_client_cookie"); - bool encryption = PackGetBool(p, "udp_acceleration_use_encryption"); + IP remote_ip; - if (server_cookie != 0 && client_cookie != 0) + Copy(&remote_ip, &s->RemoteIP, sizeof(IP)); + + if (IsZeroIp(&c->Session->AzureRealServerGlobalIp) == false) { - IP remote_ip; + Copy(&remote_ip, &c->Session->AzureRealServerGlobalIp, sizeof(IP)); + } - Copy(&remote_ip, &s->RemoteIP, sizeof(IP)); + sess->UdpAccel->Version = 1; + if (udp_acceleration_version == 2) + { + sess->UdpAccel->Version = 2; + } - if (IsZeroIp(&c->Session->AzureRealServerGlobalIp) == false) + if (UdpAccelInitClient(sess->UdpAccel, + sess->UdpAccel->Version == 2 ? udp_acceleration_server_key_v2 : udp_acceleration_server_key, + &udp_acceleration_server_ip, udp_acceleration_server_port, + server_cookie, client_cookie, &remote_ip) == false) + { + Debug("UdpAccelInitClient failed.\n"); + } + else + { + sess->UseUdpAcceleration = true; + + sess->UdpAccel->FastDetect = sess->UdpAccelFastDisconnectDetect; + + sess->UdpAccel->PlainTextMode = !encryption; + + sess->UseHMacOnUdpAcceleration = PackGetBool(p, "use_hmac_on_udp_acceleration"); + + if (sess->UseHMacOnUdpAcceleration) { - Copy(&remote_ip, &c->Session->AzureRealServerGlobalIp, sizeof(IP)); + sess->UdpAccel->UseHMac = true; } - if (UdpAccelInitClient(sess->UdpAccel, udp_acceleration_server_key, - &udp_acceleration_server_ip, udp_acceleration_server_port, - server_cookie, client_cookie, &remote_ip) == false) + AddProtocolDetailsKeyValueInt(sess->ProtocolDetails, sizeof(sess->ProtocolDetails), + "UDPAccel_Ver", + sess->UdpAccel->Version); + + if (sess->UdpAccel->Version >= 2) { - Debug("UdpAccelInitClient failed.\n"); + AddProtocolDetailsStr(sess->ProtocolDetails, sizeof(sess->ProtocolDetails), + Aead_ChaCha20Poly1305_Ietf_IsOpenSSL() ? + "ChachaPoly_OpenSSL" : "ChachaPoly_Self"); } - else - { - sess->UseUdpAcceleration = true; - sess->UdpAccel->FastDetect = sess->UdpAccelFastDisconnectDetect; - - sess->UdpAccel->PlainTextMode = !encryption; - - sess->UseHMacOnUdpAcceleration = PackGetBool(p, "use_hmac_on_udp_acceleration"); - - if (sess->UseHMacOnUdpAcceleration) - { - sess->UdpAccel->UseHMac = true; - } - } + AddProtocolDetailsKeyValueInt(sess->ProtocolDetails, sizeof(sess->ProtocolDetails), + "UDPAccel_MSS", + UdpAccelCalcMss(sess->UdpAccel)); } } } @@ -5502,15 +6480,25 @@ PACK *PackWelcome(SESSION *s) // Virtual HUB name PackAddStr(p, "IpcHubName", s->Hub->Name); + + // Shared Buffer + s->IpcSessionSharedBuffer = NewSharedBuffer(NULL, sizeof(IPC_SESSION_SHARED_BUFFER_DATA)); + AddRef(s->IpcSessionSharedBuffer->Ref); + + s->IpcSessionShared = s->IpcSessionSharedBuffer->Data; + + PackAddInt64(p, "IpcSessionSharedBuffer", (UINT64)s->IpcSessionSharedBuffer); } if (s->UdpAccel != NULL) { // UDP acceleration function PackAddBool(p, "use_udp_acceleration", true); + PackAddInt(p, "udp_acceleration_version", s->UdpAccel->Version); PackAddIp(p, "udp_acceleration_server_ip", &s->UdpAccel->MyIp); PackAddInt(p, "udp_acceleration_server_port", s->UdpAccel->MyPort); - PackAddData(p, "udp_acceleration_server_key", s->UdpAccel->MyKey, UDP_ACCELERATION_COMMON_KEY_SIZE); + PackAddData(p, "udp_acceleration_server_key", s->UdpAccel->MyKey, UDP_ACCELERATION_COMMON_KEY_SIZE_V1); + PackAddData(p, "udp_acceleration_server_key_v2", s->UdpAccel->MyKey_V2, UDP_ACCELERATION_COMMON_KEY_SIZE_V2); PackAddInt(p, "udp_acceleration_server_cookie", s->UdpAccel->MyCookie); PackAddInt(p, "udp_acceleration_client_cookie", s->UdpAccel->YourCookie); PackAddBool(p, "udp_acceleration_use_encryption", !s->UdpAccel->PlainTextMode); @@ -5523,9 +6511,46 @@ PACK *PackWelcome(SESSION *s) // Allow bulk transfer on R-UDP PackAddBool(p, "enable_bulk_on_rudp", true); PackAddBool(p, "enable_hmac_on_bulk_of_rudp", s->EnableHMacOnBulkOfRUDP); + PackAddInt(p, "rudp_bulk_version", s->BulkOnRUDPVersion); - PackAddData(p, "bulk_on_rudp_send_key", s->Connection->FirstSock->BulkRecvKey->Data, SHA1_SIZE); - PackAddData(p, "bulk_on_rudp_recv_key", s->Connection->FirstSock->BulkSendKey->Data, SHA1_SIZE); + if (s->BulkOnRUDPVersion == 2) + { + PackAddData(p, "bulk_on_rudp_send_key", s->Connection->FirstSock->BulkRecvKey->Data, RUDP_BULK_KEY_SIZE_V2); + s->Connection->FirstSock->BulkRecvKey->Size = RUDP_BULK_KEY_SIZE_V2; + + PackAddData(p, "bulk_on_rudp_recv_key", s->Connection->FirstSock->BulkSendKey->Data, RUDP_BULK_KEY_SIZE_V2); + s->Connection->FirstSock->BulkSendKey->Size = RUDP_BULK_KEY_SIZE_V2; + } + else + { + PackAddData(p, "bulk_on_rudp_send_key", s->Connection->FirstSock->BulkRecvKey->Data, SHA1_SIZE); + s->Connection->FirstSock->BulkRecvKey->Size = SHA1_SIZE; + + PackAddData(p, "bulk_on_rudp_recv_key", s->Connection->FirstSock->BulkSendKey->Data, SHA1_SIZE); + s->Connection->FirstSock->BulkSendKey->Size = SHA1_SIZE; + } + + // Backup R-UDP bulk send/recv keys for additional connections + Copy(s->BulkSendKey, s->Connection->FirstSock->BulkSendKey->Data, + s->Connection->FirstSock->BulkSendKey->Size); + + s->BulkSendKeySize = s->Connection->FirstSock->BulkSendKey->Size; + + Copy(s->BulkRecvKey, s->Connection->FirstSock->BulkRecvKey->Data, + s->Connection->FirstSock->BulkRecvKey->Size); + + s->BulkRecvKeySize = s->Connection->FirstSock->BulkRecvKey->Size; + + if (false) + { + char tmp1[128]; + char tmp2[128]; + BinToStr(tmp1, sizeof(tmp1), s->BulkRecvKey, s->BulkSendKeySize); + BinToStr(tmp2, sizeof(tmp2), s->BulkSendKey, s->BulkRecvKeySize); + Debug("Backup: s->BulkRecvKeySize = %u, s->BulkSendKeySize = %u\n", + s->BulkRecvKeySize, s->BulkSendKeySize); + Debug("Backup:\n%s\n%s\n\n", tmp1, tmp2); + } } if (s->IsAzureSession) @@ -5544,11 +6569,11 @@ PACK *PackWelcome(SESSION *s) } #define PACK_ADD_POLICY_BOOL(name, value) \ - PackAddInt(p, "policy:" name, y->value == false ? 0 : 1) + PackAddBool(p, "policy:" name, y->value == false ? 0 : 1) #define PACK_ADD_POLICY_UINT(name, value) \ PackAddInt(p, "policy:" name, y->value) #define PACK_GET_POLICY_BOOL(name, value) \ - y->value = (PackGetInt(p, "policy:" name) == 0 ? false : true) + y->value = (PackGetBool(p, "policy:" name)) #define PACK_GET_POLICY_UINT(name, value) \ y->value = PackGetInt(p, "policy:" name) @@ -5902,6 +6927,8 @@ bool ClientUploadAuth(CONNECTION *c) PackAddBool(p, "use_udp_acceleration", true); + PackAddInt(p, "udp_acceleration_version", c->Session->UdpAccel->Version); + Copy(&my_ip, &c->Session->UdpAccel->MyIp, sizeof(IP)); if (IsLocalHostIP(&my_ip)) { @@ -5917,11 +6944,15 @@ bool ClientUploadAuth(CONNECTION *c) PackAddIp(p, "udp_acceleration_client_ip", &my_ip); PackAddInt(p, "udp_acceleration_client_port", c->Session->UdpAccel->MyPort); - PackAddData(p, "udp_acceleration_client_key", c->Session->UdpAccel->MyKey, UDP_ACCELERATION_COMMON_KEY_SIZE); + PackAddData(p, "udp_acceleration_client_key", c->Session->UdpAccel->MyKey, UDP_ACCELERATION_COMMON_KEY_SIZE_V1); + PackAddData(p, "udp_acceleration_client_key_v2", c->Session->UdpAccel->MyKey_V2, UDP_ACCELERATION_COMMON_KEY_SIZE_V2); PackAddBool(p, "support_hmac_on_udp_acceleration", true); PackAddBool(p, "support_udp_accel_fast_disconnect_detect", true); + PackAddInt(p, "udp_acceleration_max_version", 2); } + PackAddInt(p, "rudp_bulk_max_version", 2); + // Brand string for the connection limit { char *branded_ctos = _SS("BRANDED_C_TO_S"); @@ -6033,16 +7064,21 @@ bool ServerDownloadSignature(CONNECTION *c, char **error_detail_str) SERVER *server; char *vpn_http_target = HTTP_VPN_TARGET2; bool check_hostname = false; + bool disable_json_api = false; // Validate arguments if (c == NULL) { return false; } - - server = c->Cedar->Server; + disable_json_api = server->DisableJsonRpcWebApi; + + + + + s = c->FirstSock; while (true) @@ -6064,6 +7100,10 @@ bool ServerDownloadSignature(CONNECTION *c, char **error_detail_str) if (h == NULL) { c->Err = ERR_CLIENT_IS_NOT_VPN; + if (c->IsJsonRpc) + { + c->Err = ERR_DISCONNECTED; + } return false; } @@ -6099,6 +7139,43 @@ bool ServerDownloadSignature(CONNECTION *c, char **error_detail_str) { // Receive the data since it's POST data_size = GetContentLength(h); + + if (disable_json_api == false) + { + if (StrCmpi(h->Target, "/api") == 0 || StrCmpi(h->Target, "/api/") == 0) + { + c->IsJsonRpc = true; + c->Type = CONNECTION_TYPE_ADMIN_RPC; + + JsonRpcProcPost(c, s, h, data_size); + + FreeHttpHeader(h); + + if (c->JsonRpcAuthed) + { + num = 0; + } + + continue; + } + else if (StartWith(h->Target, "/admin")) + { + c->IsJsonRpc = true; + c->Type = CONNECTION_TYPE_ADMIN_RPC; + + AdminWebProcPost(c, s, h, data_size, h->Target); + + FreeHttpHeader(h); + + if (c->JsonRpcAuthed) + { + num = 0; + } + + continue; + } + } + if ((data_size > MAX_WATERMARK_SIZE || data_size < SizeOfWaterMark()) && (data_size != StrLen(HTTP_VPN_TARGET_POSTDATA))) { // Data is too large @@ -6131,7 +7208,7 @@ bool ServerDownloadSignature(CONNECTION *c, char **error_detail_str) { // Compare posted data with the WaterMark if ((data_size == StrLen(HTTP_VPN_TARGET_POSTDATA) && (Cmp(data, HTTP_VPN_TARGET_POSTDATA, data_size) == 0)) - || (Cmp(data, WaterMark, SizeOfWaterMark()) == 0)) + || ((data_size >= SizeOfWaterMark()) && Cmp(data, WaterMark, SizeOfWaterMark()) == 0)) { // Check the WaterMark Free(data); @@ -6147,6 +7224,25 @@ bool ServerDownloadSignature(CONNECTION *c, char **error_detail_str) } } } + else if (StrCmpi(h->Method, "OPTIONS") == 0) + { + if (disable_json_api == false) + { + if (StrCmpi(h->Target, "/api") == 0 || StrCmpi(h->Target, "/api/") == 0 || StartWith(h->Target, "/admin")) + { + c->IsJsonRpc = true; + c->Type = CONNECTION_TYPE_ADMIN_RPC; + + JsonRpcProcOptions(c, s, h, h->Target); + + FreeHttpHeader(h); + + num = 0; + + continue; + } + } + } else if (StrCmpi(h->Method, "SSTP_DUPLEX_POST") == 0 && (server->DisableSSTPServer == false || s->IsReverseAcceptedSocket ) && GetServerCapsBool(server, "b_support_sstp") && GetNoSstp() == false) @@ -6202,50 +7298,27 @@ bool ServerDownloadSignature(CONNECTION *c, char **error_detail_str) { // Root directory SERVER *s = c->Cedar->Server; - bool is_free = false; *error_detail_str = "HTTP_ROOT"; { - if (is_free == false) + BUF *b = ReadDump("|wwwroot\\index.html"); + + if (b != NULL) { - // Other than free version - HttpSendForbidden(c->FirstSock, h->Target, ""); + FreeHttpHeader(h); + h = NewHttpHeader("HTTP/1.1", "202", "OK"); + AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE4)); + AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive")); + AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE)); + + PostHttp(c->FirstSock, h, b->Buf, b->Size); + + FreeBuf(b); } else { - // Free version - BUF *b = ReadDump("|free.htm"); - - if (b != NULL) - { - char *src = ZeroMalloc(b->Size + 1); - UINT dst_size = b->Size * 2 + 64; - char *dst = ZeroMalloc(dst_size); - char host[MAX_PATH]; - char portstr[64]; - - GetMachineName(host, sizeof(host)); - ToStr(portstr, c->FirstSock->LocalPort); - - Copy(src, b->Buf, b->Size); - ReplaceStrEx(dst, dst_size, src, - "$HOST$", host, false); - ReplaceStrEx(dst, dst_size, dst, - "$PORT$", portstr, false); - - FreeHttpHeader(h); - h = NewHttpHeader("HTTP/1.1", "202", "OK"); - AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE4)); - AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive")); - AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE)); - PostHttp(c->FirstSock, h, dst, StrLen(dst)); - - Free(src); - Free(dst); - - FreeBuf(b); - } + HttpSendForbidden(c->FirstSock, h->Target, ""); } } } @@ -6305,6 +7378,56 @@ bool ServerDownloadSignature(CONNECTION *c, char **error_detail_str) } } + if (b == false) + { + if (disable_json_api == false) + { + if (StartWith(h->Target, "/api?") || StartWith(h->Target, "/api/") || StrCmpi(h->Target, "/api") == 0) + { + c->IsJsonRpc = true; + c->Type = CONNECTION_TYPE_ADMIN_RPC; + + JsonRpcProcGet(c, s, h, h->Target); + + if (c->JsonRpcAuthed) + { + num = 0; + } + + FreeHttpHeader(h); + + continue; + } + else if (StartWith(h->Target, "/admin")) + { + c->IsJsonRpc = true; + c->Type = CONNECTION_TYPE_ADMIN_RPC; + + AdminWebProcGet(c, s, h, h->Target); + + if (c->JsonRpcAuthed) + { + num = 0; + } + + FreeHttpHeader(h); + + continue; + } + } + + if (false) // TODO + { + if (StrCmpi(h->Target, "/mvpn") == 0 || StrCmpi(h->Target, "/mvpn/") == 0) + { + MvpnProcGet(c, s, h, h->Target); + + FreeHttpHeader(h); + continue; + } + } + } + if (b == false) { // Not Found @@ -6517,6 +7640,7 @@ SOCK *ClientConnectGetSocket(CONNECTION *c, bool additional_connect, bool no_tls if (s != NULL) { StrCpy(s->UnderlayProtocol, sizeof(s->UnderlayProtocol), SOCK_UNDERLAY_NAT_T); + AddProtocolDetailsStr(s->UnderlayProtocol, sizeof(s->UnderlayProtocol), "NAT-T"); } } if (s == NULL) @@ -7225,6 +8349,45 @@ PACK *PackLoginWithPlainPassword(char *hubname, char *username, void *plain_pass return p; } +// Generate a packet of OpenVPN certificate login +PACK *PackLoginWithOpenVPNCertificate(char *hubname, char *username, X *x) +{ + PACK *p; + char cn_username[128]; + BUF *cert_buf = NULL; + // Validate arguments + if (hubname == NULL || username == NULL || x == NULL) + { + return NULL; + } + + p = NewPack(); + PackAddStr(p, "method", "login"); + PackAddStr(p, "hubname", hubname); + + if (IsEmptyStr(username)) + { + if (x->subject_name == NULL) + { + return NULL; + } + UniToStr(cn_username, sizeof(cn_username), x->subject_name->CommonName); + PackAddStr(p, "username", cn_username); + } + else + { + PackAddStr(p, "username", username); + } + + PackAddInt(p, "authtype", AUTHTYPE_OPENVPN_CERT); + + cert_buf = XToBuf(x, false); + PackAddBuf(p, "cert", cert_buf); + FreeBuf(cert_buf); + + return p; +} + // Create a packet of password authentication login PACK *PackLoginWithPassword(char *hubname, char *username, void *secure_password) { @@ -7295,3 +8458,1429 @@ void GenerateRC4KeyPair(RC4_KEY_PAIR *k) Rand(k->ServerToClientKey, sizeof(k->ServerToClientKey)); } +// MVPN GET Procedure (WebSocket) +void MvpnProcGet(CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_target) +{ + HTTP_VALUE *req_upgrade; + HTTP_VALUE *req_version; + HTTP_VALUE *req_key; + char response_key[64]; + UINT client_ws_version = 0; + char *bad_request_body = "\r\nBad Request\r\n\r\n

Bad Request

\r\n

HTTP Error 400. The request is badly formed.

\r\n"; + if (c == NULL || s == NULL || h == NULL || url_target == NULL) + { + return; + } + + req_upgrade = GetHttpValue(h, "Upgrade"); + if (req_upgrade == NULL || StrCmpi(req_upgrade->Data, "websocket") != 0) + { + MvpnSendReply(s, 400, "Bad Request", bad_request_body, StrLen(bad_request_body), + NULL, NULL, NULL, h); + return; + } + + req_version = GetHttpValue(h, "Sec-WebSocket-Version"); + if (req_version != NULL) client_ws_version = ToInt(req_version->Data); + if (client_ws_version != 13) + { + MvpnSendReply(s, 400, "Bad Request", NULL, 0, + NULL, "Sec-WebSocket-Version", "13", h); + return; + } + + Zero(response_key, sizeof(response_key)); + req_key = GetHttpValue(h, "Sec-WebSocket-Key"); + if (req_key != NULL) + { + char tmp[MAX_SIZE]; + UCHAR hash[SHA1_SIZE]; + StrCpy(tmp, sizeof(tmp), req_key->Data); + StrCat(tmp, sizeof(tmp), "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); + HashSha1(hash, tmp, StrLen(tmp)); + B64_Encode(response_key, hash, SHA1_SIZE); + } + else + { + MvpnSendReply(s, 400, "Bad Request", NULL, 0, + NULL, "Sec-WebSocket-Version", "13", h); + return; + } + + MvpnSendReply(s, 101, "Switching Protocols", NULL, 0, NULL, + "Sec-WebSocket-Accept", response_key, h); + + MvpnAccept(c, s); +} + +// MVPN Send Reply +bool MvpnSendReply(SOCK *s, UINT status_code, char *status_string, UCHAR *data, UINT data_size, char *content_type, + char *add_header_name, char *add_header_value, HTTP_HEADER *request_headers) +{ + HTTP_HEADER *h; + char date_str[MAX_SIZE]; + char error_code_str[16]; + bool ret = false; + HTTP_VALUE *origin; + HTTP_VALUE *upgrade; + HTTP_VALUE *req_connection; + if (s == NULL || status_string == NULL || (data_size != 0 && data == NULL) || request_headers == NULL) + { + return false; + } + if (content_type == NULL) + { + content_type = "text/html; charset=utf-8"; + } + + req_connection = GetHttpValue(request_headers, "Connection"); + + ToStr(error_code_str, status_code); + GetHttpDateStr(date_str, sizeof(date_str), SystemTime64()); + + h = NewHttpHeader("HTTP/1.1", error_code_str, status_string); + + AddHttpValue(h, NewHttpValue("Cache-Control", "no-cache")); + if (data_size != 0) + { + AddHttpValue(h, NewHttpValue("Content-Type", content_type)); + } + AddHttpValue(h, NewHttpValue("Date", date_str)); + if (req_connection != NULL) + { + AddHttpValue(h, NewHttpValue("Connection", req_connection->Data)); + } + else + { + AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive")); + } + AddHttpValue(h, NewHttpValue("Access-Control-Allow-Headers", "content-type")); + AddHttpValue(h, NewHttpValue("Access-Control-Allow-Headers", "authorization")); + AddHttpValue(h, NewHttpValue("Access-Control-Allow-Headers", "x-websocket-extensions")); + AddHttpValue(h, NewHttpValue("Access-Control-Allow-Headers", "x-websocket-version")); + AddHttpValue(h, NewHttpValue("Access-Control-Allow-Headers", "x-websocket-protocol")); + AddHttpValue(h, NewHttpValue("Access-Control-Allow-Credentials", "true")); + + origin = GetHttpValue(request_headers, "Origin"); + if (origin != NULL) + { + AddHttpValue(h, NewHttpValue("Access-Control-Allow-Origin", origin->Data)); + } + + upgrade = GetHttpValue(request_headers, "Upgrade"); + if (upgrade != NULL) + { + AddHttpValue(h, NewHttpValue("Upgrade", upgrade->Data)); + } + + if (add_header_name != NULL && add_header_value != NULL) + { + AddHttpValue(h, NewHttpValue(add_header_name, add_header_value)); + } + + ret = PostHttp(s, h, data, data_size); + + FreeHttpHeader(h); + + return ret; +} + +// MVPN Accept +void MvpnAccept(CONNECTION *c, SOCK *s) +{ + WS *w; + UINT err; + if (c == NULL || s == NULL) + { + return; + } + + w = NewWs(s); + + err = MvpnDoAccept(c, w); + + //while (true) + //{ + // UINT r; + // Zero(data, sizeof(data)); + // r = WsRecvSyncAll(w, data, 7); + // if (!r) + // { + // break; + // } + // Print("WS_Recv: %s\n", data); + // r = WsSendSync(w, data, 7); + // if (!r) + // { + // break; + // } + // Print("WS_Send: %s\n", data); + //} + + ReleaseWs(w); +} + +// New WebSocket +WS *NewWs(SOCK *s) +{ + WS *w; + if (s == NULL) + { + return NULL; + } + + w = ZeroMalloc(sizeof(WS)); + + w->Ref = NewRef(); + + w->MaxBufferSize = MAX_BUFFERING_PACKET_SIZE; + w->Sock = s; + AddRef(w->Sock->ref); + + w->Wsp = NewWsp(); + + return w; +} + +// Release WebSocket +void ReleaseWs(WS *w) +{ + if (w == NULL) + { + return; + } + + if (Release(w->Ref) == 0) + { + CleanupWs(w); + } +} + +void CleanupWs(WS *w) +{ + if (w == NULL) + { + return; + } + + if (w->Sock != NULL) + { + Disconnect(w->Sock); + ReleaseSock(w->Sock); + } + + FreeWsp(w->Wsp); + + Free(w); +} + +// WebSocket: Send a frame in sync mode +bool WsSendSync(WS *w, void *data, UINT size) +{ + UCHAR *send_buf; + UINT send_buf_size; + if (size == 0) + { + return !w->Disconnected; + } + if (w == NULL || data == NULL) + { + return false; + } + if (w->Disconnected || w->Wsp->HasError) + { + Disconnect(w->Sock); + return false; + } + + WriteFifo(w->Wsp->AppSendFifo, data, size); + WspTry(w->Wsp); + if (w->Wsp->HasError == false) + { + send_buf = FifoPtr(w->Wsp->PhysicalSendFifo); + send_buf_size = FifoSize(w->Wsp->PhysicalSendFifo); + if (SendAll(w->Sock, send_buf, send_buf_size, w->Sock->SecureMode)) + { + ReadFifo(w->Wsp->PhysicalSendFifo, NULL, send_buf_size); + return true; + } + } + + w->Disconnected = true; + Disconnect(w->Sock); + + return false; +} + +// WebSocket: Send a frame in async mode +UINT WsSendAsync(WS *w, void *data, UINT size) +{ + bool disconnected = false; + UINT ret = 0; + if (size == 0) + { + return !w->Disconnected; + } + if (w == NULL || data == NULL) + { + return 0; + } + if (w->Disconnected || w->Wsp->HasError) + { + Disconnect(w->Sock); + return 0; + } + + if (FifoSize(w->Wsp->PhysicalSendFifo) > w->Wsp->MaxBufferSize) + { + return INFINITE; + } + + WriteFifo(w->Wsp->AppSendFifo, data, size); + + if (WsTrySendAsync(w) == false) + { + ret = 0; + } + else + { + ret = size; + } + + if (ret == 0) + { + w->Disconnected = true; + Disconnect(w->Sock); + } + + return ret; +} + +// WebSocket: Send buffered streams in async mode +bool WsTrySendAsync(WS *w) +{ + bool ret = false; + if (w == NULL) + { + return false; + } + if (w->Disconnected || w->Wsp->HasError) + { + Disconnect(w->Sock); + return false; + } + + WspTry(w->Wsp); + + if (w->Wsp->HasError == false) + { + while (true) + { + UINT send_size = FifoSize(w->Wsp->PhysicalSendFifo); + UINT r; + if (send_size == 0) + { + ret = true; + break; + } + + r = Send(w->Sock, FifoPtr(w->Wsp->PhysicalSendFifo), send_size, w->Sock->SecureMode); + + if (r == INFINITE) + { + ret = true; + break; + } + else if (r == 0) + { + ret = false; + break; + } + else + { + ReadFifo(w->Wsp->PhysicalSendFifo, NULL, r); + } + } + } + else + { + ret = false; + } + + if (ret == 0) + { + w->Disconnected = true; + Disconnect(w->Sock); + } + + return ret; +} + +// WebSocket: Receive a frame in async mode +UINT WsRecvAsync(WS *w, void *data, UINT size) +{ + bool disconnected = false; + UINT ret = 0; + if (w == NULL || data == NULL || size == 0) + { + return 0; + } + if (w->Disconnected || w->Wsp->HasError) + { + Disconnect(w->Sock); + return 0; + } + + // Receive all arrived data from the socket + while (FifoSize(w->Wsp->PhysicalRecvFifo) < w->MaxBufferSize) + { + UINT r; + + r = Recv(w->Sock, w->TmpBuf, sizeof(w->TmpBuf), w->Sock->SecureMode); + if (r == 0) + { + // Disconnected + disconnected = true; + break; + } + else if (r == INFINITE) + { + // Pending + break; + } + else + { + // Received some data + WriteFifo(w->Wsp->PhysicalRecvFifo, w->TmpBuf, r); + } + } + + if (disconnected == false) + { + UINT sz; + WspTry(w->Wsp); + if (w->Wsp->HasError) + { + disconnected = true; + } + else + { + sz = FifoSize(w->Wsp->AppRecvFifo); + if (sz >= 1) + { + if (sz > size) + { + sz = size; + } + ReadFifo(w->Wsp->AppRecvFifo, data, sz); + ret = sz; + } + else + { + ret = INFINITE; + } + } + } + + if (disconnected) + { + w->Disconnected = true; + Disconnect(w->Sock); + ret = 0; + } + + return ret; +} + +// WebSocket: Receive a frame in sync mode until fulfill the buffer +bool WsRecvSyncAll(WS *w, void *data, UINT size) +{ + UINT recv_size; + if (w == NULL || data == NULL || size == 0) + { + return false; + } + + recv_size = 0; + + while (true) + { + UINT sz, ret; + + sz = size - recv_size; + ret = WsRecvSync(w, (UCHAR *)data + recv_size, sz); + if (ret == 0) + { + return false; + } + recv_size += ret; + if (recv_size >= size) + { + return true; + } + } +} + +// WebSocket: Receive a frame in sync mode +UINT WsRecvSync(WS *w, void *data, UINT size) +{ + if (w == NULL || data == NULL || size == 0) + { + return 0; + } + if (w->Disconnected || w->Wsp->HasError) + { + Disconnect(w->Sock); + return 0; + } + + while (w->Disconnected == false || w->Wsp->HasError == false) + { + UINT r; + UINT sz; + WspTry(w->Wsp); + if (w->Wsp->HasError) + { + break; + } + sz = FifoSize(w->Wsp->AppRecvFifo); + if (sz >= 1) + { + if (sz > size) + { + sz = size; + } + ReadFifo(w->Wsp->AppRecvFifo, data, sz); + return sz; + } + r = Recv(w->Sock, w->TmpBuf, sizeof(w->TmpBuf), w->Sock->SecureMode); + if (r == 0) + { + break; + } + WriteFifo(w->Wsp->PhysicalRecvFifo, w->TmpBuf, r); + } + + w->Disconnected = true; + Disconnect(w->Sock); + + return 0; +} + +// New WebSocket protocol +WSP *NewWsp() +{ + WSP *p = ZeroMalloc(sizeof(WSP)); + + p->AppRecvFifo = NewFifo(); + p->AppSendFifo = NewFifo(); + p->PhysicalRecvFifo = NewFifo(); + p->PhysicalSendFifo = NewFifo(); + + p->MaxBufferSize = MAX_BUFFERING_PACKET_SIZE; + + return p; +} + +// Free WebSocket protocol +void FreeWsp(WSP *p) +{ + if (p == NULL) + { + return; + } + + ReleaseFifo(p->AppRecvFifo); + ReleaseFifo(p->AppSendFifo); + ReleaseFifo(p->PhysicalRecvFifo); + ReleaseFifo(p->PhysicalSendFifo); + + Free(p); +} + +// WebSocket protocol: Try to interpret send/recv buffers +void WspTry(WSP *p) +{ + if (p == NULL) + { + return; + } + + // Physical -> App + while (p->HasError == false) + { + UINT read_buffer_size; + BLOCK *b = WspTryRecvNextFrame(p, &read_buffer_size); + if (b == NULL) + { + // No more frames + break; + } + + if (b->Param1 == WS_OPCODE_CONTINUE || b->Param1 == WS_OPCODE_TEXT || b->Param1 == WS_OPCODE_BIN) + { + WriteFifo(p->AppRecvFifo, b->Buf, b->Size); + } + else if (b->Param1 == WS_OPCODE_PING) + { + if (FifoSize(p->PhysicalSendFifo) <= p->MaxBufferSize) + { + WspTrySendFrame(p, WS_OPCODE_PONG, b->Buf, b->Size); + } + } + else if (b->Param1 == WS_OPCODE_PONG) + { + } + else + { + // Error: disconnect + p->HasError = true; + } + + ReadFifo(p->PhysicalRecvFifo, NULL, read_buffer_size); + + FreeBlock(b); + } + + // App -> Physical + while (p->HasError == false) + { + UINT size; + UCHAR *data; + + size = FifoSize(p->AppSendFifo); + if (size == 0) + { + // No more data + break; + } + + if (size > WS_SEND_SINGLE_FRAGMENT_SIZE) + { + size = WS_SEND_SINGLE_FRAGMENT_SIZE; + } + data = FifoPtr(p->AppSendFifo); + + WspTrySendFrame(p, WS_OPCODE_BIN, data, size); + + ReadFifo(p->AppSendFifo, NULL, size); + } +} + +// WebSocket protocol: Try to send a single frame +void WspTrySendFrame(WSP *p, UCHAR opcode, void *data, UINT size) +{ + BUF *b; + UCHAR flag_and_opcode; + if (p == NULL || (size != 0 && data == NULL)) + { + return; + } + if (p->HasError) + { + return; + } + + b = NewBuf(); + + flag_and_opcode = 0x80 | (opcode & 0x0F); + WriteBufChar(b, flag_and_opcode); + + if (size <= 125) + { + WriteBufChar(b, size); + } + else if (size <= 65536) + { + WriteBufChar(b, 126); + WriteBufShort(b, size); + } + else + { + WriteBufChar(b, 127); + WriteBufInt64(b, size); + } + + WriteBuf(b, data, size); + + WriteFifo(p->PhysicalSendFifo, b->Buf, b->Size); + + FreeBuf(b); +} + +// WebSocket protocol: Try to receive a single frame +BLOCK *WspTryRecvNextFrame(WSP *p, UINT *read_buffer_size) +{ + BLOCK *b; + UCHAR *buf; + UCHAR *buf_pos0; + UINT sz; + UCHAR flag_and_opcode; + UCHAR mask_and_payload_len; + UCHAR mask_flag; + UINT payload_len; + UCHAR mask_key[4]; + UCHAR *ret_data; + if (p == NULL || read_buffer_size == NULL) + { + return NULL; + } + if (p->HasError) + { + return NULL; + } + + buf = buf_pos0 = FifoPtr(p->PhysicalRecvFifo); + sz = FifoSize(p->PhysicalRecvFifo); + + if (sz < 1) + { + return NULL; + } + flag_and_opcode = *buf; + buf += 1; + sz -= 1; + + if (sz < 1) + { + return NULL; + } + mask_and_payload_len = *buf; + buf += 1; + sz -= 1; + + mask_flag = mask_and_payload_len & 0x80; + payload_len = mask_and_payload_len & 0x7F; + if (payload_len == 126) + { + if (sz < sizeof(USHORT)) + { + return NULL; + } + payload_len = READ_USHORT(buf); + buf += sizeof(USHORT); + sz -= sizeof(USHORT); + } + else if (payload_len == 127) + { + UINT64 u64; + if (sz < sizeof(UINT64)) + { + return NULL; + } + u64 = READ_UINT64(buf); + buf += sizeof(UINT64); + sz -= sizeof(UINT64); + if (u64 > 0x7FFFFFFF) + { + p->HasError = true; + return NULL; + } + payload_len = (UINT)u64; + } + + if (payload_len > WS_MAX_PAYLOAD_LEN_PER_FRAME) + { + p->HasError = true; + return NULL; + } + + if (mask_flag) + { + if (sz < 4) + { + return NULL; + } + Copy(mask_key, buf, 4); + buf += 4; + sz -= 4; + } + + if (payload_len >= 1 && sz < payload_len) + { + return NULL; + } + + ret_data = Clone(buf, payload_len); + sz -= payload_len; + buf += payload_len; + + if (mask_flag) + { + UINT i; + for (i = 0;i < payload_len;i++) + { + ret_data[i] ^= mask_key[i % 4]; + } + } + + b = NewBlock(ret_data, payload_len, 0); + b->Param1 = (flag_and_opcode & 0xF); + + *read_buffer_size = (UINT)(buf - buf_pos0); + + return b; +} + +// WebSocket: Receive a PACK serialized with JSON +PACK *WsRecvPack(WS *w) +{ + USHORT us; + UINT size; + UCHAR *buf; + PACK *p = NULL; + if (w == NULL) + { + return NULL; + } + + if (WsRecvSyncAll(w, &us, sizeof(us))) + { + size = Endian16(us); + + buf = ZeroMalloc(size + 1); + + if (WsRecvSyncAll(w, buf, size)) + { + p = JsonStrToPack(buf); + } + + Free(buf); + } + + return p; +} + +// WebSocket: Send a PACK serialized with JSON +bool WsSendPack(WS *w, PACK *p) +{ + BUF *b; + char *json_str; + bool ret = false; + if (w == NULL || p == NULL) + { + return false; + } + + json_str = PackToJsonStr(p); + if (json_str == NULL) + { + return false; + } + + b = NewBuf(); + + WriteBufShort(b, StrLen(json_str)); + WriteBuf(b, json_str, StrLen(json_str)); + + ret = WsSendSync(w, b->Buf, b->Size); + + FreeBuf(b); + + Free(json_str); + + return ret; +} + +// WebSocket: new error pack +PACK *WsNewErrorPack(UINT err) +{ + PACK *p = NewPack(); + char *error_code_str = WsErrorCodeToString(err); + wchar_t *error_message = _E(err); + + PackAddStr(p, "Error", error_code_str); + PackAddUniStr(p, "ErrorMessage", error_message); + + return p; +} + +// MVPN: convert error code to string +char *WsErrorCodeToString(UINT err) +{ + char *ret = "e_unknown"; + switch (err) + { + case ERR_NO_ERROR: + ret = "ok"; + break; + case ERR_PROTOCOL_ERROR: + ret = "e_protocol"; + break; + case ERR_INTERNAL_ERROR: + ret = "e_internal"; + break; + case ERR_DISCONNECTED: + case ERR_AUTO_DISCONNECTED: + ret = "e_disconnected"; + break; + case ERR_ACCESS_DENIED: + ret = "e_access_denied"; + break; + case ERR_HUB_NOT_FOUND: + ret = "e_network_not_found"; + break; + case ERR_HUB_STOPPING: + ret = "e_network_disabled"; + break; + case ERR_AUTH_FAILED: + ret = "e_auth_failed"; + break; + case ERR_SESSION_TIMEOUT: + ret = "e_timeout"; + break; + case ERR_USER_CANCEL: + ret = "e_user_cancel"; + break; + case ERR_AUTHTYPE_NOT_SUPPORTED: + ret = "e_auth_method_not_supported"; + break; + case ERR_TOO_MANY_CONNECTION: + ret = "e_too_many_connection"; + break; + case ERR_HUB_IS_BUSY: + ret = "e_too_many_session"; + break; + case ERR_TOO_MANY_USER_SESSION: + ret = "e_too_many_user_session"; + break; + case ERR_OBJECT_NOT_FOUND: + ret = "e_object_not_found"; + break; + case ERR_NOT_SUPPORTED: + case ERR_NOT_SUPPORTED_AUTH_ON_OPENSOURCE: + ret = "e_not_supported"; + break; + case ERR_INVALID_PARAMETER: + ret = "e_invalid_parameter"; + break; + case ERR_NULL_PASSWORD_LOCAL_ONLY: + ret = "e_empty_password_local_only"; + break; + case ERR_MONITOR_MODE_DENIED: + ret = "e_mirror_mode_denied"; + break; + case ERR_BRIDGE_MODE_DENIED: + ret = "e_bridge_mode_denied"; + break; + case ERR_IP_ADDRESS_DENIED: + ret = "e_client_ip_address_denied"; + break; + case ERR_MSCHAP2_PASSWORD_NEED_RESET: + ret = "e_user_password_must_reset"; + break; + } + return ret; +} + +// MVPN processing a client +UINT MvpnDoAccept(CONNECTION *c, WS *w) +{ + UINT ret = ERR_INTERNAL_ERROR; + PACK *client_hello = NULL; + UINT client_ver = 0; + char client_impl[256]; + UCHAR client_nonce[128]; + char client_hub_name[MAX_HUBNAME_LEN + 1]; + UINT server_ver = 0; + char server_impl[256]; + UCHAR server_nonce[128]; + PACK *server_hello = NULL; + UINT auth_ret = ERR_INTERNAL_ERROR; + IPC *ipc = NULL; + UINT i; + UINT heartbeat_interval = 0; + UINT disconnect_timeout = 0; + bool use_udp_acceleration = false; + IP client_udp_acceleration_ip = {0}; + UINT client_udp_acceleration_port = 0; + UCHAR client_udp_acceleration_key[UDP_ACCELERATION_COMMON_KEY_SIZE_V2] = {0}; + UDP_ACCEL *udp_accel = NULL; + + if (c == NULL || w == NULL) + { + return ERR_INTERNAL_ERROR; + } + + Rand(server_nonce, sizeof(server_nonce)); + + // Phase 1: Receive a Client Hello packet + client_hello = WsRecvPack(w); + if (client_hello == NULL) + { + ret = ERR_PROTOCOL_ERROR; + goto LABEL_CLEANUP; + } + client_ver = PackGetInt(client_hello, "MvpnProtocolVersion"); + if (client_ver < MVPN_VERSION_MIN) + { + ret = ERR_PROTOCOL_ERROR; + goto LABEL_CLEANUP; + } + server_ver = MIN(MVPN_VERSION_CURRENT, client_ver); + if (PackGetData2(client_hello, "Nonce", client_nonce, 128) == false) + { + ret = ERR_PROTOCOL_ERROR; + goto LABEL_CLEANUP; + } + if (PackGetStr(client_hello, "Implementation", client_impl, sizeof(client_impl)) == false) + { + ret = ERR_PROTOCOL_ERROR; + goto LABEL_CLEANUP; + } + heartbeat_interval = PackGetInt(client_hello, "HeartBeatInterval"); + + if (heartbeat_interval == 0) heartbeat_interval = MVPN_HEARTBEAT_INTERVAL_DEFAULT; + heartbeat_interval = MAKESURE(heartbeat_interval, MVPN_HEARTBEAT_INTERVAL_MIN, MVPN_HEARTBEAT_INTERVAL_MAX); + + disconnect_timeout = PackGetInt(client_hello, "DisconnectTimeout"); + if (disconnect_timeout == 0) disconnect_timeout = MVPN_DISCONNECT_TIMEOUT_DEFAULT; + disconnect_timeout = MAKESURE(disconnect_timeout, MVPN_DISCONNECT_TIMEOUT_MIN, MVPN_DISCONNECT_TIMEOUT_MAX); + + heartbeat_interval = MIN(heartbeat_interval, disconnect_timeout / 2); + + use_udp_acceleration = PackGetBool(client_hello, "UseUdpAcceleration"); + if (use_udp_acceleration) + { + client_udp_acceleration_port = PackGetInt(client_hello, "UdpAccelerationClientPort"); + if (client_udp_acceleration_port == 0 || + PackGetIp(client_hello, "UdpAccelerationClientIp", &client_udp_acceleration_ip) == false || + PackGetData2(client_hello, "UdpAccelerationClientKey", client_udp_acceleration_key, sizeof(client_udp_acceleration_key)) == false) + { + use_udp_acceleration = false; + } + } + + + Zero(client_hub_name, sizeof(client_hub_name)); + PackGetStr(client_hello, "NetworkName", client_hub_name, sizeof(client_hub_name)); + + // Phase 2: Send a Server Hello packet + server_hello = WsNewErrorPack(ERR_NO_ERROR); + StrCpy(server_impl, sizeof(server_impl), "Test Server"); + PackAddInt(server_hello, "MvpnProtocolVersion", server_ver); + PackAddData(server_hello, "Nonce", server_nonce, 128); + PackAddStr(server_hello, "Implementation", server_impl); + PackAddStr(server_hello, "SupportedAuthMethod", MVPN_AUTHTYPE_ALL_SUPPORTED); + if (WsSendPack(w, server_hello) == false) + { + ret = ERR_DISCONNECTED; + goto LABEL_CLEANUP; + } + + // Phase 3: Receive a Client Auth packet + for (i = 0;i < MVPN_MAX_AUTH_RETRY;i++) + { + bool auth_finish = false; + PACK *client_auth = NULL; + char auth_method[64] = {0}; + char auth_username[MAX_USERNAME_LEN + 1]; + IPC *ipc_tmp = NULL; + IPC_PARAM ipc_param; + UINT ipc_error_code = 0; + UINT mss = INFINITE; + + auth_ret = ERR_INTERNAL_ERROR; + + client_auth = WsRecvPack(w); + if (client_auth == NULL) + { + auth_ret = ERR_PROTOCOL_ERROR; + goto LABEL_EXIT_AUTH_RETRY; + } + + PackGetStr(client_auth, "AuthMethod", auth_method, sizeof(auth_method)); + if (IsEmptyStr(auth_method)) + { + auth_ret = ERR_PROTOCOL_ERROR; + goto LABEL_EXIT_AUTH_RETRY; + } + + PackGetStr(client_auth, "AuthUsername", auth_username, sizeof(auth_username)); + if (IsEmptyStr(auth_method)) + { + auth_ret = ERR_PROTOCOL_ERROR; + goto LABEL_EXIT_AUTH_RETRY; + } + + Zero(&ipc_param, sizeof(ipc_param)); + StrCpy(ipc_param.ClientName, sizeof(ipc_param.ClientName), MVPN_CLIENT_NAME); + + if (IsEmptyStr(client_impl) == false) + { + StrCat(ipc_param.ClientName, sizeof(ipc_param.ClientName), " - "); + StrCat(ipc_param.ClientName, sizeof(ipc_param.ClientName), client_impl); + } + + StrCpy(ipc_param.Postfix, sizeof(ipc_param.Postfix), NVPN_POSTFIX); + StrCpy(ipc_param.HubName, sizeof(ipc_param.HubName), client_hub_name); + StrCpy(ipc_param.UserName, sizeof(ipc_param.UserName), auth_username); + CopyIP(&ipc_param.ClientIp, &w->Sock->RemoteIP); + ipc_param.ClientPort, w->Sock->RemotePort; + CopyIP(&ipc_param.ServerIp, &w->Sock->LocalIP); + ipc_param.ServerPort, w->Sock->LocalPort; + StrCpy(ipc_param.ClientHostname, sizeof(ipc_param.ClientHostname), w->Sock->RemoteHostname); + StrCpy(ipc_param.CryptName, sizeof(ipc_param.CryptName), w->Sock->CipherName); + ipc_param.Layer = IPC_LAYER_3; // TODO + ipc_param.BridgeMode = false; // TODO + + // MSS + if (udp_accel != NULL) mss = MIN(mss, UdpAccelCalcMss(udp_accel)); + if (mss == INFINITE) + { + mss = 0; + } + ipc_param.Mss = mss; + + if (StrCmpi(auth_method, MVPN_AUTHTYPE_ANONYMOUS) == 0) + { + // Anonymous + } + else if (StrCmpi(auth_method, MVPN_AUTHTYPE_PASSWORD_PLAIN) == 0) + { + // Plaintext + char pw[MAX_PASSWORD_LEN + 1]; + PackGetStr(client_auth, "AuthPlainPassword", pw, sizeof(pw)); + StrCpy(ipc_param.Password, sizeof(ipc_param.Password), pw); + } + else + { + // Unknown auth method + auth_ret = ERR_AUTHTYPE_NOT_SUPPORTED; + goto LABEL_EXIT_AUTH_RETRY; + } + + ipc_tmp = NewIPCByParam(c->Cedar, &ipc_param, &ipc_error_code); + + if (ipc_tmp == NULL) + { + auth_ret = ipc_error_code; + goto LABEL_EXIT_AUTH_RETRY; + } + else + { + ipc = ipc_tmp; + auth_finish = true; + } + + auth_ret = ERR_NO_ERROR; + +LABEL_EXIT_AUTH_RETRY: + if (auth_ret != ERR_NO_ERROR) + { + // Phase 4: Send a Server Auth Response + PACK *error_pack = WsNewErrorPack(auth_ret); + UINT remain_retry = MVPN_MAX_AUTH_RETRY - 1 - i; + PackAddInt(error_pack, "RetryAllowedCount", remain_retry); + WsSendPack(w, error_pack); + FreePack(error_pack); + } + FreePack(client_auth); + if (auth_finish) + { + break; + } + } + + if (ipc != NULL) + { + AddProtocolDetailsStr(ipc->IpcSessionShared->ProtocolDetails, sizeof(ipc->IpcSessionShared->ProtocolDetails), + "ModernVPN"); + AddProtocolDetailsKeyValueStr(ipc->IpcSessionShared->ProtocolDetails, sizeof(ipc->IpcSessionShared->ProtocolDetails), + "Transport", "TCP_WebSocket"); + } + + if (ipc != NULL && use_udp_acceleration) + { + udp_accel = NewUdpAccel(c->Cedar, (c->FirstSock->IsRUDPSocket ? NULL : &c->FirstSock->LocalIP), + false, false, false); + + udp_accel->Version = 2; + + udp_accel->FastDetect = true; + udp_accel->ReadRawFlagMode = true; + + if (UdpAccelInitServer(udp_accel, client_udp_acceleration_key, + &client_udp_acceleration_ip, client_udp_acceleration_port, NULL) == false) + { + FreeUdpAccel(udp_accel); + udp_accel = NULL; + } + } + + if (ipc != NULL) + { + // Phase 4: Send auth OK response + PACK *ok_pack = WsNewErrorPack(ERR_NO_ERROR); + PackAddInt(ok_pack, "HeartBeatInterval", heartbeat_interval); + PackAddInt(ok_pack, "DisconnectTimeout", disconnect_timeout); + PackAddStr(ok_pack, "NetworkName", ipc->HubName); + if (udp_accel != NULL) + { + PackAddBool(ok_pack, "UseUdpAcceleration", true); + PackAddIp(ok_pack, "UdpAccelerationServerIp", &udp_accel->MyIp); + PackAddInt(ok_pack, "UdpAccelerationServerPort", udp_accel->MyPort); + PackAddData(ok_pack, "UdpAccelerationServerKey", udp_accel->MyKey_V2, sizeof(udp_accel->MyKey_V2)); + PackAddInt(ok_pack, "UdpAccelerationServerCookie", udp_accel->MyCookie); + PackAddInt(ok_pack, "UdpAccelerationClientCookie", udp_accel->YourCookie); + } + else + { + PackAddBool(ok_pack, "UseUdpAcceleration", false); + } + WsSendPack(w, ok_pack); + FreePack(ok_pack); + + // Session main loop + if (true) + { + SOCK *sock = w->Sock; + SOCK_EVENT *sock_event = NewSockEvent(); + FIFO *send_fifo = NewFifo(); + FIFO *recv_fifo = NewFifo(); + bool has_error = false; + UINT magic_number = Endian32(MVPN_PACKET_MAGIC_NUMBER); + UINT64 last_sent_heartbeat = 0; + UINT tmp_buf_size = 256000; + UCHAR *tmp_buf = ZeroMalloc(tmp_buf_size); + UINT64 last_comm_recv = Tick64(); + + SetTimeout(sock, TIMEOUT_INFINITE); + JoinSockToSockEvent(sock, sock_event); + if (udp_accel != NULL) + { + JoinSockToSockEvent(udp_accel->UdpSock, sock_event); + } + IPCSetSockEventWhenRecvL2Packet(ipc, sock_event); + + while (true) + { + UINT next_interval = INFINITE; + UINT send_ret = 0; + UINT64 now = Tick64(); + UINT r; + + if (udp_accel != NULL) + { + UdpAccelSetTick(udp_accel, now); + UdpAccelPoll(udp_accel); + ipc->IpcSessionShared->EnableUdpAccel = true; + ipc->IpcSessionShared->UsingUdpAccel = UdpAccelIsSendReady(udp_accel, true); + } + else + { + ipc->IpcSessionShared->EnableUdpAccel = false; + ipc->IpcSessionShared->UsingUdpAccel = false; + } + + // Send heartbeat + if (last_sent_heartbeat == 0 || (last_sent_heartbeat + (UINT64)heartbeat_interval) <= now) + { + last_sent_heartbeat = now; + if (FifoSize(send_fifo) <= MAX_BUFFERING_PACKET_SIZE) + { + UCHAR packet_type = MVPN_PACKET_TYPE_HEARTBEAT; + USHORT packet_size = 0; + WriteFifo(send_fifo, &magic_number, 4); + WriteFifo(send_fifo, &packet_type, 1); + WriteFifo(send_fifo, &packet_size, 2); + } + } + + // IPC --> send_fifo or UDP accelerator + while (true) + { + BLOCK *l2_packet = IPCRecvL2(ipc); + UCHAR packet_type; + USHORT packet_size; + if (l2_packet == NULL) + { + break; + } + if (UdpAccelIsSendReady(udp_accel, true)) + { + // Send via UDP accelerator + UdpAccelSend(udp_accel, l2_packet->Buf, l2_packet->Size, + MVPN_PACKET_TYPE_ETHERNET, udp_accel->MaxUdpPacketSize, + false); + } + else + { + // Send via WebSocket + if (FifoSize(send_fifo) <= MAX_BUFFERING_PACKET_SIZE) + { + packet_size = Endian16(l2_packet->Size); + packet_type = MVPN_PACKET_TYPE_ETHERNET; + WriteFifo(send_fifo, &magic_number, 4); + WriteFifo(send_fifo, &packet_type, 1); + WriteFifo(send_fifo, &packet_size, 2); + WriteFifo(send_fifo, l2_packet->Buf, (USHORT)l2_packet->Size); + } + } + FreeBlock(l2_packet); + } + + // send_fifo --> MVPN Client + while (FifoSize(send_fifo) >= 1) + { + UINT r = WsSendAsync(w, ((UCHAR *)send_fifo->p) + send_fifo->pos, send_fifo->size); + if (r == 0) + { + has_error = true; + break; + } + else if (r == INFINITE) + { + break; + } + else + { + ReadFifo(send_fifo, NULL, r); + } + } + + if (WsTrySendAsync(w) == false) + { + has_error = true; + } + + // MVPN Client --> recv_fifo + while (FifoSize(recv_fifo) <= MAX_BUFFERING_PACKET_SIZE) + { + r = WsRecvAsync(w, tmp_buf, tmp_buf_size); + if (r == 0) + { + has_error = true; + break; + } + else if (r == INFINITE) + { + break; + } + else + { + //Debug("recv %u\n", r); + WriteFifo(recv_fifo, tmp_buf, r); + } + } + + // recv_fifo --> IPC + while (true) + { + UINT u32; + UINT packet_size; + UCHAR packet_type; + UCHAR *packet_data; + if (FifoSize(recv_fifo) < 7) + { + break; + } + packet_size = READ_USHORT(FifoPtr(recv_fifo) + 5); + if (FifoSize(recv_fifo) < (7 + packet_size)) + { + break; + } + + ReadFifo(recv_fifo, &u32, 4); + if (u32 != magic_number) + { + break; + } + + ReadFifo(recv_fifo, &packet_type, 1); + ReadFifo(recv_fifo, NULL, 2); + + packet_data = Malloc(packet_size); + + ReadFifo(recv_fifo, packet_data, packet_size); + + if (packet_type == MVPN_PACKET_TYPE_ETHERNET) + { + IPCSendL2(ipc, packet_data, packet_size); + } + + Free(packet_data); + + last_comm_recv = now; + } + + // UDP Accel --> IPC + if (udp_accel != NULL) + { + while (true) + { + UINT packet_size; + UCHAR packet_type; + UCHAR *packet_data; + BLOCK *b = GetNext(udp_accel->RecvBlockQueue); + if (b == NULL) + { + break; + } + + packet_type = b->RawFlagRetUdpAccel; + packet_data = b->Buf; + packet_size = b->Size; + + if (packet_type == MVPN_PACKET_TYPE_ETHERNET) + { + IPCSendL2(ipc, packet_data, packet_size); + } + + FreeBlock(b); + } + } + + if (IsIPCConnected(ipc) == false) + { + has_error = true; + } + + if (now > (last_comm_recv + (UINT64)disconnect_timeout)) + { + has_error = true; + } + + IPCProcessInterrupts(ipc); + + if (has_error) + { + break; + } + + // Wait until the next event occurs + next_interval = GetNextIntervalForInterrupt(ipc->Interrupt); + next_interval = MIN(next_interval, SELECT_TIME); + next_interval = MIN(next_interval, (UINT)((last_sent_heartbeat + (UINT64)heartbeat_interval) - now)); + WaitSockEvent(sock_event, next_interval); + } + + ReleaseSockEvent(sock_event); + ReleaseFifo(send_fifo); + ReleaseFifo(recv_fifo); + Free(tmp_buf); + } + } + +LABEL_CLEANUP: + if (ret != ERR_NO_ERROR) + { + PACK *ret_pack = WsNewErrorPack(ret); + WsSendPack(w, ret_pack); + FreePack(ret_pack); + } + FreeUdpAccel(udp_accel); + FreeIPC(ipc); + FreePack(client_hello); + FreePack(server_hello); + + return 0; +} + + + + + + + + diff --git a/src/Cedar/Protocol.h b/src/Cedar/Protocol.h index 94db6240..3ee86867 100644 --- a/src/Cedar/Protocol.h +++ b/src/Cedar/Protocol.h @@ -105,6 +105,13 @@ #ifndef PROTOCOL_H #define PROTOCOL_H +// MIME types +struct HTTP_MIME_TYPE +{ + char *Extension; + char *MimeType; +}; + // The parameters that will be passed to the certificate confirmation thread struct CHECK_CERT_THREAD_PROC { @@ -195,6 +202,73 @@ struct UPDATE_CLIENT #define PROTO_SUPPRESS_CLIENT_UPDATE_NOTIFICATION_REGKEY "Software\\" GC_REG_COMPANY_NAME "\\" CEDAR_PRODUCT_STR " VPN\\Client Update Notification" #define PROTO_SUPPRESS_CLIENT_UPDATE_NOTIFICATION_REGVALUE "Suppress" +// WebSocket +struct WS +{ + SOCK *Sock; + WSP *Wsp; + REF *Ref; + bool Disconnected; + UINT MaxBufferSize; + UCHAR TmpBuf[65536]; +}; + +// WebSocket Protocol +struct WSP +{ + UINT MaxBufferSize; + FIFO *PhysicalSendFifo; // WSP -> Network + FIFO *PhysicalRecvFifo; // WSP <- Network + FIFO *AppSendFifo; // APP -> WSP + FIFO *AppRecvFifo; // APP <- WSP + bool HasError; +}; + +// WebSocket constants +#define WS_MAX_PAYLOAD_LEN_PER_FRAME (8 * 1024 * 1024) +#define WS_SEND_SINGLE_FRAGMENT_SIZE (32 * 1024) + +#define WS_OPCODE_CONTINUE 0x00 +#define WS_OPCODE_TEXT 0x01 +#define WS_OPCODE_BIN 0x02 +#define WS_OPCODE_CLOSE 0x08 +#define WS_OPCODE_PING 0x09 +#define WS_OPCODE_PONG 0x0A + +// MVPN constants +#define MVPN_VERSION_MIN 100 +#define MVPN_VERSION_CURRENT 100 +#define MVPN_MAX_AUTH_RETRY 10 +#define MVPN_CLIENT_NAME "Modern VPN Client" +#define NVPN_POSTFIX "MVPN" + +// MVPN protocol constants +#define MVPN_AUTHTYPE_ANONYMOUS "anonymous" +#define MVPN_AUTHTYPE_PASSWORD_PLAIN "password_plain" +#define MVPN_AUTHTYPE_PASSWORD_MSCHAPV2 "password_mschapv2" +#define MVPN_AUTHTYPE_CERT "x509cert" + +#define MVPN_HEARTBEAT_INTERVAL_DEFAULT 1234 +#define MVPN_HEARTBEAT_INTERVAL_MIN 100 +#define MVPN_HEARTBEAT_INTERVAL_MAX 15000 + +#define MVPN_DISCONNECT_TIMEOUT_DEFAULT 15000 +#define MVPN_DISCONNECT_TIMEOUT_MIN 5000 +#define MVPN_DISCONNECT_TIMEOUT_MAX 60000 + +#define MVPN_PACKET_MAGIC_NUMBER 0xCAFEBEEF +#define MVPN_PACKET_TYPE_ETHERNET 0 +#define MVPN_PACKET_TYPE_IPV4 1 +#define MVPN_PACKET_TYPE_HEARTBEAT 254 + + + +#define MVPN_AUTHTYPE_ALL_SUPPORTED MVPN_AUTHTYPE_ANONYMOUS "," MVPN_AUTHTYPE_PASSWORD_PLAIN "," MVPN_AUTHTYPE_PASSWORD_MSCHAPV2 "," MVPN_AUTHTYPE_CERT + + + + + // Function prototype UPDATE_CLIENT *NewUpdateClient(UPDATE_NOTIFY_PROC *cb, UPDATE_ISFOREGROUND_PROC *isforeground_cb, void *param, char *family_name, char *software_name, wchar_t *software_title, UINT my_build, UINT64 my_date, char *my_lang, UPDATE_CLIENT_SETTING *current_setting, char *client_id); void FreeUpdateClient(UPDATE_CLIENT *c); @@ -233,6 +307,7 @@ PACK *PackLoginWithAnonymous(char *hubname, char *username); PACK *PackLoginWithPassword(char *hubname, char *username, void *secure_password); PACK *PackLoginWithPlainPassword(char *hubname, char *username, void *plain_password); PACK *PackLoginWithCert(char *hubname, char *username, X *x, void *sign, UINT sign_size); +PACK *PackLoginWithOpenVPNCertificate(char *hubname, char *username, X *x); bool GetMethodFromPack(PACK *p, char *method, UINT size); bool GetHubnameAndUsernameFromPack(PACK *p, char *username, UINT username_size, char *hubname, UINT hubname_size); @@ -302,6 +377,36 @@ X *FindCertIssuerFromCertList(LIST *o, X *x); bool TryGetRootCertChain(LIST *o, X *x, bool auto_save, X **found_root_x); bool TryGetParentCertFromCertList(LIST *o, X *x, LIST *found_chain); bool DownloadAndSaveIntermediateCertificatesIfNecessary(X *x); +char *GetMimeTypeFromFileName(char *filename); + +void MvpnProcGet(CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_target); +bool MvpnSendReply(SOCK *s, UINT status_code, char *status_string, UCHAR *data, UINT data_size, char *content_type, + char *add_header_name, char *add_header_value, HTTP_HEADER *request_headers); +void MvpnAccept(CONNECTION *c, SOCK *s); +UINT MvpnDoAccept(CONNECTION *c, WS *w); + + +WS *NewWs(SOCK *s); +void ReleaseWs(WS *w); +void CleanupWs(WS *w); +UINT WsRecvSync(WS *w, void *data, UINT size); +bool WsRecvSyncAll(WS *w, void *data, UINT size); +bool WsSendSync(WS *w, void *data, UINT size); +UINT WsRecvAsync(WS *w, void *data, UINT size); +UINT WsSendAsync(WS *w, void *data, UINT size); +bool WsTrySendAsync(WS *w); +PACK *WsRecvPack(WS *w); +bool WsSendPack(WS *w, PACK *p); +PACK *WsNewErrorPack(UINT err); +char *WsErrorCodeToString(UINT err); + +WSP *NewWsp(); +void FreeWsp(WSP *p); +void WspTry(WSP *p); +BLOCK *WspTryRecvNextFrame(WSP *p, UINT *read_buffer_size); +void WspTrySendFrame(WSP *p, UCHAR opcode, void *data, UINT size); + + #endif // PROTOCOL_H diff --git a/src/Cedar/Radius.c b/src/Cedar/Radius.c index 689ef65b..bcbac5d4 100644 --- a/src/Cedar/Radius.c +++ b/src/Cedar/Radius.c @@ -314,11 +314,11 @@ bool SendPeapRawPacket(EAP_CLIENT *e, UCHAR *peap_data, UINT peap_size) fragments = NewListFast(NULL); for (num = 0;;num++) { - UCHAR tmp[1024]; + UCHAR tmp[200]; EAP_PEAP *send_peap_message; UINT sz; - sz = ReadBuf(buf, tmp, 1024); + sz = ReadBuf(buf, tmp, sizeof(tmp)); if (sz == 0) { @@ -690,6 +690,11 @@ void EapSetRadiusGeneralAttributes(RADIUS_PACKET *r, EAP_CLIENT *e) Add(r->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_NAS_ID, 0, 0, CEDAR_SERVER_STR, StrLen(CEDAR_SERVER_STR))); + if (IsEmptyStr(e->In_VpnProtocolState) == false) + { + Add(r->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_PROXY_STATE, 0, 0, e->In_VpnProtocolState, StrLen(e->In_VpnProtocolState))); + } + ui = Endian32(2); Add(r->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_VENDOR_SPECIFIC, RADIUS_VENDOR_MICROSOFT, RADIUS_MS_NETWORK_ACCESS_SERVER_TYPE, &ui, sizeof(UINT))); @@ -1011,11 +1016,27 @@ RADIUS_PACKET *EapSendPacketAndRecvResponse(EAP_CLIENT *e, RADIUS_PACKET *r) { RADIUS_AVP *eap_msg = GetRadiusAvp(rp, RADIUS_ATTRIBUTE_EAP_MESSAGE); RADIUS_AVP *vlan_avp = GetRadiusAvp(rp, RADIUS_ATTRIBUTE_VLAN_ID); + RADIUS_AVP *framed_interface_id_avp = GetRadiusAvp(rp, RADIUS_ATTRIBUTE_FRAMED_INTERFACE_ID); if (eap_msg != NULL) { e->LastRecvEapId = ((EAP_MESSAGE *)(eap_msg->Data))->Id; } + if (framed_interface_id_avp != NULL) + { + // FRAMED_INTERFACE_ID + char tmp_str[64]; + UCHAR mac_address[6]; + + Zero(tmp_str, sizeof(tmp_str)); + Copy(tmp_str, framed_interface_id_avp->Data, MIN(framed_interface_id_avp->DataSize, sizeof(tmp_str) - 1)); + + if (StrToMac(mac_address, tmp_str)) + { + Copy(e->LastRecvVirtualMacAddress, mac_address, 6); + } + } + if (vlan_avp != NULL) { // VLAN ID @@ -1746,6 +1767,11 @@ bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT sec // Try the EAP authentication for RADIUS first EAP_CLIENT *eap = mschap.MsChapV2_EapClient; + if (IsEmptyStr(opt->In_VpnProtocolState) == false) + { + StrCpy(eap->In_VpnProtocolState, sizeof(eap->In_VpnProtocolState), opt->In_VpnProtocolState); + } + if (eap->PeapMode == false) { ret = EapClientSendMsChapv2AuthClientResponse(eap, mschap.MsChapV2_ClientResponse, @@ -1766,6 +1792,8 @@ bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT sec opt->Out_VLanId = eap->LastRecvVLanId; } + Copy(opt->Out_VirtualMacAddress, eap->LastRecvVirtualMacAddress, 6); + return true; } else @@ -1880,31 +1908,31 @@ bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT sec // Service-Type ui = Endian32(2); - RadiusAddValue(p, 6, 0, 0, &ui, sizeof(ui)); + RadiusAddValue(p, RADIUS_ATTRIBUTE_SERVICE_TYPE, 0, 0, &ui, sizeof(ui)); // NAS-Port-Type ui = Endian32(5); - RadiusAddValue(p, 61, 0, 0, &ui, sizeof(ui)); + RadiusAddValue(p, RADIUS_ATTRIBUTE_NAS_PORT_TYPE, 0, 0, &ui, sizeof(ui)); // Tunnel-Type ui = Endian32(1); - RadiusAddValue(p, 64, 0, 0, &ui, sizeof(ui)); + RadiusAddValue(p, RADIUS_ATTRIBUTE_TUNNEL_TYPE, 0, 0, &ui, sizeof(ui)); // Tunnel-Medium-Type ui = Endian32(1); - RadiusAddValue(p, 65, 0, 0, &ui, sizeof(ui)); + RadiusAddValue(p, RADIUS_ATTRIBUTE_TUNNEL_MEDIUM_TYPE, 0, 0, &ui, sizeof(ui)); // Called-Station-ID - VPN Hub Name if (IsEmptyStr(hubname) == false) { - RadiusAddValue(p, 30, 0, 0, hubname, StrLen(hubname)); + RadiusAddValue(p, RADIUS_ATTRIBUTE_CALLED_STATION_ID, 0, 0, hubname, StrLen(hubname)); } // Calling-Station-Id - RadiusAddValue(p, 31, 0, 0, client_ip_str, StrLen(client_ip_str)); + RadiusAddValue(p, RADIUS_ATTRIBUTE_CALLING_STATION_ID, 0, 0, client_ip_str, StrLen(client_ip_str)); // Tunnel-Client-Endpoint - RadiusAddValue(p, 66, 0, 0, client_ip_str, StrLen(client_ip_str)); + RadiusAddValue(p, RADIUS_ATTRIBUTE_TUNNEL_CLIENT_ENDPOINT, 0, 0, client_ip_str, StrLen(client_ip_str)); } else { @@ -1918,69 +1946,75 @@ bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT sec // Acct-Session-Id us = Endian16(session_id % 254 + 1); session_id++; - RadiusAddValue(p, 44, 0, 0, &us, sizeof(us)); + RadiusAddValue(p, RADIUS_ATTRIBUTE_ACCT_SESSION_ID, 0, 0, &us, sizeof(us)); // NAS-IP-Address if (c != NULL && c->FirstSock != NULL && c->FirstSock->IPv6 == false) { ui = IPToUINT(&c->FirstSock->LocalIP); - RadiusAddValue(p, 4, 0, 0, &ui, sizeof(ui)); + RadiusAddValue(p, RADIUS_ATTRIBUTE_NAS_IP, 0, 0, &ui, sizeof(ui)); } // Service-Type ui = Endian32(2); - RadiusAddValue(p, 6, 0, 0, &ui, sizeof(ui)); + RadiusAddValue(p, RADIUS_ATTRIBUTE_SERVICE_TYPE, 0, 0, &ui, sizeof(ui)); // MS-RAS-Vendor - ui = Endian32(311); - RadiusAddValue(p, 26, 311, 9, &ui, sizeof(ui)); + ui = Endian32(RADIUS_VENDOR_MICROSOFT); + RadiusAddValue(p, RADIUS_ATTRIBUTE_VENDOR_SPECIFIC, RADIUS_VENDOR_MICROSOFT, RADIUS_MS_RAS_VENDOR, &ui, sizeof(ui)); // MS-RAS-Version - RadiusAddValue(p, 26, 311, 18, ms_ras_version, StrLen(ms_ras_version)); + RadiusAddValue(p, RADIUS_ATTRIBUTE_VENDOR_SPECIFIC, RADIUS_VENDOR_MICROSOFT, RADIUS_MS_VERSION, ms_ras_version, StrLen(ms_ras_version)); // NAS-Port-Type ui = Endian32(5); - RadiusAddValue(p, 61, 0, 0, &ui, sizeof(ui)); + RadiusAddValue(p, RADIUS_ATTRIBUTE_NAS_PORT_TYPE, 0, 0, &ui, sizeof(ui)); // Tunnel-Type ui = Endian32(1); - RadiusAddValue(p, 64, 0, 0, &ui, sizeof(ui)); + RadiusAddValue(p, RADIUS_ATTRIBUTE_TUNNEL_TYPE, 0, 0, &ui, sizeof(ui)); // Tunnel-Medium-Type ui = Endian32(1); - RadiusAddValue(p, 65, 0, 0, &ui, sizeof(ui)); + RadiusAddValue(p, RADIUS_ATTRIBUTE_TUNNEL_MEDIUM_TYPE, 0, 0, &ui, sizeof(ui)); // Called-Station-ID - VPN Hub Name if (IsEmptyStr(hubname) == false) { - RadiusAddValue(p, 30, 0, 0, hubname, StrLen(hubname)); + RadiusAddValue(p, RADIUS_ATTRIBUTE_CALLED_STATION_ID, 0, 0, hubname, StrLen(hubname)); } // Calling-Station-Id - RadiusAddValue(p, 31, 0, 0, client_ip_str, StrLen(client_ip_str)); + RadiusAddValue(p, RADIUS_ATTRIBUTE_CALLING_STATION_ID, 0, 0, client_ip_str, StrLen(client_ip_str)); // Tunnel-Client-Endpoint - RadiusAddValue(p, 66, 0, 0, client_ip_str, StrLen(client_ip_str)); + RadiusAddValue(p, RADIUS_ATTRIBUTE_TUNNEL_CLIENT_ENDPOINT, 0, 0, client_ip_str, StrLen(client_ip_str)); // MS-RAS-Client-Version - RadiusAddValue(p, 26, 311, 35, ms_ras_version, StrLen(ms_ras_version)); + RadiusAddValue(p, RADIUS_ATTRIBUTE_VENDOR_SPECIFIC, RADIUS_VENDOR_MICROSOFT, RADIUS_MS_RAS_CLIENT_VERSION, ms_ras_version, StrLen(ms_ras_version)); // MS-RAS-Client-Name - RadiusAddValue(p, 26, 311, 34, client_ip_str, StrLen(client_ip_str)); + RadiusAddValue(p, RADIUS_ATTRIBUTE_VENDOR_SPECIFIC, RADIUS_VENDOR_MICROSOFT, RADIUS_MS_RAS_CLIENT_NAME, client_ip_str, StrLen(client_ip_str)); // MS-CHAP-Challenge - RadiusAddValue(p, 26, 311, 11, mschap.MsChapV2_ServerChallenge, sizeof(mschap.MsChapV2_ServerChallenge)); + RadiusAddValue(p, RADIUS_ATTRIBUTE_VENDOR_SPECIFIC, RADIUS_VENDOR_MICROSOFT, RADIUS_MS_CHAP_CHALLENGE, mschap.MsChapV2_ServerChallenge, sizeof(mschap.MsChapV2_ServerChallenge)); // MS-CHAP2-Response Zero(ms_chapv2_response, sizeof(ms_chapv2_response)); Copy(ms_chapv2_response + 2, mschap.MsChapV2_ClientChallenge, 16); Copy(ms_chapv2_response + 2 + 16 + 8, mschap.MsChapV2_ClientResponse, 24); - RadiusAddValue(p, 26, 311, 25, ms_chapv2_response, sizeof(ms_chapv2_response)); + RadiusAddValue(p, RADIUS_ATTRIBUTE_VENDOR_SPECIFIC, RADIUS_VENDOR_MICROSOFT, RADIUS_MS_CHAP2_RESPONSE, ms_chapv2_response, sizeof(ms_chapv2_response)); // NAS-ID WriteBuf(p, nas_id->Buf, nas_id->Size); } + if (IsEmptyStr(opt->In_VpnProtocolState) == false) + { + // Proxy state as protocol details + RadiusAddValue(p, RADIUS_ATTRIBUTE_PROXY_STATE, 0, 0, opt->In_VpnProtocolState, StrLen(opt->In_VpnProtocolState)); + } + SeekBuf(p, 0, 0); WRITE_USHORT(((UCHAR *)p->Buf) + 2, (USHORT)p->Size); @@ -2071,6 +2105,9 @@ RECV_RETRY: // Success if (recv_buf[0] == 2) { + LIST *o; + BUF *buf = NewBufFromMemory(recv_buf, recv_size); + ret = true; if (is_mschap && mschap_v2_server_response_20 != NULL) @@ -2108,12 +2145,26 @@ RECV_RETRY: } } - if (opt->In_CheckVLanId) + o = RadiusParseOptions(buf); + if (o != NULL) { - BUF *buf = NewBufFromMemory(recv_buf, recv_size); - LIST *o = RadiusParseOptions(buf); + DHCP_OPTION *framed_interface_id_option = GetDhcpOption(o, RADIUS_ATTRIBUTE_FRAMED_INTERFACE_ID); - if (o != NULL) + if (framed_interface_id_option != NULL) + { + char tmp_str[64]; + UCHAR mac_address[6]; + + Zero(tmp_str, sizeof(tmp_str)); + Copy(tmp_str, framed_interface_id_option->Data, MIN(framed_interface_id_option->Size, sizeof(tmp_str) - 1)); + + if (StrToMac(mac_address, tmp_str)) + { + Copy(opt->Out_VirtualMacAddress, mac_address, 6); + } + } + + if (opt->In_CheckVLanId) { DHCP_OPTION *vlan_option = GetDhcpOption(o, RADIUS_ATTRIBUTE_VLAN_ID); @@ -2132,9 +2183,10 @@ RECV_RETRY: } } - FreeBuf(buf); FreeDhcpOptions(o); } + + FreeBuf(buf); } break; } diff --git a/src/Cedar/Radius.h b/src/Cedar/Radius.h index 286f24a8..712b6003 100644 --- a/src/Cedar/Radius.h +++ b/src/Cedar/Radius.h @@ -133,6 +133,7 @@ #define RADIUS_ATTRIBUTE_EAP_MESSAGE 79 #define RADIUS_ATTRIBUTE_EAP_AUTHENTICATOR 80 #define RADIUS_ATTRIBUTE_VLAN_ID 81 +#define RADIUS_ATTRIBUTE_FRAMED_INTERFACE_ID 96 #define RADIUS_MAX_NAS_ID_LEN 253 // RADIUS codes @@ -327,6 +328,9 @@ struct EAP_CLIENT UCHAR RecvLastCode; UINT LastRecvVLanId; + UCHAR LastRecvVirtualMacAddress[6]; + + char In_VpnProtocolState[64]; }; void FreeRadiusPacket(RADIUS_PACKET *p); @@ -365,6 +369,8 @@ struct RADIUS_LOGIN_OPTION UINT Out_VLanId; bool Out_IsRadiusLogin; char NasId[RADIUS_MAX_NAS_ID_LEN + 1]; // NAS-Identifier + char Out_VirtualMacAddress[6]; + char In_VpnProtocolState[64]; }; // Function prototype diff --git a/src/Cedar/Remote.c b/src/Cedar/Remote.c index cbcae112..5cc45630 100644 --- a/src/Cedar/Remote.c +++ b/src/Cedar/Remote.c @@ -112,6 +112,10 @@ void EndRpc(RPC *rpc) // Release the RPC void RpcFree(RPC *rpc) +{ + RpcFreeEx(rpc, false); +} +void RpcFreeEx(RPC *rpc, bool no_disconnect) { // Validate arguments if (rpc == NULL) @@ -119,7 +123,11 @@ void RpcFree(RPC *rpc) return; } - Disconnect(rpc->Sock); + if (no_disconnect == false) + { + Disconnect(rpc->Sock); + } + ReleaseSock(rpc->Sock); DeleteLock(rpc->Lock); diff --git a/src/Cedar/Remote.h b/src/Cedar/Remote.h index 4052c678..b0b6be3c 100644 --- a/src/Cedar/Remote.h +++ b/src/Cedar/Remote.h @@ -139,6 +139,7 @@ bool RpcIsOk(PACK *p); UINT RpcGetError(PACK *p); void EndRpc(RPC *rpc); void RpcFree(RPC *rpc); +void RpcFreeEx(RPC *rpc, bool no_disconnect); #endif // REMOTE_H diff --git a/src/Cedar/SM.c b/src/Cedar/SM.c index 26b957d9..8741c505 100644 --- a/src/Cedar/SM.c +++ b/src/Cedar/SM.c @@ -3639,6 +3639,16 @@ void SmLicenseAddDlgOnOk(HWND hWnd, SM_SERVER *s) { RPC_TEST t; + if (s->LicenseWarnFlag == false) + { + if (MsgBoxEx(hWnd, MB_ICONINFORMATION | MB_OKCANCEL, _UU("SM_LICENSE_WARNING")) == IDCANCEL) + { + return; + } + + s->LicenseWarnFlag = true; + } + Disable(hWnd, IDOK); Disable(hWnd, IDCANCEL); diff --git a/src/Cedar/SMInner.h b/src/Cedar/SMInner.h index f8d09b17..b9982ded 100644 --- a/src/Cedar/SMInner.h +++ b/src/Cedar/SMInner.h @@ -166,6 +166,7 @@ typedef struct SM_SERVER bool VgsMessageDisplayed; // Whether to have already displayed a message about VGS WINUI_UPDATE *Update; // Update notification bool IsInClient; // Within VPN Client mode + bool LicenseWarnFlag; } SM_SERVER; typedef void (SM_STATUS_INIT_PROC)(HWND hWnd, SM_SERVER *p, void *param); diff --git a/src/Cedar/SW.c b/src/Cedar/SW.c index f022dd90..e1f7ef62 100644 --- a/src/Cedar/SW.c +++ b/src/Cedar/SW.c @@ -5732,6 +5732,15 @@ UINT SwWelcomeDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, WIZARD *wiz break; } + if (MsIsKB3033929RequiredAndMissing()) + { + // KB3033929 is missing + if (MsgBoxEx(hWnd, MB_ICONINFORMATION | MB_OKCANCEL, _UU("SW_KB3033929_REQUIRED")) == IDCANCEL) + { + break; + } + } + if (sw->DoubleClickBlocker) { break; diff --git a/src/Cedar/Server.c b/src/Cedar/Server.c index 98bfa571..31f4cb67 100644 --- a/src/Cedar/Server.c +++ b/src/Cedar/Server.c @@ -1115,52 +1115,72 @@ LIST *EnumLogFile(char *hubname) // Enumerate in the packet_log Format(tmp, sizeof(tmp), "%s/packet_log", exe_dir); - dir = EnumDir(tmp); - if (dir != NULL) + + if (hubname == NULL) { - UINT i; - for (i = 0;i < dir->NumFiles;i++) + dir = EnumDir(tmp); + if (dir != NULL) { - DIRENT *e = dir->File[i]; - - if (e->Folder) + UINT i; + for (i = 0;i < dir->NumFiles;i++) { - char dir_name[MAX_PATH]; + DIRENT *e = dir->File[i]; - if (hubname == NULL || StrCmpi(hubname, e->FileName) == 0) + if (e->Folder) { + char dir_name[MAX_PATH]; + Format(dir_name, sizeof(dir_name), "packet_log/%s", e->FileName); + EnumLogFileDir(o, dir_name); } } - } - FreeDir(dir); + FreeDir(dir); + } + } + else + { + char dir_name[MAX_PATH]; + + Format(dir_name, sizeof(dir_name), "packet_log/%s", hubname); + + EnumLogFileDir(o, dir_name); } // Enumerate in the security_log Format(tmp, sizeof(tmp), "%s/security_log", exe_dir); - dir = EnumDir(tmp); - if (dir != NULL) + + if (hubname == NULL) { - UINT i; - for (i = 0;i < dir->NumFiles;i++) + dir = EnumDir(tmp); + if (dir != NULL) { - DIRENT *e = dir->File[i]; - - if (e->Folder) + UINT i; + for (i = 0;i < dir->NumFiles;i++) { - char dir_name[MAX_PATH]; + DIRENT *e = dir->File[i]; - if (hubname == NULL || StrCmpi(hubname, e->FileName) == 0) + if (e->Folder) { + char dir_name[MAX_PATH]; + Format(dir_name, sizeof(dir_name), "security_log/%s", e->FileName); + EnumLogFileDir(o, dir_name); } } - } - FreeDir(dir); + FreeDir(dir); + } + } + else + { + char dir_name[MAX_PATH]; + + Format(dir_name, sizeof(dir_name), "security_log/%s", hubname); + + EnumLogFileDir(o, dir_name); } return o; @@ -1871,14 +1891,37 @@ void OutRpcCapsList(PACK *p, CAPSLIST *t) return; } + PackSetCurrentJsonGroupName(p, "CapsList"); for (i = 0;i < LIST_NUM(t->CapsList);i++) { char tmp[MAX_SIZE]; + char ct_key[MAX_PATH]; + wchar_t ct_description[MAX_PATH]; + wchar_t *w; CAPS *c = LIST_DATA(t->CapsList, i); Format(tmp, sizeof(tmp), "caps_%s", c->Name); + + Format(ct_key, sizeof(ct_key), "CT_%s", c->Name); + + Zero(ct_description, sizeof(ct_description)); + w = _UU(ct_key); + if (UniIsEmptyStr(w) == false) + { + UniStrCpy(ct_description, sizeof(ct_description), w); + } + else + { + StrToUni(ct_description, sizeof(ct_description), c->Name); + } + PackAddInt(p, tmp, c->Value); + + PackAddStrEx(p, "CapsName", c->Name, i, LIST_NUM(t->CapsList)); + PackAddIntEx(p, "CapsValue", c->Value, i, LIST_NUM(t->CapsList)); + PackAddUniStrEx(p, "CapsDescrption", ct_description, i, LIST_NUM(t->CapsList)); } + PackSetCurrentJsonGroupName(p, NULL); } void FreeRpcCapsList(CAPSLIST *t) { @@ -6167,6 +6210,9 @@ void SiLoadServerCfg(SERVER *s, FOLDER *f) c->SslAcceptSettings.Tls_Disable1_2 = CfgGetBool(f, "Tls_Disable1_2"); s->StrictSyslogDatetimeFormat = CfgGetBool(f, "StrictSyslogDatetimeFormat"); + + // Disable JSON-RPC Web API + s->DisableJsonRpcWebApi = CfgGetBool(f, "DisableJsonRpcWebApi"); } Unlock(c->lock); @@ -6484,6 +6530,9 @@ void SiWriteServerCfg(FOLDER *f, SERVER *s) CfgAddBool(f, "DisableSessionReconnect", GetGlobalServerFlag(GSF_DISABLE_SESSION_RECONNECT)); CfgAddBool(f, "StrictSyslogDatetimeFormat", s->StrictSyslogDatetimeFormat); + + // Disable JSON-RPC Web API + CfgAddBool(f, "DisableJsonRpcWebApi", s->DisableJsonRpcWebApi); } Unlock(c->lock); } @@ -7211,7 +7260,7 @@ FARM_MEMBER *SiGetNextFarmMember(SERVER *s, CONNECTION *c, HUB *h) PackAddIntEx(p, "NumTcpConnections", f->NumTcpConnections, i, num); PackAddIntEx(p, "NumHubs", LIST_NUM(f->HubList), i, num); PackAddBoolEx(p, "Me", f->Me, i, num); - PackAddInt64Ex(p, "ConnectedTime", f->ConnectedTime, i, num); + PackAddTime64Ex(p, "ConnectedTime", f->ConnectedTime, i, num); PackAddInt64Ex(p, "SystemId", f->SystemId, i, num); PackAddBoolEx(p, "DoNotSelect", do_not_select, i, num); } @@ -7240,7 +7289,7 @@ FARM_MEMBER *SiGetNextFarmMember(SERVER *s, CONNECTION *c, HUB *h) PackAddStr(p, "CipherName", c->CipherName); PackAddStr(p, "ClientStr", c->ClientStr); PackAddInt(p, "ClientVer", c->ClientVer); - PackAddInt64(p, "ConnectedTime", Tick64ToTime64(c->ConnectedTick)); + PackAddTime64(p, "ConnectedTime", Tick64ToTime64(c->ConnectedTick)); PackAddStr(p, "HubName", h->Name); PackAddBool(p, "StaticHub", h->Type == HUB_TYPE_FARM_STATIC); @@ -7381,8 +7430,8 @@ void SiCalledEnumHub(SERVER *s, PACK *p, PACK *req) PackAddIntEx(p, "NumIpTables", LIST_NUM(h->IpTable), i, num); - PackAddInt64Ex(p, "LastCommTime", h->LastCommTime, i, num); - PackAddInt64Ex(p, "CreatedTime", h->CreatedTime, i, num); + PackAddTime64Ex(p, "LastCommTime", h->LastCommTime, i, num); + PackAddTime64Ex(p, "CreatedTime", h->CreatedTime, i, num); } Unlock(h->lock); } @@ -10309,12 +10358,16 @@ void SiFarmServMain(SERVER *server, SOCK *sock, FARM_MEMBER *f) } // Receive - p = HttpServerRecv(sock); + p = HttpServerRecvEx(sock, FIRM_SERV_RECV_PACK_MAX_SIZE); t->Response = p; Set(t->CompleteEvent); - send_noop = false; + if (p == NULL) + { + Disconnect(sock); + goto DISCONNECTED; + } } } while (t != NULL); diff --git a/src/Cedar/Server.h b/src/Cedar/Server.h index 55bf6016..4618eee5 100644 --- a/src/Cedar/Server.h +++ b/src/Cedar/Server.h @@ -147,6 +147,8 @@ extern char *SERVER_CONFIG_FILE_NAME; #define MEMBER_SELECTOR_CONNECT_TIMEOUT 2000 #define MEMBER_SELECTOR_DATA_TIMEOUT 5000 +#define FIRM_SERV_RECV_PACK_MAX_SIZE (100 * 1024 * 1024) + // Virtual HUB list hosted by each farm member struct HUB_LIST @@ -360,6 +362,7 @@ struct SERVER volatile UINT NatTGlobalUdpPort; // NAT-T global UDP port bool StrictSyslogDatetimeFormat; // Make syslog datetime format strict RFC3164 + bool DisableJsonRpcWebApi; // Disable JSON-RPC Web API }; @@ -383,6 +386,7 @@ struct RPC_SESSION_STATUS RPC_CLIENT_GET_CONNECTION_STATUS Status; // Status UINT ClientIp; // Client IP address UCHAR ClientIp6[16]; // Client IPv6 address + IP ClientIpAddress; // Client IP address (IPv4/IPv6) char ClientHostName[MAX_HOST_NAME_LEN + 1]; // Client host name NODE_INFO NodeInfo; // Node information }; diff --git a/src/Cedar/Session.c b/src/Cedar/Session.c index 5116ff70..6a44a1ab 100644 --- a/src/Cedar/Session.c +++ b/src/Cedar/Session.c @@ -1257,7 +1257,10 @@ void StopSessionEx(SESSION *s, bool no_wait) // Client mode if (s->Connection) { - StopConnection(s->Connection, no_wait); + CONNECTION *c = s->Connection; + AddRef(c->ref); + StopConnection(c, no_wait); + ReleaseConnection(c); } } else @@ -1265,7 +1268,10 @@ void StopSessionEx(SESSION *s, bool no_wait) // Server mode if (s->Connection) { - StopConnection(s->Connection, no_wait); + CONNECTION *c = s->Connection; + AddRef(c->ref); + StopConnection(c, no_wait); + ReleaseConnection(c); } } @@ -1391,6 +1397,8 @@ void CleanupSession(SESSION *s) DeleteCounter(s->LoggingRecordCount); + ReleaseSharedBuffer(s->IpcSessionSharedBuffer); + Free(s); } @@ -2199,9 +2207,9 @@ void if_free(SESSION *s); // Create a server session SESSION *NewServerSession(CEDAR *cedar, CONNECTION *c, HUB *h, char *username, POLICY *policy) { - return NewServerSessionEx(cedar, c, h, username, policy, false); + return NewServerSessionEx(cedar, c, h, username, policy, false, NULL); } -SESSION *NewServerSessionEx(CEDAR *cedar, CONNECTION *c, HUB *h, char *username, POLICY *policy, bool inproc_mode) +SESSION *NewServerSessionEx(CEDAR *cedar, CONNECTION *c, HUB *h, char *username, POLICY *policy, bool inproc_mode, UCHAR *ipc_mac_address) { SESSION *s; char name[MAX_SIZE]; @@ -2322,28 +2330,35 @@ SESSION *NewServerSessionEx(CEDAR *cedar, CONNECTION *c, HUB *h, char *username, // Generate a MAC address for IPC if (s->InProcMode) { - char tmp[MAX_SIZE]; - char machine[MAX_SIZE]; - UCHAR hash[SHA1_SIZE]; + if (ipc_mac_address != NULL) + { + Copy(s->IpcMacAddress, ipc_mac_address, 6); + } + else + { + char tmp[MAX_SIZE]; + char machine[MAX_SIZE]; + UCHAR hash[SHA1_SIZE]; - GetMachineName(machine, sizeof(machine)); + GetMachineName(machine, sizeof(machine)); - Format(tmp, sizeof(tmp), "%s@%s@%u", machine, h->Name, s->UniqueId); + Format(tmp, sizeof(tmp), "%s@%s@%u", machine, h->Name, s->UniqueId); - StrUpper(tmp); - Trim(tmp); + StrUpper(tmp); + Trim(tmp); - Hash(hash, tmp, StrLen(tmp), true); + Hash(hash, tmp, StrLen(tmp), true); - s->IpcMacAddress[0] = 0xCA; - s->IpcMacAddress[1] = hash[1]; - s->IpcMacAddress[2] = hash[2]; - s->IpcMacAddress[3] = hash[3]; - s->IpcMacAddress[4] = hash[4]; - s->IpcMacAddress[5] = hash[5]; + s->IpcMacAddress[0] = 0xCA; + s->IpcMacAddress[1] = hash[1]; + s->IpcMacAddress[2] = hash[2]; + s->IpcMacAddress[3] = hash[3]; + s->IpcMacAddress[4] = hash[4]; + s->IpcMacAddress[5] = hash[5]; - MacToStr(tmp, sizeof(tmp), s->IpcMacAddress); - Debug("MAC Address for IPC: %s\n", tmp); + MacToStr(tmp, sizeof(tmp), s->IpcMacAddress); + Debug("MAC Address for IPC: %s\n", tmp); + } } return s; diff --git a/src/Cedar/Session.h b/src/Cedar/Session.h index 4a74b0f8..d2704994 100644 --- a/src/Cedar/Session.h +++ b/src/Cedar/Session.h @@ -256,6 +256,7 @@ struct SESSION UINT NumDisconnected; // Number of socket disconnection bool NoReconnectToSession; // Disable to reconnect to the session char UnderlayProtocol[64]; // Physical communication protocol + char ProtocolDetails[256]; // Protocol Details UINT64 FirstConnectionEstablisiedTime; // Connection completion time of the first connection UINT64 CurrentConnectionEstablishTime; // Completion time of this connection UINT NumConnectionsEatablished; // Number of connections established so far @@ -265,10 +266,12 @@ struct SESSION bool IsRUDPSession; // Whether R-UDP session UINT RUdpMss; // The value of the MSS should be applied while the R-UDP is used bool EnableBulkOnRUDP; // Allow the bulk transfer in the R-UDP session + UINT BulkOnRUDPVersion; // RUDP Bulk Version bool EnableHMacOnBulkOfRUDP; // Use the HMAC to sign the bulk transfer of R-UDP session bool EnableUdpRecovery; // Enable the R-UDP recovery bool UseUdpAcceleration; // Use of UDP acceleration mode + UINT UdpAccelerationVersion; // UDP acceleration version bool UseHMacOnUdpAcceleration; // Use the HMAC in the UDP acceleration mode UDP_ACCEL *UdpAccel; // UDP acceleration bool IsUsingUdpAcceleration; // Flag of whether the UDP acceleration is used @@ -308,6 +311,11 @@ struct SESSION char FirstTimeHttpRedirectUrl[128]; // URL for redirection only the first time UINT FirstTimeHttpAccessCheckIp; // IP address for access checking + UCHAR BulkSendKey[RUDP_BULK_KEY_SIZE_MAX]; // RUDP Bulk Send Key + UINT BulkSendKeySize; // RUDP Bulk Send Key size + UCHAR BulkRecvKey[RUDP_BULK_KEY_SIZE_MAX]; // RUDP Bulk Recv Key + UINT BulkRecvKeySize; // RUDP Bulk Recv Key size + // To examine the maximum number of alowed logging target packets per minute UINT64 MaxLoggedPacketsPerMinuteStartTick; // Inspection start time UINT CurrentNumPackets; // Current number of packets @@ -315,6 +323,9 @@ struct SESSION // Measures for D-Link bug UINT64 LastDLinkSTPPacketSendTick; // Last D-Link STP packet transmission time UCHAR LastDLinkSTPPacketDataHash[MD5_SIZE]; // Last D-Link STP packet hash + + SHARED_BUFFER *IpcSessionSharedBuffer; // A shared buffer between IPC and Session + IPC_SESSION_SHARED_BUFFER_DATA *IpcSessionShared; // A shared data between IPC and Session }; // Password dialog @@ -396,7 +407,7 @@ SESSION *NewRpcSession(CEDAR *cedar, CLIENT_OPTION *option); SESSION *NewRpcSessionEx(CEDAR *cedar, CLIENT_OPTION *option, UINT *err, char *client_str); SESSION *NewRpcSessionEx2(CEDAR *cedar, CLIENT_OPTION *option, UINT *err, char *client_str, void *hWnd); SESSION *NewServerSession(CEDAR *cedar, CONNECTION *c, HUB *h, char *username, POLICY *policy); -SESSION *NewServerSessionEx(CEDAR *cedar, CONNECTION *c, HUB *h, char *username, POLICY *policy, bool inproc_mode); +SESSION *NewServerSessionEx(CEDAR *cedar, CONNECTION *c, HUB *h, char *username, POLICY *policy, bool inproc_mode, UCHAR *ipc_mac_address); void ClientThread(THREAD *t, void *param); void ReleaseSession(SESSION *s); void CleanupSession(SESSION *s); diff --git a/src/Cedar/UdpAccel.c b/src/Cedar/UdpAccel.c index a9597bf7..dc9b0c33 100644 --- a/src/Cedar/UdpAccel.c +++ b/src/Cedar/UdpAccel.c @@ -350,7 +350,7 @@ void UdpAccelSendBlock(UDP_ACCEL *a, BLOCK *b) return; } - UdpAccelSend(a, b->Buf, b->Size, b->Compressed, a->MaxUdpPacketSize, b->PriorityQoS); + UdpAccelSend(a, b->Buf, b->Size, b->Compressed ? 1 : 0, a->MaxUdpPacketSize, b->PriorityQoS); } // Calculate the best MSS @@ -382,7 +382,7 @@ UINT UdpAccelCalcMss(UDP_ACCEL *a) if (a->PlainTextMode == false) { // IV - ret -= UDP_ACCELERATION_PACKET_IV_SIZE; + ret -= UDP_ACCELERATION_PACKET_IV_SIZE_V1; } // Cookie @@ -403,7 +403,7 @@ UINT UdpAccelCalcMss(UDP_ACCEL *a) if (a->PlainTextMode == false) { // Verify - ret -= UDP_ACCELERATION_PACKET_IV_SIZE; + ret -= UDP_ACCELERATION_PACKET_IV_SIZE_V1; } // Ethernet header (communication packets) @@ -419,12 +419,12 @@ UINT UdpAccelCalcMss(UDP_ACCEL *a) } // Send -void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, bool compressed, UINT max_size, bool high_priority) +void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, UCHAR flag, UINT max_size, bool high_priority) { UCHAR tmp[UDP_ACCELERATION_TMP_BUF_SIZE]; UCHAR *buf; UINT size; - UCHAR key[UDP_ACCELERATION_PACKET_KEY_SIZE]; + UCHAR key[UDP_ACCELERATION_PACKET_KEY_SIZE_V1]; UINT64 ui64; USHORT us; UCHAR c; @@ -448,27 +448,40 @@ void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, bool compressed, UI // IV if (a->PlainTextMode == false) { - // IV - Copy(buf, a->NextIv, UDP_ACCELERATION_PACKET_IV_SIZE); - - buf += UDP_ACCELERATION_PACKET_IV_SIZE; - size += UDP_ACCELERATION_PACKET_IV_SIZE; - - // Calculate the key - UdpAccelCalcKey(key, a->MyKey, a->NextIv); - - if (false) + if (a->Version == 2) { - char tmp1[256]; - char tmp2[256]; - char tmp3[256]; - BinToStr(tmp1, sizeof(tmp1), a->MyKey, sizeof(a->MyKey)); - BinToStr(tmp2, sizeof(tmp2), a->NextIv, UDP_ACCELERATION_PACKET_IV_SIZE); - BinToStr(tmp3, sizeof(tmp3), key, sizeof(key)); - Debug("My Key : %s\n" - "IV : %s\n" - "Comm Key: %s\n", - tmp1, tmp2, tmp3); + // Version 2.0 + // IV + Copy(buf, a->NextIv_V2, UDP_ACCELERATION_PACKET_IV_SIZE_V2); + + buf += UDP_ACCELERATION_PACKET_IV_SIZE_V2; + size += UDP_ACCELERATION_PACKET_IV_SIZE_V2; + } + else + { + // Version 1.0 + // IV + Copy(buf, a->NextIv, UDP_ACCELERATION_PACKET_IV_SIZE_V1); + + buf += UDP_ACCELERATION_PACKET_IV_SIZE_V1; + size += UDP_ACCELERATION_PACKET_IV_SIZE_V1; + + // Calculate the key + UdpAccelCalcKey(key, a->MyKey, a->NextIv); + + if (false) + { + char tmp1[256]; + char tmp2[256]; + char tmp3[256]; + BinToStr(tmp1, sizeof(tmp1), a->MyKey, sizeof(a->MyKey)); + BinToStr(tmp2, sizeof(tmp2), a->NextIv, UDP_ACCELERATION_PACKET_IV_SIZE_V1); + BinToStr(tmp3, sizeof(tmp3), key, sizeof(key)); + Debug("My Key : %s\n" + "IV : %s\n" + "Comm Key: %s\n", + tmp1, tmp2, tmp3); + } } } @@ -496,8 +509,8 @@ void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, bool compressed, UI buf += sizeof(USHORT); size += sizeof(USHORT); - // Compress Flag - c = (compressed ? 1 : 0); + // Flag + c = flag; Copy(buf, &c, sizeof(UCHAR)); buf += sizeof(UCHAR); size += sizeof(UCHAR); @@ -512,37 +525,74 @@ void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, bool compressed, UI if (a->PlainTextMode == false) { - static UCHAR zero[UDP_ACCELERATION_PACKET_IV_SIZE] = {0}; - CRYPT *c; - - current_size = UDP_ACCELERATION_PACKET_IV_SIZE + sizeof(UINT) + sizeof(UINT64) * 2 + - sizeof(USHORT) + sizeof(UCHAR) + data_size + UDP_ACCELERATION_PACKET_IV_SIZE; - - if (current_size < max_size) + if (a->Version == 2) { + // Ver 2 // Padding - UCHAR pad[UDP_ACCELERATION_MAX_PADDING_SIZE]; - UINT pad_size = MIN(max_size - current_size, UDP_ACCELERATION_MAX_PADDING_SIZE); - pad_size = rand() % pad_size; + current_size = UDP_ACCELERATION_PACKET_IV_SIZE_V2 + sizeof(UINT) + sizeof(UINT64) * 2 + + sizeof(USHORT) + sizeof(UCHAR) + data_size + UDP_ACCELERATION_PACKET_MAC_SIZE_V2; - Zero(pad, sizeof(pad)); - Copy(buf, pad, pad_size); - buf += pad_size; - size += pad_size; + if (current_size < max_size) + { + UCHAR pad[UDP_ACCELERATION_MAX_PADDING_SIZE]; + UINT pad_size = MIN(max_size - current_size, UDP_ACCELERATION_MAX_PADDING_SIZE); + pad_size = rand() % pad_size; + Zero(pad, sizeof(pad)); + Copy(buf, pad, pad_size); + buf += pad_size; + size += pad_size; + } + + // Encryption by RFC 8439: ChaCha20-Poly1305-IETF Encryption with AEAD + Aead_ChaCha20Poly1305_Ietf_Encrypt(tmp + UDP_ACCELERATION_PACKET_IV_SIZE_V2, + tmp + UDP_ACCELERATION_PACKET_IV_SIZE_V2, + size - UDP_ACCELERATION_PACKET_IV_SIZE_V2, + a->MyKey_V2, + a->NextIv_V2, + NULL, 0); + + // Next Iv + Copy(a->NextIv_V2, + tmp + UDP_ACCELERATION_PACKET_IV_SIZE_V2 + size - UDP_ACCELERATION_PACKET_IV_SIZE_V2 - UDP_ACCELERATION_PACKET_IV_SIZE_V2, UDP_ACCELERATION_PACKET_IV_SIZE_V2); + + // MAC + size += UDP_ACCELERATION_PACKET_MAC_SIZE_V2; } + else + { + // Ver 1 + static UCHAR zero[UDP_ACCELERATION_PACKET_IV_SIZE_V1] = {0}; + CRYPT *c; - // Verify - Copy(buf, zero, UDP_ACCELERATION_PACKET_IV_SIZE); - buf += UDP_ACCELERATION_PACKET_IV_SIZE; - size += UDP_ACCELERATION_PACKET_IV_SIZE; + current_size = UDP_ACCELERATION_PACKET_IV_SIZE_V1 + sizeof(UINT) + sizeof(UINT64) * 2 + + sizeof(USHORT) + sizeof(UCHAR) + data_size + UDP_ACCELERATION_PACKET_IV_SIZE_V1; - // Encryption - c = NewCrypt(key, UDP_ACCELERATION_PACKET_KEY_SIZE); - Encrypt(c, tmp + UDP_ACCELERATION_PACKET_IV_SIZE, tmp + UDP_ACCELERATION_PACKET_IV_SIZE, size - UDP_ACCELERATION_PACKET_IV_SIZE); - FreeCrypt(c); + if (current_size < max_size) + { + // Padding + UCHAR pad[UDP_ACCELERATION_MAX_PADDING_SIZE]; + UINT pad_size = MIN(max_size - current_size, UDP_ACCELERATION_MAX_PADDING_SIZE); + pad_size = rand() % pad_size; - // Next Iv - Copy(a->NextIv, buf - UDP_ACCELERATION_PACKET_IV_SIZE, UDP_ACCELERATION_PACKET_IV_SIZE); + Zero(pad, sizeof(pad)); + Copy(buf, pad, pad_size); + buf += pad_size; + size += pad_size; + } + + // Verify + Copy(buf, zero, UDP_ACCELERATION_PACKET_IV_SIZE_V1); + buf += UDP_ACCELERATION_PACKET_IV_SIZE_V1; + size += UDP_ACCELERATION_PACKET_IV_SIZE_V1; + + // Encryption + c = NewCrypt(key, UDP_ACCELERATION_PACKET_KEY_SIZE_V1); + Encrypt(c, tmp + UDP_ACCELERATION_PACKET_IV_SIZE_V1, tmp + UDP_ACCELERATION_PACKET_IV_SIZE_V1, size - UDP_ACCELERATION_PACKET_IV_SIZE_V1); + FreeCrypt(c); + + // Next Iv + Copy(a->NextIv, buf - UDP_ACCELERATION_PACKET_IV_SIZE_V1, UDP_ACCELERATION_PACKET_IV_SIZE_V1); + } } // Send @@ -667,7 +717,7 @@ bool UdpAccelIsSendReady(UDP_ACCEL *a, bool check_keepalive) // Process the received packet BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip, UINT src_port) { - UCHAR key[UDP_ACCELERATION_PACKET_KEY_SIZE]; + UCHAR key[UDP_ACCELERATION_PACKET_KEY_SIZE_V1]; UCHAR *iv; CRYPT *c; UINT64 my_tick, your_tick; @@ -676,6 +726,7 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip UINT pad_size; UCHAR *verify; bool compress_flag; + UCHAR raw_flag; BLOCK *b = NULL; UINT cookie; // Validate arguments @@ -686,36 +737,66 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip if (a->PlainTextMode == false) { - // IV - if (size < UDP_ACCELERATION_PACKET_IV_SIZE) + if (a->Version == 2) { - return NULL; + // Version 2.0 + // IV + if (size < UDP_ACCELERATION_PACKET_IV_SIZE_V2) + { + return NULL; + } + iv = buf; + buf += UDP_ACCELERATION_PACKET_IV_SIZE_V2; + size -= UDP_ACCELERATION_PACKET_IV_SIZE_V2; + + if (size < AEAD_CHACHA20_POLY1305_MAC_SIZE) + { + return NULL; + } + + // Decryption by RFC 8439: ChaCha20-Poly1305-IETF Encryption with AEAD + if (Aead_ChaCha20Poly1305_Ietf_Decrypt(buf, buf, size, a->YourKey_V2, + iv, NULL, 0) == false) + { + return NULL; + } + + size -= AEAD_CHACHA20_POLY1305_MAC_SIZE; } - iv = buf; - buf += UDP_ACCELERATION_PACKET_IV_SIZE; - size -= UDP_ACCELERATION_PACKET_IV_SIZE; - - // Calculate the key - UdpAccelCalcKey(key, a->YourKey, iv); - - if (false) + else { - char tmp1[256]; - char tmp2[256]; - char tmp3[256]; - BinToStr(tmp1, sizeof(tmp1), a->YourKey, sizeof(a->YourKey)); - BinToStr(tmp2, sizeof(tmp2), iv, UDP_ACCELERATION_PACKET_IV_SIZE); - BinToStr(tmp3, sizeof(tmp3), key, sizeof(key)); - Debug("Your Key: %s\n" - "IV : %s\n" - "Comm Key: %s\n", - tmp1, tmp2, tmp3); - } + // Version 1.0 + // IV + if (size < UDP_ACCELERATION_PACKET_IV_SIZE_V1) + { + return NULL; + } + iv = buf; + buf += UDP_ACCELERATION_PACKET_IV_SIZE_V1; + size -= UDP_ACCELERATION_PACKET_IV_SIZE_V1; - // Decryption - c = NewCrypt(key, UDP_ACCELERATION_PACKET_KEY_SIZE); - Encrypt(c, buf, buf, size); - FreeCrypt(c); + // Calculate the key + UdpAccelCalcKey(key, a->YourKey, iv); + + if (false) + { + char tmp1[256]; + char tmp2[256]; + char tmp3[256]; + BinToStr(tmp1, sizeof(tmp1), a->YourKey, sizeof(a->YourKey)); + BinToStr(tmp2, sizeof(tmp2), iv, UDP_ACCELERATION_PACKET_IV_SIZE_V1); + BinToStr(tmp3, sizeof(tmp3), key, sizeof(key)); + Debug("Your Key: %s\n" + "IV : %s\n" + "Comm Key: %s\n", + tmp1, tmp2, tmp3); + } + + // Decryption + c = NewCrypt(key, UDP_ACCELERATION_PACKET_KEY_SIZE_V1); + Encrypt(c, buf, buf, size); + FreeCrypt(c); + } } // Cookie @@ -759,12 +840,20 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip buf += sizeof(USHORT); size -= sizeof(USHORT); - // compress_flag + // flag if (size < sizeof(UCHAR)) { return NULL; } - compress_flag = *((UCHAR *)buf); + if (a->ReadRawFlagMode == false) + { + compress_flag = *((UCHAR *)buf); + } + else + { + raw_flag = *((UCHAR *)buf); + } + buf += sizeof(UCHAR); size -= sizeof(UCHAR); @@ -783,26 +872,29 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip if (a->PlainTextMode == false) { - // padding - if (size < UDP_ACCELERATION_PACKET_IV_SIZE) + if (a->Version == 1) { - return false; - } - pad_size = size - UDP_ACCELERATION_PACKET_IV_SIZE; - buf += pad_size; - size -= pad_size; + // padding + if (size < UDP_ACCELERATION_PACKET_IV_SIZE_V1) + { + return false; + } + pad_size = size - UDP_ACCELERATION_PACKET_IV_SIZE_V1; + buf += pad_size; + size -= pad_size; - // verify - if (size != UDP_ACCELERATION_PACKET_IV_SIZE) - { - return NULL; - } + // verify + if (size != UDP_ACCELERATION_PACKET_IV_SIZE_V1) + { + return NULL; + } - verify = buf; + verify = buf; - if (IsZero(verify, UDP_ACCELERATION_PACKET_IV_SIZE) == false) - { - return NULL; + if (IsZero(verify, UDP_ACCELERATION_PACKET_IV_SIZE_V1) == false) + { + return NULL; + } } } @@ -819,7 +911,11 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip if (inner_size >= 1) { - b = NewBlock(Clone(inner_data, inner_size), inner_size, compress_flag ? -1 : 0); + b = NewBlock(Clone(inner_data, inner_size), inner_size, a->ReadRawFlagMode == false ? (compress_flag ? -1 : 0) : 0); + if (a->ReadRawFlagMode) + { + b->RawFlagRetUdpAccel = raw_flag; + } } if (a->LastSetSrcIpAndPortTick < a->LastRecvYourTick) @@ -851,15 +947,15 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip // Calculate the key void UdpAccelCalcKey(UCHAR *key, UCHAR *common_key, UCHAR *iv) { - UCHAR tmp[UDP_ACCELERATION_COMMON_KEY_SIZE + UDP_ACCELERATION_PACKET_IV_SIZE]; + UCHAR tmp[UDP_ACCELERATION_COMMON_KEY_SIZE_V1 + UDP_ACCELERATION_PACKET_IV_SIZE_V1]; // Validate arguments if (key == NULL || common_key == NULL || iv == NULL) { return; } - Copy(tmp, common_key, UDP_ACCELERATION_COMMON_KEY_SIZE); - Copy(tmp + UDP_ACCELERATION_COMMON_KEY_SIZE, iv, UDP_ACCELERATION_PACKET_IV_SIZE); + Copy(tmp, common_key, UDP_ACCELERATION_COMMON_KEY_SIZE_V1); + Copy(tmp + UDP_ACCELERATION_COMMON_KEY_SIZE_V1, iv, UDP_ACCELERATION_PACKET_IV_SIZE_V1); HashSha1(key, tmp, sizeof(tmp)); } @@ -887,7 +983,9 @@ bool UdpAccelInitServer(UDP_ACCEL *a, UCHAR *client_key, IP *client_ip, UINT cli } IPToStr(tmp, sizeof(tmp), client_ip); - Debug("UdpAccelInitServer: client_ip=%s, client_port=%u, server_cookie=%u, client_cookie=%u\n", tmp, client_port, + Debug("UdpAccelInitServer: ver=%u, client_ip=%s, client_port=%u, server_cookie=%u, client_cookie=%u\n", + a->Version, + tmp, client_port, a->MyCookie, a->YourCookie); if (IsIP6(client_ip) != a->IsIPv6) @@ -895,7 +993,14 @@ bool UdpAccelInitServer(UDP_ACCEL *a, UCHAR *client_key, IP *client_ip, UINT cli return false; } - Copy(a->YourKey, client_key, UDP_ACCELERATION_COMMON_KEY_SIZE); + if (a->Version == 2) + { + Copy(a->YourKey_V2, client_key, UDP_ACCELERATION_COMMON_KEY_SIZE_V2); + } + else + { + Copy(a->YourKey, client_key, UDP_ACCELERATION_COMMON_KEY_SIZE_V1); + } Copy(&a->YourIp, client_ip, sizeof(IP)); Copy(&a->YourIp2, client_ip_2, sizeof(IP)); @@ -919,14 +1024,22 @@ bool UdpAccelInitClient(UDP_ACCEL *a, UCHAR *server_key, IP *server_ip, UINT ser } IPToStr(tmp, sizeof(tmp), server_ip); - Debug("UdpAccelInitClient: server_ip=%s, server_port=%u, server_cookie=%u, client_cookie=%u\n", tmp, server_port, server_cookie, client_cookie); + Debug("UdpAccelInitClient: ver = %u, server_ip=%s, server_port=%u, server_cookie=%u, client_cookie=%u\n", + a->Version, tmp, server_port, server_cookie, client_cookie); if (IsIP6(server_ip) != a->IsIPv6) { return false; } - Copy(a->YourKey, server_key, UDP_ACCELERATION_COMMON_KEY_SIZE); + if (a->Version == 2) + { + Copy(a->YourKey_V2, server_key, UDP_ACCELERATION_COMMON_KEY_SIZE_V2); + } + else + { + Copy(a->YourKey, server_key, UDP_ACCELERATION_COMMON_KEY_SIZE_V1); + } Copy(&a->YourIp, server_ip, sizeof(IP)); Copy(&a->YourIp2, server_ip_2, sizeof(IP)); @@ -1008,6 +1121,8 @@ UDP_ACCEL *NewUdpAccel(CEDAR *cedar, IP *ip, bool client_mode, bool random_port, a->NoNatT = no_nat_t; + a->Version = 1; + a->NatT_TranId = Rand64(); @@ -1021,6 +1136,8 @@ UDP_ACCEL *NewUdpAccel(CEDAR *cedar, IP *ip, bool client_mode, bool random_port, a->UdpSock = s; Rand(a->MyKey, sizeof(a->MyKey)); Rand(a->YourKey, sizeof(a->YourKey)); + Rand(a->MyKey_V2, sizeof(a->MyKey_V2)); + Rand(a->YourKey_V2, sizeof(a->YourKey_V2)); Copy(&a->MyIp, ip, sizeof(IP)); a->MyPort = s->LocalPort; @@ -1035,6 +1152,7 @@ UDP_ACCEL *NewUdpAccel(CEDAR *cedar, IP *ip, bool client_mode, bool random_port, a->RecvBlockQueue = NewQueue(); Rand(a->NextIv, sizeof(a->NextIv)); + Rand(a->NextIv_V2, sizeof(a->NextIv_V2)); do { diff --git a/src/Cedar/UdpAccel.h b/src/Cedar/UdpAccel.h index 0c9dc32e..876c55e6 100644 --- a/src/Cedar/UdpAccel.h +++ b/src/Cedar/UdpAccel.h @@ -106,9 +106,14 @@ #define UDPACCEL_H // Constants -#define UDP_ACCELERATION_COMMON_KEY_SIZE 20 // Common key size -#define UDP_ACCELERATION_PACKET_KEY_SIZE 20 // Key size for the packet -#define UDP_ACCELERATION_PACKET_IV_SIZE 20 // IV size for the packet +#define UDP_ACCELERATION_COMMON_KEY_SIZE_V1 20 // V1: Common key size +#define UDP_ACCELERATION_PACKET_KEY_SIZE_V1 20 // V1: Key size for the packet +#define UDP_ACCELERATION_PACKET_IV_SIZE_V1 20 // V1: IV size for the packet + +#define UDP_ACCELERATION_COMMON_KEY_SIZE_V2 128 // V2: Common key size +#define UDP_ACCELERATION_PACKET_IV_SIZE_V2 12 // V2: IV size for the packet +#define UDP_ACCELERATION_PACKET_MAC_SIZE_V2 16 // V2: MAC size for the packet + #define UDP_ACCELERATION_TMP_BUF_SIZE 2048 // Temporary buffer size #define UDP_ACCELERATION_WINDOW_SIZE_MSEC (30 * 1000) // Receive window size (in milliseconds) @@ -142,8 +147,8 @@ struct UDP_ACCEL bool ClientMode; // Whether client mode bool IsInCedarPortList; // Whether included in the port list of the Cedar UINT64 Now; // Current time - UCHAR MyKey[UDP_ACCELERATION_COMMON_KEY_SIZE]; // Submit-direction common key - UCHAR YourKey[UDP_ACCELERATION_COMMON_KEY_SIZE]; // Receiving-direction common key + UCHAR MyKey[UDP_ACCELERATION_COMMON_KEY_SIZE_V1]; // Submit-direction common key + UCHAR YourKey[UDP_ACCELERATION_COMMON_KEY_SIZE_V1]; // Receiving-direction common key SOCK *UdpSock; // UDP socket UINT MyPort; // My port number UINT YourPort; // Port number of the other party @@ -160,7 +165,7 @@ struct UDP_ACCEL UINT64 LastSetSrcIpAndPortTick; // Opponent's tick ??value at the time of storing the IP address and port number of the opponent at the end UINT64 LastRecvTick; // Tick when data has received at the end UINT64 NextSendKeepAlive; // Next time to send a KeepAlive packet - UCHAR NextIv[UDP_ACCELERATION_PACKET_IV_SIZE]; // IV to be used next + UCHAR NextIv[UDP_ACCELERATION_PACKET_IV_SIZE_V1]; // IV to be used next UINT MyCookie; // My cookie UINT YourCookie; // Cookie of the other party bool Inited; // Initialized flag @@ -191,6 +196,11 @@ struct UDP_ACCEL UCHAR UdpIpQueryPacketData[16]; // Query packet data (final transmission) UINT UdpIpQueryPacketSize; // Query packet data size (final transmission) UCHAR UdpHostUniqueKey[SHA1_SIZE]; // Unique key for UDP self endpoint query + UINT Version; // Version + UCHAR MyKey_V2[UDP_ACCELERATION_COMMON_KEY_SIZE_V2]; // Submit-direction common key (Ver 2) + UCHAR YourKey_V2[UDP_ACCELERATION_COMMON_KEY_SIZE_V2]; // Receiving-direction common key (Ver 2) + UCHAR NextIv_V2[UDP_ACCELERATION_PACKET_IV_SIZE_V2]; // IV to be used next (Ver 2) + bool ReadRawFlagMode; // Read raw flag mode }; // Function prototype @@ -203,7 +213,7 @@ void UdpAccelSetTick(UDP_ACCEL *a, UINT64 tick64); BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip, UINT src_port); void UdpAccelCalcKey(UCHAR *key, UCHAR *common_key, UCHAR *iv); bool UdpAccelIsSendReady(UDP_ACCEL *a, bool check_keepalive); -void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, bool compressed, UINT max_size, bool high_priority); +void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, UCHAR flag, UINT max_size, bool high_priority); void UdpAccelSendBlock(UDP_ACCEL *a, BLOCK *b); UINT UdpAccelCalcMss(UDP_ACCEL *a); void NatT_GetIpThread(THREAD *thread, void *param); diff --git a/src/Cedar/VLanWin32.c b/src/Cedar/VLanWin32.c index 6cdc22ec..dae66a99 100644 --- a/src/Cedar/VLanWin32.c +++ b/src/Cedar/VLanWin32.c @@ -367,8 +367,8 @@ void RouteTrackingMain(SESSION *s) if (IPToUINT(&e->DestIP) == 0 && IPToUINT(&e->DestMask) == 0) { - Debug("e->InterfaceID = %u, t->VLanInterfaceId = %u\n", - e->InterfaceID, t->VLanInterfaceId); + //Debug("e->InterfaceID = %u, t->VLanInterfaceId = %u\n", + // e->InterfaceID, t->VLanInterfaceId); if (e->InterfaceID == t->VLanInterfaceId) { diff --git a/src/CurrentBuild.txt b/src/CurrentBuild.txt index 2be2e762..3d94c7e4 100644 --- a/src/CurrentBuild.txt +++ b/src/CurrentBuild.txt @@ -1,4 +1,4 @@ -BUILD_NUMBER 9680 -VERSION 429 -BUILD_NAME rtm -BUILD_DATE 20190228_183947 +BUILD_NUMBER 9695 +VERSION 430 +BUILD_NAME beta +BUILD_DATE 20190707_195808 diff --git a/src/Ham/generated_manual_cn.html b/src/Ham/generated_manual_cn.html new file mode 100644 index 00000000..4ccc1725 --- /dev/null +++ b/src/Ham/generated_manual_cn.html @@ -0,0 +1,9861 @@ + + + + + + + + + + +------ 1 ------ + + + + + + + + + +

6.3.1 "About": 显示版本信息

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + About
命令的概要 + 显示版本信息
说明 + 这显示了此命令行管理工具的版本信息。版本信息中包括了 vpncmd 版本号,内部标号和内部标号信息。
命令行格式 + About
"About" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.2 "ServerInfoGet": 获取服务器信息

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ServerInfoGet
命令的概要 + 获取服务器信息
说明 + 这使您可以获取当前连接的 VPN Server 或 VPN Bridge 的服务器信息。服务器信息中包括版本号,内部标号和内部标号信息。您还可以获取当前服务器运行模式的信息和服务器上运行的操作系统信息。
命令行格式 + ServerInfoGet
"ServerInfoGet" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.3 "ServerStatusGet": 获取当前服务器状态

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ServerStatusGet
命令的概要 + 获取当前服务器状态
说明 + 这使您可以实时获取当前连接的 VPN Server 或 VPN Bridge 的现状。您可以得到关于数据通信和服务器上存在的不同类型对象数量的统计资料。您可以得到当前计算机所使用的操作系统内存多少的信息。
命令行格式 + ServerStatusGet
"ServerStatusGet" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.4 "ListenerCreate": 创建新的 TCP 监听器

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ListenerCreate
命令的概要 + 创建新的 TCP 监听器
说明 + 这使您可以在服务器上创建一个新的 TCP 监听器。通过建立 TCP 监听器,服务器开始在指定的 TCP/IP 端口连接监听。
已创建的 TCP 监听器可以被 ListenerDelete 命令删除。
您还可以得到一个当前使用 ListenerList 命令登记的 TCP 侦听器列表。
要执行这个命令,您必须有 VPN Server 管理员权限。
命令行格式 + ListenerCreate [port]
"ListenerCreate" 命令中可以指定的参数引数的一览:
port + 使用一个整数,指定新添加的 TCP/IP 监听端口号。您也可以使用一个已经被其他程序使用的端口号; 但 VPN Server 将无法使用,直到该程序结束了在端口的使用。指定一个范围从 1 到 65535 的端口号。
+

 

+

6.3.5 "ListenerDelete": 删除 TCP 监听器

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ListenerDelete
命令的概要 + 删除 TCP 监听器
说明 + 这允许您删除一个在服务器上已注册的 TCP 侦听器。当 TCP 监听器在运行状态,当运行停止时,监听器将被自动删除。
您还可以得到一个当前使用 ListenerList 命令登记的 TCP 监听器列表。
为了执行这个命令,您必须有 VPN Server 管理员权限。
命令行格式 + ListenerDelete [port]
"ListenerDelete" 命令中可以指定的参数引数的一览:
port + 使用一个整数,指定要删除的 TCP/IP 监听器端口号。
+

 

+

6.3.6 "ListenerList": 获取 TCP 监听器列表

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ListenerList
命令的概要 + 获取 TCP 监听器列表
说明 + 这使您可以获取的 TCP 侦听器列表当前服务器上注册。您可以获取有关各种 TCP 监听器的运行状态或错误的信息。
执行这个命令,您必须有 VPN Server 管理员权限。
命令行格式 + 监听器列表
"ListenerList" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.7 "ListenerEnable": 开始 TCP 监听器运行

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ListenerEnable
命令的概要 + 开始 TCP 监听器运行
说明 + 这将启动在当前服务器上注册的停止 TCP 监听器的运行。
您还可以得到一个当前使用 ListenerList 命令注册的 TCP 监听器列表。
为了执行这个命令,您必须有 VPN Server 管理员权限。
命令行格式 + ListenerEnable [port]
"ListenerEnable" 命令中可以指定的参数引数的一览:
port + 使用一个整数,指定要启动的 TCP/IP 监听器端口号。
+

 

+

6.3.8 "ListenerDisable": 停止 TCP 监听器运行

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ListenerDisable
命令的概要 + 停止 TCP 监听器运行
说明 + 这将停止在当前服务器上注册的 TCP 监侦听器的运行。
您还可以得到一个当前使用 ListenerList 命令注册的 TCP 监听器列表。
为了执行这个命令,您必须有 VPN Server 管理员权限。
命令行格式 + ListenerDisable [port]
"ListenerDisable" 命令中可以指定的参数引数的一览:
port + 使用一个整数,指定要停止的 TCP/IP 监听器端口号。
+

 

+

6.3.9 "ServerPasswordSet": 设置 VPN Server 管理员密码

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ServerPasswordSet
命令的概要 + 设置 VPN Server 管理员密码
说明 + 这将设置 VPN Server 管理员密码。您可以指定密码为一个参数。如果密码没有指定,将显示提示输入密码和密码确认。如果指定密码为一个参数,这个密码将在屏幕上显示瞬间,这构成了风险。我们建议尽可能避免指定这个参数,使用密码提示输入密码。
为了执行这个命令,您必须有 VPN Server 管理员权限。
命令行格式 + ServerPasswordSet [password]
"ServerPasswordSet" 命令中可以指定的参数引数的一览:
password + 指定一个新的密码设置。
+

 

+

6.3.10 "ClusterSettingGet": 获取当前 VPN Server 群集配置

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ClusterSettingGet
命令的概要 + 获取当前 VPN Server 群集配置
说明 + 你可以用它来获取当前 VPN Server 的群集配置。
为了执行这个命令,您必须有 VPN Server 管理员权限。
命令行格式 + ClusterSettingGet
"ClusterSettingGet" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.11 "ClusterSettingStandalone": 设置为独立的 VPN Server 类型

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ClusterSettingStandalone
命令的概要 + 设置为独立的 VPN Server 类型
说明 + 使用此设置 VPN Server 类型为 [独立服务器]。独立服务器指 VPN Server 在当前状态下不属于任何群集。当 VPN Server 安装后,默认情况下为独立的服务器模式。除非你有特别的计划来配置群集,我们建议 VPN Server 以独立模式运行。
为了执行这个命令,您必须有 VPN Server 管理员权限。
还有,当这个命令执行时,VPN Server 会自动重新启动。
此命令不能在 VPN Bridge 上运行。
命令行格式 + ClusterSettingStandalone
"ClusterSettingStandalone" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.12 "ClusterSettingController": 设置 VPN Server 类型为群集控制器

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ClusterSettingController
命令的概要 + 设置 VPN Server 类型为群集控制器
说明 + 使用此设置 VPN Server 类型为 [群集控制器]。群集控制器是一个群集的所有成员服务器的中央电脑,群集环境是由多个 VPN Server 构成。一个群集需要一台电脑成为这个角色。在同一群集配置里的其他群集成员服务器,是通过连接到群信控制器作为群集成员开始运行的。
为了执行这个命令,您必须有 VPN Server 管理员权限。
还有,当这个命令执行时刻,VPN Server 会自动重新启动。
此命令不能在 VPN Bridge 上运行。
命令行格式 + ClusterSettingController [/WEIGHT:weight] [/ONLY:yes|no]
"ClusterSettingController" 命令中可以指定的参数引数的一览:
/WEIGHT + 这设置了这个 VPN Server 的性能标准比值。这是在群集负载平衡中执行的标准值。一般而言,这个值是 100。例如,仅设置一台机器为 200,而其他成员机器为 100,在负载平衡期间,将调节这台机器收到其他成员两倍的连接数。指定 1 或更高的值。如果此参数未指定,将使用 100。
/ONLY + 通过在这里指定 "yes",VPN Server 在群集里仅作为一个控制器运行,并总是分配一般 VPN Client 连接给到自身以外的成员。此功能用于高负载的环境。如果此参数未指定,"no" 将被使用。
+

 

+

6.3.13 "ClusterSettingMember": VPN Server 类型设置为群集成员

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ClusterSettingMember
命令的概要 + VPN Server 类型设置为群集成员
说明 + 使用此设置 VPN Server 类型,[群集成员服务器]。一个群集成员服务器是成员的计算机属于群集配置由多个 VPN Server 与另一个中心现有群集控制器。集群成员可以根据需要任意添加到群集。
在设置为群集成员服务器的 VPN Server,群集控制器管理员要为控制器的 IP 地址和端口号使用,需要知道公共 IP 地址和公共端口号 (必要时本 VPN Server) 和密码。
要执行这个命令,您必须拥有 VPN Server 管理员权限。
另外,在执行此命令,VPN Server 会自动重新启动。
此命令不能运行的 VPN Bridge。
命令行格式 + ClusterSettingMember [server:port] [/IP:ip] [/PORTS:ports] [/PASSWORD:password] [/WEIGHT:weight]
"ClusterSettingMember" 命令中可以指定的参数引数的一览:
server:port + 按照 [主机名:端口号] 的形式,设定目的地群集控制器的主机名,IP 地址,端口号等。
/IP + 指定该服务器的公用 IP 地址。如果不指定公用 IP 地址,请设定 "/IP:none"。当 IP 地址没有指定,将自动使用的网络接口的 IP 地址连接到群集控制器。
/PORTS + 指定服务器的公开端口一览。该清单必须至少有一个公共端口号设置,也可以设置多个公共端口号。当指定多个端口号,例如 "/PORTS:443,992,8888" 中间用逗号分开。
/PASSWORD + 指定连接到目标控制器的密码。它与目标控制器管理密码是相同的。
/WEIGHT + 这设定了一个表现这个 VPN Server 的标准比率值。这是负载平衡集群中执行的标准值。一般而言,这个值是 100。例如,只有一台机器是 200,而其他成员是 100 个单位,将规范这台机器得到像其他许多成员期间两次连接负载平衡。指定 1 或更高的值。如果此参数未指定,将使用 100。
+

 

+

6.3.14 "ClusterMemberList": 获得群集成员名单

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ClusterMemberList
命令的概要 + 获得群集成员名单
说明 + 使用此命令时,VPN Server 作为群集控制器操作获得对相同的群集群集成员服务器,包括群集控制器本身的列表。
若需每个成员,下面的信息也被列入。 [类型],[连线开始],[主机名],[点],[会期号码],[TCP 连接数],[虚拟的作业站数目],[使用客户端连接许可证],[使用大桥连接许可证]。
此命令不能运行在 VPN Bridge。
命令行格式 + ClusterMemberList
"ClusterMemberList" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.15 "ClusterMemberInfoGet": 会员信息的获取

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ClusterMemberInfoGet
命令的概要 + 会员信息的获取
说明 + 当 VPN Server 作为群集控制器操作,您就可以通过指定的集的成员服务器 ID 获得在群集成员的信息。
您可以得到有关指定群集成员服务器上的以下信息: ]服务器类型]、],[已建立连接的时间],[IP 地址],[主机名],[点],[公共端口列表],[操作中的虚拟 HUB],[第一虚拟 HUB],[会话数],[TCP 连接数]。
此命令不能运行在 VPN Bridge。
命令行格式 + ClusterMemberInfoGet [id]
"ClusterMemberInfoGet" 命令中可以指定的参数引数的一览:
id + 指定想获信息的取群集成员的 ID。ID 地址可以在 ClusterMemberList 中获得。
+

 

+

6.3.16 "ClusterMemberCertGet": 获得群集成员证书

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ClusterMemberCertGet
命令的概要 + 获得群集成员证书
说明 + 当 VPN Server 作为群集控制器操作,您就可以通过指定的群集这些成员服务器的 ID 的群集成员服务器获取公共 X.509 证书。您可以保存为 X.509 格式文件。
此命令不能在 VPN Bridge 中运行。
命令行格式 + ClusterMemberCertGet [id] [/SAVECERT:cert]
"ClusterMemberCertGet" 命令中可以指定的参数引数的一览:
id + 指定获取证书所需的群集的成员的 ID。此 ID 可以群集成员使用 ClusterMemberList 中获得。
/SAVECERT + 指定路径以保存您获得的证书。证书被保存为 X.509 格式。
+

 

+

6.3.17 "ClusterConnectionStatusGet": 获得群集控制器的连接状态的信息

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ClusterConnectionStatusGet
命令的概要 + 获得群集控制器的连接状态的信息
说明 + 使用此命令时,VPN Server 作为群集控制器操作来获得连接状态的群集控制器。
您可以得到以下信息: [控制器 IP 地址],[端口号],[连接状态],[连线开始时间],[第一个连接成立时间],[当前连接成立时间],[的连接尝试次数],[成功连接次数],[连接失败次数]。
此命令不能运行在 VPN Bridge。
命令行格式 + ClusterConnectionStatusGet
"ClusterConnectionStatusGet" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.18 "ServerCertGet": 获得 VPN Server 的 SSL 证书

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ServerCertGet
命令的概要 + 获得 VPN Server 的 SSL 证书
说明 + VPN Server,取得连接客户机所需的 SSL 证书。证书可以保存为 X.509 的格式。
命令行格式 + ServerCertGet [cert]
"ServerCertGet" 命令中可以指定的参数引数的一览:
cert + 获得的证书指定文件保存路径,以 X.509 的形式保存。
+

 

+

6.3.19 "ServerKeyGet": 获取 VPN Server SSL 证书的密钥

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ServerKeyGet
命令的概要 + 获取 VPN Server SSL 证书的密钥
说明 + VPN Server,为已连接客户提供获得证书的密钥。密钥可以存储为 Base 64 的编码文件。
为了运行此命令,VPN Server 需要管理员的权限。
命令行格式 + ServerKeyGet [key]
"ServerKeyGet" 命令中可以指定的参数引数的一览:
key + 指定文件的路径名来存储已获得的密钥。将密钥存储为 Base 64 编码。
+

 

+

6.3.20 "ServerCertSet": VPN Server 的 SSL 证书和密钥的设置

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ServerCertSet
命令的概要 + VPN Server 的 SSL 证书和密钥的设置
说明 + 设置已连接 VPN Server 的客户端所需的 SSL 证书,以及跟证书相对应的密钥。证书为 X.509 格式,密钥为 Base 64 编码格式。
为了运行此命令,需要有 VPN Server 管理员权限。
命令行格式 + ServerCertSet [/LOADCERT:cert] [/LOADKEY:key]
"ServerCertSet" 命令中可以指定的参数引数的一览:
/LOADCERT + 指定要使用的 X.509 格式的证书文件。
/LOADKEY + 指定格式为 Base 64 编码并且与证书对应的密钥文件。
+

 

+

6.3.21 "ServerCipherGet": 获取 VPN 通信中使用的加密程序

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ServerCipherGet
命令的概要 + 获取 VPN 通信中使用的加密程序
说明 + 您可以获取 VPN Server 和客户端之间进行通信时使用的 SSL 加密,电子签名等,以及在 VPN Server 上的程序列表。
命令行格式 + ServerCipherGet
"ServerCipherGet" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.22 "ServerCipherSet": 设置 VPN 通讯中使用的加密程序,

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ServerCipherSet
命令的概要 + 设置 VPN 通讯中使用的加密程序,
说明 + 您可以设置 VPN Server 和客户端在通讯中应用的 SSL 加密连接,电子签名等应用程序。
如果您指定程序的名称,以后和 VPN Server 连接的 VPN Client,VPN Bridge 之间的将应用指定程序,数据将被加密。
运行此命令,需要 VPN Server 管理员的权限。
命令行格式 + ServerCipherSet [name]
"ServerCipherSet" 命令中可以指定的参数引数的一览:
name + 指定设置加密和数字签名的程序。可以使用的程序一览,可以从 ServerCipherGet 指令中获取。
+

 

+

6.3.23 "Debug": 执行调试命令

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + Debug
命令的概要 + 执行调试命令
说明 + 在运行的 VPN Server / Bridge 进程上运行调试命令。
此命令在支持人员请求这么做时执行。
错误使用此命令,很可能造成 VPN Server / Bridge 运行崩溃。
命令行格式 + Debug [id] [/ARG:arg]
"Debug" 命令中可以指定的参数引数的一览:
id + 指定一个调试命令序号。
/ARG + 指定一个字符串传递给调试命令。如果该字符串包含空格,并且整个命令都包含在" "内。
+

 

+

6.3.24 "Crash": 出现一个错误的 VPN Server / Bridge 强行终止该进程。

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + Crash
命令的概要 + 出现一个错误的 VPN Server / Bridge 强行终止该进程。
说明 + 此命令会在 VPN Server / Bridge 的进程中产生一个严重的错误(内存访问冲突),从而会导致进程崩溃。于是,在服务模式下的 VPN Server / Bridge 将会终止并重启。如果 VPN Server 在用户模式下运行,进程将不会自动重启。
本命令适用于:当 VPN Server / Bridge 处于一个不可恢复的错误或者进程无限循环时。此命令将断开所有 VPN Server / Bridge 上的 VPN 会话。所有在 VPN Server / Bridge 内存中未保存的设置将会丢失。
在运行此命令前,运行"Flush" 命令来把不稳定的数据保存在配置文件中。
要执行此命令,您必须具有 VPN Server / Bridge 的管理员权限。
命令行格式 + Crash [yes]
"Crash" 命令中可以指定的参数引数的一览:
yes + 确认请输入 "yes"
+

 

+

6.3.25 "Flush": 保存 VPN Server / Bridge 全部不稳定数据到配置文件。

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + Flush
命令的概要 + 保存 VPN Server / Bridge 全部不稳定数据到配置文件。
说明 + 通常,不稳定设置数据会保存在 VPN Server / Bridge 的内存中。它定期以 vpn_server.config 或者 vpn_bridge.config 刷新硬盘。默认周期是 300 秒(5 分钟)。(周期长度可以在配置文件中,通过修改 AutoSaveConfigSpan 进行改变。)数据会在正常关闭 VPN Server / Bridge 时保存。
执行 Flush 命令使 VPN Server / Bridge 立即保存设置至文件。此设置数据将被保存在服务器计算机的磁盘驱动中。在您没有足够时间正常关闭服务器进程的情况下,使用 Flush 命令。
执行此命令,您必须有 VPN Server 管理员权限。
执行此命令,您必须有 VPN Server / Bridge 的管理员权限。
命令行格式 + Flush
"Flush" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.26 "KeepEnable": 启动 Internet 保持连接功能

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + KeepEnable
命令的概要 + 启动 Internet 保持连接功能
说明 + 启动 [互联网保持连接功能]。启动此功能后,如果一段时间没有通信数据,导致连接将被断开时,会自动发送数据包到任何服务器,互联网服务器一定的间隔,从而可以保持连接。
目标主机名等,可以通过 KeepSet 指令来设置。
VPN Server 或 VPN Bridge 运行此命令时,您必须具有管理员的权限。
命令行格式 + KeepEnable
"KeepEnable" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.27 "KeepDisable": 禁用保持互联网连接功能

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + KeepDisable
命令的概要 + 禁用保持互联网连接功能
说明 + 解除 [保持互联网连接功能]。
VPN Server 或 VPN Bridge 运行此命令,您必须具有管理员权限。
命令行格式 + KeepDisable
"KeepDisable" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.28 "KeepSet": 设置 Internet 保持连接功能

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + KeepSet
命令的概要 + 设置 Internet 保持连接功能
说明 + 设置 [保持互联网连接功能] 的目标主机名。 如果一段时间没有任何通信数据,连接将被断开时,使用 [保持互联网连接功能 ] 可以,设定时间向 Internet 上的任何服务器发送数据包,从而可以保持您的 Internet 连接。
在此功能中,可以设置目标 [主机名],[端口号],[数据包发送时间间隔],以及 [协议]。
发送的数据包为随机内容,不会讲计算机和个人的识别信息发送。
保持 Internet 连接功能,可以通过 KeepEnable 命令,或使用命令 KeepDisable,实现启用 / 禁用。不可以用 KeepSet 来改变启用 / 禁用的状态。
VPN Server 或 VPN Bridge 运行此命令,您必须具有管理员权限。
命令行格式 + KeepSet [/HOST:host:port] [/PROTOCOL:tcp|udp] [/INTERVAL:interval]
"KeepSet" 命令中可以指定的参数引数的一览:
/HOST + 用 [主机:端口] 的格式,来设定目标主机名或 IP 地址和端口号。
/PROTOCOL + 设定 tcp 或 udp。
/INTERVAL + 以秒为单位设定发送数据包之间的间隔时间。
+

 

+

6.3.29 "KeepGet": 获取保持互联网连接的功能

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + KeepGet
命令的概要 + 获取保持互联网连接的功能
说明 + 获取 [保持互联网连接功能] 的当前设置。可以得到 [主机名],[端口],[数据包发送时间间隔],和 [协议],还包括当前 [保持互联网连接功能] 是否启用的当前状态。
命令行格式 + KeepGet
"KeepGet" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.30 "SyslogEnable": 设置发送系统日志功能

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + SyslogEnable
命令的概要 + 设置发送系统日志功能
说明 + 使用 syslog 发送系统日志的使用方法和服务器的设置。
命令行格式 + SyslogEnable [1|2|3] [/HOST:host:port]
"SyslogEnable" 命令中可以指定的参数引数的一览:
1|2|3 + 使用 syslog 功能 1 - 3 来进行设置。 +1: 发送 syslog 服务器日志。 +2: 发送服务器和虚拟 HUB 安全系统日志。 +3: 服务器,虚拟 HUB 安全和数据包发送系统日志记录枢纽。
/HOST + 按照 [主机:端口] 的形式,设定系统日志服务器主机名或 IP 地址和端口号。如果省略端口号使用 514。
+

 

+

6.3.31 "SyslogDisable": 禁用发送系统日志的功能

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + SyslogDisable
命令的概要 + 禁用发送系统日志的功能
说明 + 解除系统日志的传送功能。
命令行格式 + SyslogDisable
"SyslogDisable" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.32 "SyslogGet": 取得发送系统日志的功能

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + SyslogGet
命令的概要 + 取得发送系统日志的功能
说明 + 获取 syslog 发送功能的当前设置。您可以设置系统日志功能的使用方法,可以获取 syslog 服务器的主机名和端口号。
命令行格式 + SyslogGet
"SyslogGet" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.33 "ConnectionList": 获取与 VPN Server 相连的 TCP 连接一览

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ConnectionList
命令的概要 + 获取与 VPN Server 相连的 TCP 连接一览
说明 + 现在,先获取与 VPN Server 连接的 TCP/IP 一览表。但是,VPN 会话作为 TCP/IP 连接不显示。VPN 会话建立的 TCP/IP 连接一览表,何以运用 SessionList 命令获得。
可以获取 [连接名称], [原始连接], [连接时间] 和 [类型]。
要运行此命令,VPN Server 需要管理员权限。
命令行格式 + ConnectionList
"ConnectionList" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.34 "ConnectionGet": 获取连接到 VPN Server 的 TCP 信息一览表

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ConnectionGet
命令的概要 + 获取连接到 VPN Server 的 TCP 信息一览表
说明 + 获取与 VPN Server 连接的 TCP/IP 连接的详细信息。
可以获得 [连接名],[连接种类],[连接主机名],[连接主机 IP],[联机主机端口 TCP],[连接时间],[服务器品牌],[服务器版本],[服务器铭牌号],[客户机品牌],[客户机版本],[客户机铭牌号] 等信息。
要运行此命令,需要管理员权限。
命令行格式 + ConnectionGet [name]
"ConnectionGet" 命令中可以指定的参数引数的一览:
name + 指定希望获取信息的连接名称。所有连接的一览表,可以通过 ConnectionList 命令获得。
+

 

+

6.3.35 "ConnectionDisconnect": 断开 VPN Server 和 TCP 的连接

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ConnectionDisconnect
命令的概要 + 断开 VPN Server 和 TCP 的连接
说明 + 强制切断 VPN Server 和指定的 TCP/IP 的连接。
运行此命令,需要管理员权限。
命令行格式 + ConnectionDisconnect [name]
"ConnectionDisconnect" 命令中可以指定的参数引数的一览:
name + 选定希望切断的连接。连接的名称可以从 ConnectionList 命令中获得。
+

 

+

6.3.36 "BridgeDeviceList": 获取可以在当地的网桥上使用的 LAN 卡一览

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + BridgeDeviceList
命令的概要 + 获取可以在当地的网桥上使用的 LAN 卡一览
说明 + 使用当地网桥连接,获取目标桥中可以使用的设备 (LAN 卡) 列表。
在此显示的设备名字,BridgeCreate 命令都可以使用。
为了运行此命令,需要管理员权限。
命令行格式 + BridgeDeviceList
"BridgeDeviceList" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.37 "BridgeList": 获得当地网桥连接列表

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + BridgeList
命令的概要 + 获得当地网桥连接列表
说明 + 获取当地定义的网桥连接列表。
可以获取当地网桥连接的虚拟 HUB 名称,目标太网桥连接器件 (LAN 卡) 的名称,或可以获取设备的名称和工作状态。
命令行格式 + BridgeList
"BridgeList" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.38 "BridgeCreate": 创建本地的网桥连接

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + BridgeCreate
命令的概要 + 创建本地的网桥连接
说明 + 在 VPN Server 上创建新的本地网桥连接的。
当您使用一个本地的网桥,这个虚拟 HUB 和物理以太网设备 (LAN 卡在两层) 之间可以创建网桥连接。
在系统中创建 tap 设备 (虚拟网络接口),可以与虚拟 HUB 建立连接 (tap 设备仅支持 Linux)。
目的地以太网桥设备 (LAN 卡) 可以连接到您的任何运行的 LAN 卡,但是高负荷环境的网桥,建议您准备专用的 LAN 卡。
要运行此命令,需要管理员权限。
命令行格式 + BridgeCreate [hubname] [/DEVICE:device_name] [/TAP:yes|no]
"BridgeCreate" 命令中可以指定的参数引数的一览:
hubname + 选定虚拟 HUB 的网桥。虚拟 HUB 列表,可以通过 HubList 命令获得。但是,没有必要一定要选定目前正在运行的虚拟 HUB,即使选定目前没有工作,或不存在的虚拟名称的 HUB,当它真正工作时,它与虚拟本地网桥就会建立连接。
/DEVICE + 设定目标以太网桥设备 (LAN 卡) 的名称,或 tap 设备的名称。以太网设备名单,可以通过运行 BridgeDeviceList 命令得到。
/TAP + 网桥连接局域网,不使用 LAN 卡,而是使用 tap 设备时,选定 yes,如果您使用的设备指定 (只支持 Linux)。如果省略,默认为 no。
+

 

+

6.3.39 "BridgeDelete": 删除本地网桥连接

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + BridgeDelete
命令的概要 + 删除本地网桥连接
说明 + 删除现有的当地网桥连接。当地网桥梁连接的列表,可以通过 BridgeDeviceList 命令得到。
运行此命令,需要服务器管理员权限。
命令行格式 + BridgeDelete [hubname] [/DEVICE:device_name]
"BridgeDelete" 命令中可以指定的参数引数的一览:
hubname + 选定被删除的当地网桥的虚拟 HUB。
/DEVICE + 选定被删除的当地的网桥的设备名 (LAN 卡的名称或 tap 设备的名称)。
+

 

+

6.3.40 "Caps": 获得服务器的功能性能一览表

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + Caps
命令的概要 + 获得服务器的功能性能一览表
说明 + 取得现在正在连接使用的 VPN Server 的功能和性能的清单。
VPN Server 的功能和性能取决于服务器的版本。指令清单中的指令也可能因为对方的服务器的功能,而无法工作。因此此命令需调查目标服务器的功能。
如果 VPN Server 的版本比命令行管理工具的版本新,存在不掌握的指令时,其内部的字符串 (变量名),但可能原原本本的表示出来。
命令行格式 + Caps
"Caps" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.41 "Reboot": VPN Server 服务重新启动

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + Reboot
命令的概要 + VPN Server 服务重新启动
说明 + VPN Server 重新启动该服务。
VPN Server 重新启动服务,目前连接的会话和 TCP 连接都将被切断,直道建立新的连接。
此命令,VPN Server,只是重新启动服务程序,而不是重新启动计算机。这种管理的连接也会断开,如果需要请重新建立连接。
此外,/RESETCONFIG:yes 指定参数,并对 VPN Server 的系统内容 (.config) 进行初始化。
要运行此命令,VPN Server需要管理员权限。
命令行格式 + Reboot [/RESETCONFIG:yes|no]
"Reboot" 命令中可以指定的参数引数的一览:
/RESETCONFIG + 选定 yes,对当前的 VPN Server 的系统内容 (.config) 初始化。请谨慎设置此参数。
+

 

+

6.3.42 "ConfigGet": 获取 VPN Server 当前系统配置

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ConfigGet
命令的概要 + 获取 VPN Server 当前系统配置
说明 + 获取 VPN Server 当前 (.config 文件) 系统结构化文本保存的文本文件,你可以检索到 VPN Server 执行这个指令的瞬间状态。
系统内容的文件,如果不指定参数,会在屏幕上直接显示。如果您指定参数保存,会保存为一个指定的文件名。
配置文件可以使用普通的文本编辑器编辑。编辑好的文件要写入 VPN Server,需执行 ConfigSet 命令。
要运行此命令,VPN Server 需要管理员权限。
命令行格式 + ConfigGet [path]
"ConfigGet" 命令中可以指定的参数引数的一览:
path + 如果你想保存配置文件,请指定文件名。如果没有指定,配置的内容将以画面形式显示在屏幕上。如果配置是多字字符的,请转变成 Unicode (UTF-8) 编码存储。
+

 

+

6.3.43 "ConfigSet": 往 VPN Server 上写入系统配置内容

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ConfigSet
命令的概要 + 往 VPN Server 上写入系统配置内容
说明 + 往 VPN Server 上写入系统配置内容。这样,您选定的系统配置内容会适用于 VPN Server,VPN Server 程序会自动重启,新的系统配同配置开始工作。
对系统管理者来说,要记录所有的系统配置的文件是比较困难的。因此建议使用 ConfigGet 命令,先获取当前的 VPN Server 的系统配置内容保存成文件,再将此文件加以编辑,然后用 ConfigSet 命令写入 VPN Server。
这个操作,需要对 VPN Server 充分的了解,如果写入了不正确的系统配置信息,系统将发生错误,甚至可能丢失现在的设置内容。请务必小心操作。
执行这个命令,需要 VPN Server 的管理员权限。
命令行格式 + ConfigSet [path]
"ConfigSet" 命令中可以指定的参数引数的一览:
path + 指定配置文件的名称。如果文件有多种文字,请先变化成 Unicode (UTF-8) 格式。
+

 

+

6.3.44 "RouterList": 获取虚拟 3 层交换机列表

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + RouterList
命令的概要 + 获取虚拟 3 层交换机列表
说明 + 在 VPN Server 上获取 3 层虚拟交换机的清单。获取虚拟 3 层交换机的 [交换机名称],[工作状态],[接口数量],[路由数目] 等信息。
要运行此命令,需要 VPN Server 管理员权限。
此外,此命令不能在 VPN Bridge 中运行。
命令行格式 + RouterList
"RouterList" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.45 "RouterAdd": 定义一个新的虚拟 3 层交换机

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + RouterAdd
命令的概要 + 定义一个新的虚拟 3 层交换机
说明 + 在 VPN Server 上定义一个新的 3 层虚拟交换机。
要运行此命令,需要 VPN Server 管理员权限。
此外,此命令不能在 VPN Bridge 中运行。

[虚拟 3 层交换机功能的说明]
在这个虚拟 VPN Server 上运行的多个虚拟 HUB 之间,可以通过定义的虚拟 3 层交换机,实现不同 IP 地址之间的路由。

[虚拟 3 层交换机功能的注意事项]
虚拟 3 层交换机功能是基于对网络和 IP 路由熟悉的人或者是网络管理员使用的。如果您使用正常的 VPN 功能,您没有必要使用虚拟 3 层交换机。
如果您使用虚拟 3 层交换机的功能,请您务必要十分熟悉 IP 路由方面的知识,并十分清楚您的设置将对网络产生的影响。
命令行格式 + RouterAdd [name]
"RouterAdd" 命令中可以指定的参数引数的一览:
name + 创建一个新的虚拟 3 层交换机的名称。新创建的名称与现有的名称是不能相同。
+

 

+

6.3.46 "RouterDelete": 删除虚拟 3 层交换机

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + RouterDelete
命令的概要 + 删除虚拟 3 层交换机
说明 + 删除在 VPN Server 上已定义的 3 层虚拟交换机。如果选定的虚拟 3 层交换机正在运行,它将停止工作,然后自动删除。
获取虚拟 3 层交换机的清单,可以使用 RouterList 命令。
要运行此命令,需要 VPN Server 管理员权限。
此外,此命令不能在 VPN Bridge 中运行。
命令行格式 + RouterDelete [name]
"RouterDelete" 命令中可以指定的参数引数的一览:
name + 选定想要删除的虚拟 3 层交换机的名称。
+

 

+

6.3.47 "RouterStart": 开始运行虚拟 3 层交换机

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + RouterStart
命令的概要 + 开始运行虚拟 3 层交换机
说明 + VPN Server 上已经存在的虚拟 3 层交换机,如果处于停止工作工作状态,将开始运行。
获取当前的虚拟 3 层交换机清单,可以执行 RouterList 命令。
要运行此命令,需要 VPN Server 管理员权限。
此外,此命令不能在 VPN Bridge 运行。

[虚拟 3 层交换机功能的说明]
在这个虚拟 VPN Server 上运行的多个虚拟 HUB 之间,可以通过定义的虚拟 3 层交换机,实现不同 IP 地址之间的路由。

[虚拟 3 层交换机功能的注意事项]
虚拟 3 层交换机功能是基于对网络和 IP 路由熟悉的人或者是网络管理员使用的。如果您使用正常的 VPN 功能,您没有必要使用虚拟 3 层交换机。
如果您使用虚拟 3 层交换机的功能,请您务必要十分熟悉 IP 路由方面的知识,并十分清楚您的设置将对网络产生的影响。
命令行格式 + RouterStart [name]
"RouterStart" 命令中可以指定的参数引数的一览:
name + 选定即将启动的虚拟 3 层交换机的名称。
+

 

+

6.3.48 "RouterStop": 停止虚拟 3 层交换机的运行

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + RouterStop
命令的概要 + 停止虚拟 3 层交换机的运行
说明 + 在 VPN Server 上已定义的虚拟 3 层交换机,如果正在运行,它将停止运行。
想要获取现有的虚拟 3 层交换机清单,可以运行 RouterList 命令。
要运行此命令,需要 VPN Server 管理员权限。
命令行格式 + RouterStop [name]
"RouterStop" 命令中可以指定的参数引数的一览:
name + 选定想要停止运行的虚拟 3 层交换机的名称。
+

 

+

6.3.49 "RouterIfList": 获取在虚拟 3 层交换机中注册的远程接口的清单

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + RouterIfList
命令的概要 + 获取在虚拟 3 层交换机中注册的远程接口的清单
说明 + 如果在指定的虚拟 3 层交换机上有已经定义的虚拟远程接口,您将会获取一个虚拟接口列表。
在一个虚拟 3 层交换机上,您可以定义多个虚拟接口和路由表。
虚拟接口与虚拟 HUB 相互关联,当虚拟 HUB 运行时,虚拟接口就像一个虚拟 IP 主机在工作。相对于多个 IP 虚拟 HUB,如果定义分属不同网络的多个远程接口时,IP 路由会自动运行。
要运行此命令,需要 VPN Server 管理员权限。
此外,此命令不能在 VPN Bridge 中运行。
命令行格式 + RouterIfList [name]
"RouterIfList" 命令中可以指定的参数引数的一览:
name + 选定虚拟 3 层交换机的名称。
+

 

+

6.3.50 "RouterIfAdd": 在虚拟 3 层交换机上添加一个虚拟远程接口

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + RouterIfAdd
命令的概要 + 在虚拟 3 层交换机上添加一个虚拟远程接口
说明 + 指定的 3 层虚拟交换机,为它添加一个在同一个 VPN Server 上运行的虚拟 HUB 的连接虚拟接口。
一个指定的 3 层虚拟交换机,您可以定义多个虚拟接口和路由表。
虚拟接口与虚拟 HUB 相互关联,当虚拟 HUB 运行时,虚拟接口就像一个虚拟 IP 主机在工作。相对于多个 IP 虚拟 HUB,如果定义分属不同网络的多个远程接口时,IP 路由会自动运行。
虚拟接口的 IP 网络空间,虚拟接口的 IP 地址必须被定义。
虚拟接口必须制定目标连接的虚拟 HUB 的名称。
指定虚拟 HUB 时,也可选定当前不存在的虚拟 HUB。
虚拟接口必须在虚拟 HUB 内有一个 IP 地址。此外,还需指定属于该 IP 地址的 IP 网络的子网掩码。
设置虚拟 HUB 内几个虚拟空间通过交换机的路由网,需在指定的 IP 地址操作。
要运行此命令,需要 VPN Server 管理员权限。
此外,此命令不能在 VPN Bridge 中运行。
要运行此命令,操作对象的虚拟 3 层交换机必须关闭。如果正在运行中,可用 RouterStop 命令让其停止。
命令行格式 + RouterIfAdd [name] [/HUB:hub] [/IP:ip/mask]
"RouterIfAdd" 命令中可以指定的参数引数的一览:
name + 指定虚拟 3 层交换机的名称。
/HUB + 指定新建虚拟接口拟连接的虚拟 HUB 名称。虚拟 HUB 名单,可以通过 HubList 命令获取。但是,目前正在运行的虚拟 HUB 没有必要指定。如果指定了目前没有工作,或不存在的虚拟 HUB,当它开始虚拟工作时,虚拟 3 层交换机将被激活。
/IP + 按照 [IP 地址/子网掩码] 的格式,设定新添加的接口的的 IP 地址和子网掩码。IP 地址为 192.168.0.1,10 进制,以点区分。子网掩码 255.255.255.0 以点区分,10 进制,也可以设定为如 24 这样的字节数用 10 进制来表示。
+

 

+

6.3.51 "RouterIfDel": 删除虚拟 3 层交换机的虚拟远程接口

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + RouterIfDel
命令的概要 + 删除虚拟 3 层交换机的虚拟远程接口
说明 + 删除在指定虚拟交换机中已定义的虚拟接口。
对当前定义的虚拟接口列表,可以通过 RouterIfList 命令得到。
要运行此命令,需要 VPN Server 管理员权限。
此外,此命令不能在 VPN Bridge 中运行。
要运行此命令,虚拟 3 层转化及必须在停止状态。如果不是,可以通过 RouterStop 指令使其停止。
命令行格式 + RouterIfDel [name] [/HUB:hub]
"RouterIfDel" 命令中可以指定的参数引数的一览:
name + 指定虚拟 3 层交换机的名称。
/HUB + 指定虚拟接口所连接的虚拟 HUB 的名称。
+

 

+

6.3.52 "RouterTableList": 获取虚拟 3 层交换机的路由列表

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + RouterTableList
命令的概要 + 获取虚拟 3 层交换机的路由列表
说明 + 在指定的虚拟 3 层交换机中,如果有路由表已定义,可以获取一个路由表的列表。
虚拟 3 层交换机的IP 路由引擎,当 IP 数据包的 IP 地址不属于任一个虚拟接口时,将参照这个路由表。
要运行此命令,VPN Server 需要管理员权限。
此外,此命令不能在 VPN Bridge 中运行。
命令行格式 + RouterTableList [name]
"RouterTableList" 命令中可以指定的参数引数的一览:
name + 指定虚拟 3 层交换机的名称。
+

 

+

6.3.53 "RouterTableAdd": 添加一个路由表项到虚拟 3 层交换机

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + RouterTableAdd
命令的概要 + 添加一个路由表项到虚拟 3 层交换机
说明 + 指定新的虚拟 3 层交换机的路由表并添加一个新的路由表项。
虚拟 3 层交换机操作 IP 路由引擎时,IP 数据包的目的 IP 地址不属于任何 IP 接口时,可以参照路由表进行操作。
向虚拟 3 层交换机中添加的路由表项内容必须指定。作为网关,在虚拟 3 层交换机的虚拟接口中,有至少一个属于同一 IP 网络的 IP 地址相同。
要运行此命令,VPN Server 需要管理员权限。
此外,此命令不能在 VPN Bridge 中运行。
要运行此命令虚拟 3 层交换机必须处于停止噢国内工作状态。如果不在停止状态,可以执行 RouterStop 命令令其处于暂停。
命令行格式 + RouterTableAdd [name] [/NETWORK:ip/mask] [/GATEWAY:gwip] [/METRIC:metric]
"RouterTableAdd" 命令中可以指定的参数引数的一览:
name + 指定虚拟 3 层交换机的名称。
/NETWORK + 按照 [IP 地址/子网掩码] 的格式,设置新添加的路由表的网络地址和子网掩码。网络地址,如 192.168.0.1 的格式,由点分隔,10 进位制。子网掩码如 255.255.255.0,用点分隔,10 进位制,或者像 24 这样从开头 10 进位设定字节数。位长度可为十进制数指定的分隔十进制数字。 如 0.0.0.0/0.0.0.0 将格式设定好,默认为根。
/GATEWAY + 指定网关的 IP 地址。
/METRIC + 指定度量的值。请使用一个以上的整数。
+

 

+

6.3.54 "RouterTableDel": 删除虚拟 3 层交换机的路由表项

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + RouterTableDel
命令的概要 + 删除虚拟 3 层交换机的路由表项
说明 + 指定在虚拟 3 层交换机上已定义的路由表项,进行删除。
已定义的路由表项名单,可通过 RouterTableList 命令获取。
要运行此命令,需要 VPN Server 管理员权限。
此外,此命令不能在 VPN Bridge 中运行。
要运行此命令要求虚拟 3 层转换机处于停止状态。如果没有处于停止状态,可以执行 RouterStop 命令,让其暂停。
命令行格式 + RouterTableDel [name] [/NETWORK:ip/mask] [/GATEWAY:gwip] [/METRIC:metric]
"RouterTableDel" 命令中可以指定的参数引数的一览:
name + 指定虚拟 3 层交换机的名称。
/NETWORK + 按照 [IP 地址/子网掩码] 的格式,选定拟删除的路由表项的网络地址。
/GATEWAY + 指定网关的 IP 地址。
/METRIC + 指定度量的值。请使用一以上整数。
+

 

+

6.3.55 "LogFileList": 获取日志文件列表

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + LogFileList
命令的概要 + 获取日志文件列表
说明 + 您可以将保存在 VPN Server 上,并有服务器输出的日志文件显示成一个输出列表。通过指定一个文件名,运用 LogFileGet 命令,可以下载该日志文件的内容。
如果 VPN Server 在管理模式下,所有的虚拟 HUB 的数据包日志,安全日志,VPN Server 日志允许您查看或下载。
如果虚拟 HUB 在管理模式下,并处于连接状态,可以查看或下载该数据包日志和安全日志。
命令行格式 + LogFileList
"LogFileList" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.56 "LogFileGet": 日志文件下载

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + LogFileGet
命令的概要 + 日志文件下载
说明 + 下载 VPN Server 上存储的日志文件。要下载日志文件,先用 LogFileList 命令获取日志文件列表,然后您就可以执行 LogFileGet 命令来下载。如果与 VPN Server 连接并处于管理模式,所有的虚拟 HUB 的数据包日志,安全日志,VPN Server 允许您查看或下载。如果正在连接的虚拟 HUB 处于管理模式,HUB 管理的虚拟数据包日志,安全日志可查阅,也可以下载。
如果您指定一个作为参数作为文件名,下载的日志文件将被保存为这个文件名。如果你不指定文件将显示在屏幕上。
日志文件的大小有可能非常巨大的,所以一定要小心。
命令行格式 + LogFileGet [name] [/SERVER:server] [/SAVEPATH:savepath]
"LogFileGet" 命令中可以指定的参数引数的一览:
name + 选定要下载的日志文件名。运行 LogFileList 命令,可以得到一个日志文件的名称列表。
/SERVER + 如果您要从群集控制器中下载,请指定保存日志文件的服务器名称。运行 LogFileGet 指令可以获得指定服务器。
/SAVEPATH + 如果你想保存下载的日志文件,请指定文件名。如果没有指定,将显示在屏幕上。
+

 

+

6.3.57 "HubCreate": 创建新的虚拟 HUB

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + HubCreate
命令的概要 + 创建新的虚拟 HUB
说明 + 在 VPN Server 上创建一个新的虚拟 HUB。
创建的虚拟 HUB 将立即开始工作。
当 VPN Server,在一个群集中运行,此命令仅对群集控制器有效。新的虚拟 HUB,将作为一个动态的虚拟 HUB。应用 HubSetStatic 命令也可将虚拟 HUB 改为静态的。要想获取已经存储在 VPN Server 上的 HUB,可以运行 HubList 命令获得列表。
要运行此命令,需要 VPN Server 管理员权限。
此外,此命令在 VPN Bridge 和群集管理服务器中不起作用。
在群集上创建虚拟群集控制器 HUB 时,请运行 HubCreateStatic 或者 HubCreateDynamic 命令。(对群集控制器操作时,HubCreate 和 HubCreateDynamic就有相同的功能)。
命令行格式 + HubCreate [name] [/PASSWORD:password]
"HubCreate" 命令中可以指定的参数引数的一览:
name + 指定新创建的枢纽虚拟名称。
/PASSWORD + 如果您设置的虚拟 HUB 需要密码,请指定管理员密码。否则,会提示您输入。
+

 

+

6.3.58 "HubCreateDynamic": 创建一个新的动态虚拟 HUB (集群)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + HubCreateDynamic
命令的概要 + 创建一个新的动态虚拟 HUB (集群)
说明 + 在 VPN Server 上创建新的动态虚拟 HUB。
创建的虚拟 HUB 将立即开始工作。
VPN Server,在一个群集中运行时,此命令仅对群集控制器有效。新的虚拟 HUB,将作为一个虚拟的动态 HUB。运行 HubSetStatic 命令可以将虚拟 HUB 可以改为静态的。运行 HubList 命令可以获取当前虚拟 HUB 的列表。
要运行此命令,VPN Server 需要管理员权限。
此外,此命令在 VPN Bridge,群集管理器,独立的服务器在 VPN Server 工作时不起作用。
命令行格式 + HubCreateDynamic [name] [/PASSWORD:password]
"HubCreateDynamic" 命令中可以指定的参数引数的一览:
name + 指定新创建的虚拟 HUB 的名称。
/PASSWORD + 如果您设置虚拟 HUB 管理密码,请指定管理员密码。否则,会提示您输入。
+

 

+

6.3.59 "HubCreateStatic": 新创建一个静态虚拟 HUB (集群用)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + HubCreateStatic
命令的概要 + 新创建一个静态虚拟 HUB (集群用)
说明 + 在 VPN Server 上创建一个新的静态虚拟 HUB。
创建的虚拟 HUB 将立即开始工作。
VPN Server 在一个群集中运行时,此命令仅对群集控制器有效。新创建的虚拟 HUB,为一个虚拟的动态 HUB。运行 HubSetStatic 命令可以将虚拟 HUB 改为静态的。如果想得到已经保存在 VPN Server 上的 HUB 列表,可以运行 HubList 命令。
要运行此命令,VPN Server 需要管理员权限。
此外,此命令在 VPN Bridge,群集管理器,独立的服务器在 VPN Server 工作时不起作用。
命令行格式 + HubCreateStatic [name] [/PASSWORD:password]
"HubCreateStatic" 命令中可以指定的参数引数的一览:
name + 指定新创建的虚拟 HUB 的名称。
/PASSWORD + 如果您设置虚拟 HUB 管理密码,请指定管理员密码。否则,会提示您输入。
+

 

+

6.3.60 "HubDelete": 删除虚拟 HUB

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + HubDelete
命令的概要 + 删除虚拟 HUB
说明 + 删除 VPN Server 上现有的虚拟 HUB。
当您删除虚拟 HUB 后,所有的程序连接将断开,新的程序将不能与它连接。
虚拟 HUB 的所有的设置,用户选项,组选项,证书设置和级联将被删除。
虚拟 HUB 被删除后,将不能恢复。
运行此命令,需要 VPN Server 管理员权限。
此外,此命令在 VPN Bridge,群集管理器,独立的服务器在 VPN Server 工作时不起作用。
命令行格式 + HubDelete [name]
"HubDelete" 命令中可以指定的参数引数的一览:
name + 定要删除的虚拟 HUB 名称。
+

 

+

6.3.61 "HubSetStatic": 将虚拟 HUB 的类型变为静态虚拟型

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + HubSetStatic
命令的概要 + 将虚拟 HUB 的类型变为静态虚拟型
说明 + 使用 VPN Server 运行在群集上时,将虚拟 HUB 类型设定为静态虚拟 HUB。当虚拟 HUB 类型改变时,所有的程序连接将被暂时中断。
当作为静态虚拟 HUB 工作时,所有的群集成员的服务器上,将生成该名称的虚拟 HUB。每个尝试连接这个虚拟 HUB 的用户,基于各自服务器的负荷状况,确定与这个群集某个成员的连接。
静态虚拟 HUB,举例说,一个企业从互联网上访问局域网,允许数千或数以万计的用户远程访问 VPN Server。
要执行这个命令,您必须有 VPN Server 管理员权限。
此外,此命令在 VPN Bridge,群集管理器,独立的服务器在 VPN Server 工作时不起作用。
此命令不能用于比 5190 更新的服务器。
命令行格式 + HubSetStatic [name]
"HubSetStatic" 命令中可以指定的参数引数的一览:
name + 选定拟变更成静态虚拟 HUB 的名称。
+

 

+

6.3.62 "HubSetDynamic": 将虚拟 HUB 的类型变为动态虚拟型

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + HubSetDynamic
命令的概要 + 将虚拟 HUB 的类型变为动态虚拟型
说明 + 使用 VPN Server 运行在群集上时,将虚拟 HUB 类型变更为动态。当虚拟 HUB 类型改变时,所有的程序连接会暂时被中断。
当该虚拟 HUB 上没有任何成员时,虚拟 HUB 在任何群集上都不存在。当第一个客户端试图连接到动态的虚拟 HUB 时,负荷最低的服务器启动,托管虚拟 HUB。当第二个和随后的客户端试图连接到同一个虚拟 HUB,它们会自动连接到服务器托管的虚拟 HUB。当所有的客户都从一个特定的动态虚拟 HUB 断开,服务器上将不存在任何实体。
动态虚拟 HUB 的应用很广泛,例如,公司内部每个部门定应一个虚拟 HUB,让员工可以连接到自己所属的虚拟枢纽部门来操作,从而实现集中管理。
要执行这个命令,您必须有 VPN Server 管理员权限。
此外,此命令在 VPN Bridge,群集管理器,独立的服务器在 VPN Server 工作时不起作用。
此命令不能用于比 5190 更新的服务器。
命令行格式 + HubSetDynamic [name]
"HubSetDynamic" 命令中可以指定的参数引数的一览:
name + 指定拟转变为动态虚拟 HUB 的名称。
+

 

+

6.3.63 "HubList": 获取一个虚拟 HUB 列表

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + HubList
命令的概要 + 获取一个虚拟 HUB 列表
说明 + 在 VPN Server 中获得虚拟 HUB 的清单。对于每一个虚拟 HUB,可以获得 [虚拟 HUB 名称],[状态],[类型],[用户数量],[群数量],[访问数量],[MAC 目录的数量],[IP 目录数],[登陆次数],[上次登录],[最终通信时间]。
但是,如果处于连接状态的虚拟 HUB 在管理模式下,对于匿名用户如果设定为不列举虚拟 HUB,则虚拟 HUB 不会被显示。如果您连接到服务器的管理模式,则所有的虚拟 HUB 会显示清单。
如果你连接到群集控制器以外的其他群集成员,VPN Server 只显示虚拟 HUB 的托管虚拟主机。如果您连接到群集控制器来管理群集,所有虚拟 HUB 将显示。
命令行格式 + HubList
"HubList" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.64 "Hub": 选择拟管理的虚拟 HUB

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + Hub
命令的概要 + 选择拟管理的虚拟 HUB
说明 + 选择拟管理的虚拟 HUB。在 VPN Server 中,对目标虚拟 HUB 实行配置管理之前,需要用选择命令选定虚拟 HUB。
当正在连接的 VPN Server 处于管理虚拟 HUB 模式时,您可以选定拟管理的一个虚拟 HUB,而不可以选择其他的虚拟 HUB。与正在连接的 VPN Server 处于服务器管理模式,可以对所有的虚拟 HUB 进行管理。
获取当前的虚拟 HUB 列表,可以执行 HubList 命令。
在 VPN Bridge 中,只可以选择名字中带 "BRIDGE" 的虚拟 HUB。
命令行格式 + Hub [name]
"Hub" 命令中可以指定的参数引数的一览:
name + 选定拟管理的虚拟 HUB 的名称。如果您没有指定参数,目标虚拟 HUB 的选定将被清除。
+

 

+

6.3.65 "MakeCert": 创建新的 X.509 证书和密钥

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + MakeCert
命令的概要 + 创建新的 X.509 证书和密钥
说明 + 创建新的 X.509 证书和密钥,将其保存为一个文件。
证书公共密钥和秘密密钥的生成算法使用 RSA 1024 位。
作为证书类型,可以创建由根证书 (自签名证书) 和其他证书签名的某个证书。要创建由其他证书签名的证书,需要与用于签名的证书 (X.509格式文件) 相对应的密钥文件 (Base 64 编码)。

创建的证书可以指定名称 (CN),所属机构 (O),组织单位 (OU),国家 (C),州 (ST),当地 (L),序列号,有效期限。
创建的证书以 X.509 格式的文件,密钥文件以 RSA 1024 位的 Base 64 编码文件,被分别保存。

MakeCert 指令是一个工具,它提供创建证书所需的最低功能。如果想创建一个真正的证书,建议使用 OpenSSL 等免费软件和出售的 CA (认证机构) 软件。

※注意: 此指令可以从 PacketiX VPN 命令行管理工具调用。虽然目前以管理模式连接到 VPN Server 和 VPN Client 时可以运行,但要实际运行 RSA 演算,生成证书数据的,是运行此指令的计算机,和以管理模式连接的链接目标计算机没有任何关系。
命令行格式 + MakeCert [/CN:cn] [/O:o] [/OU:ou] [/C:c] [/ST:st] [/L:l] [/SERIAL:serial] [/EXPIRES:expires] [/SIGNCERT:signcert] [/SIGNKEY:signkey] [/SAVECERT:savecert] [/SAVEKEY:savekey]
"MakeCert" 命令中可以指定的参数引数的一览:
/CN + 指定创建证书的名称 (CN) 项目。还可以指定 none。
/O + 指定创建证书的所属机构 (O) 项目。还可以指定 none。
/OU + 指定创建证书的组织单位 (OU) 项目。还可以指定 none。
/C + 指定创建证书的国家 (C) 项目。还可以指定 none。
/ST + 指定创建证书的州 (ST) 项目。还可以指定 none。
/L + 指定创建证书的当地 (L) 项目。还可以指定 none。
/SERIAL + 指定创建证书的序列号项目。以 16 进制指定。还可以指定 none。
/EXPIRES + 指定创建证书的有效期限。如果指定 none 或 0,将被使用 3650 天 (约 10 年)。最大可以指定 10950 天 (约 30 年)。
/SIGNCERT + 根据现有的证书对要创建的证书签名时,指定用来签名的 X.509 形式的证书文件名。如果省略参数,将作为根证书而创建没有签名的新证书。
/SIGNKEY + 指定与 /SIGNCERT 指定的证书相应的密钥 (RSA,Base 64 的编码)
/SAVECERT + 指定文件名以保存创建的证书。该证书以包含 RSA 形式的 1024 位公开密钥的 X.509 文件格式被保存。
/SAVEKEY + 指定文件名保存对应创建的证书的密钥。该密钥以 RSA 形式的 1024 位密钥文件被保存。
+

 

+

6.3.66 "TrafficClient": 在用户模式下,运行网络流量速度测试工具

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + TrafficClient
命令的概要 + 在用户模式下,运行网络流量速度测试工具
说明 + 运行通信吞吐量测量工具的客户端程序。
通信吞吐量测量工具,作为 TrafficClient 和 TrafficServer 两个指令使用,可以测量在 IP 网络上连接的 2 台计算机之间可传送的通信吞吐量。在另一台计算机上使用 TrafficServer 指令使通信吞吐量测量工具服务器处于待机状态,用 TrafficClient 指令指定并连接其服务器的主机名或 IP 地址和端口号,测量通信速度。
同时建立多个连接,计算各连接最大限度传送流数据的结果,及在指定时间内能够实际传送的数据的比特数,以此为依据计算通信吞吐量的平均值 (bps),用此方法进行通信速度的测量。通常,用一个 TCP 连接时,由于 TCP 算法的限制,大多数时候只能用比实际的网络吞吐量慢的速度通信。因此,建议测量同时建立多个 TCP 连接进行通信的结果。用此方法测量的吞吐量,以实际上作为 TCP 流到达接收方的数据的比特长度来计算,因此途中产生的数据包丢失和数据包损坏不包括在实际到达的数据包中,因而能够计算出纯粹的网络最大通信带宽的近似值。
用作为测量结构的,在 TCP 内被传输的 TCP 流的大小,来计算在网络上实际传输的数据量的近似值,将其除以时间,计算出比特每秒 (bps)。假定计算的物理网络类型为以太网 (IEEE802.3) ,MAC 帧有效载荷的大小是 1,500 比特 (TCP 的 MSS 是 1,460 比特)。如果指定 /RAW 选项,不会对 TCP/IP 头和 MAC 头的数据量进行更正计算。

※注意: 此指令可以从 PacketiX VPN 命令行管理工具调用。虽然目前以管理模式连接到 VPN Server 和 VPN Client 时可以运行,但要实际进行通信,测量吞吐量的,是运行此指令的计算机,与以管理模式连接的连接目标计算机没有任何关系。
命令行格式 + TrafficClient [host:port] [/NUMTCP:numtcp] [/TYPE:download|upload|full] [/SPAN:span] [/DOUBLE:yes|no] [/RAW:yes|no]
"TrafficClient" 命令中可以指定的参数引数的一览:
host:port + 指定通信吞吐量测量服务器 (TrafficServer) 待机时的主机名,或 IP 地址和端口号。如果省略端口号,9821 将被使用。
/NUMTCP + 指定同时在客户端和服务器进行数据传输的 TCP 连接数量。如果省略,32 将被使用。
/TYPE + 指定进行吞吐量测量时的数据传输流方向。指定下列选项之一: "download","upload" 或 "full"。指定 "download",则数据从服务器端向客户端传送。指定 "upload",则数据从客户端向服务器端传送。指定 "full",数据将双向传送。当指定 "full" 时,NUMTCP 的值必须指定是 2 以上的偶数 (同时被连接的 TCP 连接中一半用于下载的方向,而另一半用于上传的方向)。如果省略此参数,将使用 "full"。
/SPAN + 以秒为单位指定为测量吞吐量而进行数据传输时间。如果省略此参数,"15秒" 将被使用。
/DOUBLE + 指定 "yes" 时,测量结果的吞吐量将显示为 2 倍。在中途有网络设备等,测量其其网络设备的输入输出合计的吞吐量能力时,此选项被使用。
/RAW + 通过指定 "yes",不进行修正 TCP/IP 头和 MAC 头的数据量计算。
+

 

+

6.3.67 "TrafficServer": 在服务器模式下,运行网络流量速度测试工具

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + TrafficServer
命令的概要 + 在服务器模式下,运行网络流量速度测试工具
说明 + 运行通信吞吐量测量工具的服务器程序。
通信吞吐量测量工具,作为 TrafficClient 和 TrafficServer 两个指令使用,可以测量在 IP 网络上连接的 2 台计算机之间可传送的通信吞吐量。
要使此计算机上的 TCP 端口处于待机状态,等待从另一台计算机的 TrafficClient 连接,启动 TrafficServer 指令并指定端口号。
关于通信吞吐量测量工具的详细情况,输入 TrafficClient /? 将显示。

※注意: 此指令可以从 PacketiX VPN 命令行管理工具调用。虽然目前以管理模式连接 VPN Server 和 VPN Client 时可以运行,但要进行实际通信并测量吞吐量的,是运行此指令的计算机,与用管理模式连接终端的计算机没有任何关系。
命令行格式 + TrafficServer [port]
"TrafficServer" 命令中可以指定的参数引数的一览:
port + 以整数指定等待连接的端口号。被指定的端口,如果已经由另一个程序在使用,或不能打开该端口时,将发生错误。
+

 

+

6.3.68 "Check": 检测 PacketiX VPN 是否能正常运行

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + Check
命令的概要 + 检测 PacketiX VPN 是否能正常运行
说明 + 正在运行 vpncmd 的计算机上,正检测 PacketiX VPN Server / Bridge 的运行平台是否适合。
通过了这一检查的系统,PacketiX VPN 软件有较高的可能性进行正常运行。此外,无法通过此检查的系统,如果使用了 PacketiX VPN 软件可能会发生一些问题。
命令行格式 + Check
"Check" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.69 "IPsecEnable": 启用或禁用 IPsec VPN Server 功能

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + IPsecEnable
命令的概要 + 启用或禁用 IPsec VPN Server 功能
说明 + 在 PacketiX VPN Server 上启用或禁用IPsec VPN Server 功能。
如果您禁用了此功能,VPN Server 上的虚拟 HUB 将会接受从 L2TP 兼容的 PC,Mac OS X 和智能手机的远程 VPN 连接,同时也会接受 EtherIP 站点到站点的 VPN 连接。从智能手机上的 VPN 连接,如iPhone、iPad 和 Android, 和从 Mac OS X 和 Windows 上的本地 VPN Client 的连接也都会接受。

要执行此命令,您必须具有 VPN Server 管理员权限。
该命令在 VPN Bridge 上不能运行。
以集群成员运行的 VPN Server 的虚拟 HUB 不能执行此命令。
命令行格式 + IPsecEnable [/L2TP:yes|no] [/L2TPRAW:yes|no] [/ETHERIP:yes|no] [/PSK:pre-shared-key] [/DEFAULTHUB:default_hub]
"IPsecEnable" 命令中可以指定的参数引数的一览:
/L2TP + 启用或禁用 L2TP over IPsec 服务器功能。要接受来自 iPhone, iPad, Android, Windows 或者 Mac OS X 的 VPN 连接,请启用本选项。
/L2TPRAW + 启用或禁用 L2TP 服务器功能 (未加密的原始 L2TP).要接受特殊 VPN 客服端,请启用本选项。
/ETHERIP + 启用或禁用 EtherIP / L2TPv3 over IPsec服务器功能(为站点到站点 VPN Server 功能). 兼容 EtherIP over IPsec 的路由器产品就可以连接到 VPN Server 上的虚拟 HUB ,并建成二层(以太网)网桥。
/PSK + 指定 IPsec 预共享密钥。IPsec 预共享密钥通常称为 "PSK" 或者"秘钥"。指定一个 8 位或者小于 8 位的密钥,并且将它分配给要连接到该 VPN Server 的用户。请注意:Google Android 4.0 有一个漏洞 bug,当预共享密钥是 10 位或以上时,会引发意外行为。介于这种情况,预共享密钥应该是 9 位或小于 9 位。
/DEFAULTHUB + 为防止遗漏用户名上的 HUB 名,请指定默认的虚拟 HUB。用户应该指定他们的用户名,如 "用户名@目标虚拟 HUB 名" 来连接此 L2TP 服务器。如果指定的虚拟 HUB 被遗漏,那么上述HUB将会作为目标被使用。
+

 

+

6.3.70 "IPsecGet": 获得当前IPsec VPN Server 设置

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + IPsecGet
命令的概要 + 获得当前IPsec VPN Server 设置
说明 + 获得并显示在 PacketiX VPN Server 上的当前 IPsec VPN Server 设置。

要执行此命令,您必须具有 VPN Server 管理员权限。
该命令在 VPN Bridge 上不能运行。
以集群成员运行的 VPN Server 的虚拟 HUB 不能执行此命令。
命令行格式 + IPsecGet
"IPsecGet" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.71 "EtherIpClientAdd": 添加新的 EtherIP / L2TPv3 over IPsec 客户端设置来接受 EtherIP / L2TPv3 客户端设备

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + EtherIpClientAdd
命令的概要 + 添加新的 EtherIP / L2TPv3 over IPsec 客户端设置来接受 EtherIP / L2TPv3 客户端设备
说明 + 添加一个新的设置条目启用 EtherIP / L2TPv3 over IPsec 服务器功能来接受客户端设备。
为了能够通过EtherIP / L2TPv3 over IPsec 服务器功能接受来自路由器的连接,您需要定义两者之间的关系表。这两者分别是表示客户端兼容EtherIP / L2TPv3 over IPsec 路由器的IPsec Phase 1 字符串和目标虚拟 HUB 的名称。
在您使用 EtherIpClientAdd 命令添加了一个连接定义后,这个定义的连接设置将会被应用到, EtherIP / L2TPv3 over IPsec 客户端设备的接入请求会话中。
用户名和密码条目必须要在虚拟 HUB 上注册。一个 EtherIP / L2TPv3 客户端会被认为它使用如上的用户信息的身份连接到虚拟 HUB 。n
为执行此命令,您必须具有 VPN Server 管理员权限。
该命令在 VPN Bridge 上不能运行。
以集群成员运行的 VPN Server 的虚拟 HUB 不能执行此命令。
命令行格式 + EtherIpClientAdd [ID] [/HUB:hubname] [/USERNAME:username] [/PASSWORD:password]
"EtherIpClientAdd" 命令中可以指定的参数引数的一览:
ID + 指定一个 ISAKMP Phase 1 ID。这个 ID 必须与 EtherIP / L2TPv3 客户端的ID配置完全相同。如果. EtherIP 客户端用 IP 地址作为Phase 1 ID,您可以指定像 ID 的字符类似的 IP 地址。如果您指定 '*' (星号),它将会是一个与任一不符合其他具体规则的客户端相符合的通配符。
/HUB + 指定要连接的虚拟 HUB 名称。
/USERNAME + 指定连接到目的虚拟 HUB 的用户名。
/PASSWORD + 指定连接到目的虚拟 HUB 的密码。
+

 

+

6.3.72 "EtherIpClientDelete": 删除一个 EtherIP / L2TPv3 over IPsec 客户端设置

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + EtherIpClientDelete
命令的概要 + 删除一个 EtherIP / L2TPv3 over IPsec 客户端设置
说明 + 本命令删除一个通过使用 EtherIP / L2TPv3 over IPsec 功能来接受 VPN Client 的条目。

要执行此命令,您必须具有 VPN Server 管理员权限。
该命令在 VPN Bridge 上不能运行。
以集群成员运行的 VPN Server 的虚拟 HUB 不能执行此命令。
命令行格式 + EtherIpClientDelete [ID]
"EtherIpClientDelete" 命令中可以指定的参数引数的一览:
ID + 指定一个要删除的 ISAKMP Phase 1 ID
+

 

+

6.3.73 "EtherIpClientList": 获得当前 EtherIP / L2TPv3 客户端设备条目定义列表

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + EtherIpClientList
命令的概要 + 获得当前 EtherIP / L2TPv3 客户端设备条目定义列表
说明 + 这个命令会获得和显示通过 EtherIP / L2TPv3 over IPsec 功能来接受 VPN Client 条目的列表。

要执行此命令,您必须具有 VPN Server 管理员权限。
该命令在 VPN Bridge 上不能运行。
以集群成员运行的 VPN Server 的虚拟 HUB 不能执行此命令。
命令行格式 + EtherIpClientList
"EtherIpClientList" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.74 "OpenVpnEnable": 启用/禁用 OpenVPN 克隆服务器功能

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + OpenVpnEnable
命令的概要 + 启用/禁用 OpenVPN 克隆服务器功能
说明 + 本 VPN Server 有 OpenVPN Technologies, Inc. 公司生产的 OpenVPN 软件产品的克隆功能。任何 OpenVPN Client 都可以连接到本 VPN Server。

指定用户名连接到虚拟 HUB 的的方式,使用本克隆服务器功能来为默认虚拟 HUB 的选择规则都与 IPsec 服务器功能相同。详情,请参见 IPsecEnable 命令的帮助。

要执行此命令,您必须具有 VPN Server 管理员权限。
该命令在 VPN Bridge 上不能运行。
以集群成员运行的 VPN Server 的虚拟 HUB 不能执行此命令。
命令行格式 + OpenVpnEnable [yes|no] [/PORTS:udp_port_list]
"OpenVpnEnable" 命令中可以指定的参数引数的一览:
yes|no + 指定 "yes",启用 OpenVPN 克隆服务器功能。指定 "no" 禁用该功能。
/PORTS + 指定UDP端口监听 OpenVPN 。指定多个 UDP 端口可以用空格或者逗号分开来它们,例如: "1194, 2001, 2010, 2012"。OpenVPN 的默认端口是 UDP 1194。您也可以指定任一其他 UDP 端口。
+

 

+

6.3.75 "OpenVpnGet": 获取 OpenVPN 克隆服务器功能的当前设置

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + OpenVpnGet
命令的概要 + 获取 OpenVPN 克隆服务器功能的当前设置
说明 + 获取并显示 OpenVPN 克隆服务器功能的当前设置。

要执行此命令,您必须具有 VPN Server 管理员权限。
该命令在 VPN Bridge 上不能运行。
以集群成员运行的 VPN Server 的虚拟 HUB 不能执行此命令。
命令行格式 + OpenVpnGet
"OpenVpnGet" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.76 "OpenVpnMakeConfig": 生成 OpenVPN Client 样本设置文件

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + OpenVpnMakeConfig
命令的概要 + 生成 OpenVPN Client 样本设置文件
说明 + 原来,OpenVPN Client 会要求用户手写很难的配置文件。本工具可以帮助您创建一个有用的配置样本。你所需要生成的 OpenVPN Client 配置文件就是运行此命令。

要执行此命令,您必须具有 VPN Server 管理员权限。
该命令在 VPN Bridge 上不能运行。
以集群成员运行的 VPN Server 的虚拟 HUB 不能执行此命令。
命令行格式 + OpenVpnMakeConfig [ZIP_FileName]
"OpenVpnMakeConfig" 命令中可以指定的参数引数的一览:
ZIP_FileName + 指定以 ZIP 压缩格式保存的输出文件。如果没指定文件后缀,那么".zip" 后缀就会被添加在文件名上。
+

 

+

6.3.77 "SstpEnable": 启用/禁用 Microsoft SSTP VPN 克隆服务器功能

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + SstpEnable
命令的概要 + 启用/禁用 Microsoft SSTP VPN 克隆服务器功能
说明 + 本 VPN Server 拥有植入在微软 Windows Server 2008 / 2012 中的 MS-SSTP VPN Server 的克隆功能。Windows Vista / 7 / 8 / RT 中的标准 MS-SSTP 用户端可以连接本 VPN Server。

[注意]
在 VPN Server 上的 SSL 证书 CN 值必须要和指定给客户端的主机名吻合。并且,该证书必须在 SSTP VPN Client 的信任列表中。详情请参见微软相关文件。
您可以用用 ServerCertRegenerate 命令来取代当前 VPN Server 的证书,形成一个新的,有 CN 值字段的自我认证证书。这样的话,您需要在 SSTP VPN Client 注册这样一个新的自我认证证书作为一个可信任根证书。如果您的确想做这件复杂的事,请考虑购买一个商业权威机构的 SSL 证书,如 VeriSign 或者 GlobalSign。

指定用户名连接到虚拟 HUB 的的方式,使用本克隆服务器功能来为默认虚拟 HUB 的选择规则都与 IPsec 服务器功能相同。详情,请参见 IPsecEnable 命令的帮助。

要执行此命令,您必须具有 VPN Server 管理员权限。
该命令在 VPN Bridge 上不能运行。
以集群成员运行的 VPN Server 的虚拟 HUB 不能执行此命令。
命令行格式 + SstpEnable [yes|no]
"SstpEnable" 命令中可以指定的参数引数的一览:
yes|no + 指定 "yes",启用Microsoft SSTP VPN 克隆服务器功能。指定 "no" 禁用该功能。
+

 

+

6.3.78 "SstpGet": 获得 Microsoft SSTP VPN 克隆服务器功能的当前设置

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + SstpGet
命令的概要 + 获得 Microsoft SSTP VPN 克隆服务器功能的当前设置
说明 + 获得并显示 Microsoft SSTP VPN 克隆服务器功能的当前设置。

要执行此命令,您必须具有 VPN Server 管理员权限。
该命令在 VPN Bridge 上不能运行。
以集群成员运行的 VPN Server 的虚拟 HUB 不能执行此命令。
命令行格式 + SstpGet
"SstpGet" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.79 "ServerCertRegenerate": 生成一个新的带有指定 CN (Common Name) 的自签名证书,并且在 VPN Server 上注册。

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ServerCertRegenerate
命令的概要 + 生成一个新的带有指定 CN (Common Name) 的自签名证书,并且在 VPN Server 上注册。
说明 + 您可以使用此命令,将当前 VPN Server 上的证书替换成一个新的、有 CN (Common Name) 值字段的、自签字证书。n
此命令在您想使用 Microsoft SSTP VPN 克隆服务器功能时很方便。因为在 VPN Server 上 SSL 证书的 CN 值必须要与 SSTP VPN Client 指定的主机名吻合。
详情参见 SstpEnable 命令的帮助。

本命令会删除 VPN Server 上现有的 SSL 证书。这要求事先使用 ServerKeyGet 命令备份当前的 SSL 证书和密钥。

要执行此命令,您必须具有 VPN Server 管理员权限。
该命令在 VPN Bridge 上不能运行。
以集群成员运行的 VPN Server 的虚拟 HUB 不能执行此命令。
命令行格式 + ServerCertRegenerate [CN]
"ServerCertRegenerate" 命令中可以指定的参数引数的一览:
CN + 指定一个新证书要使用的 Common Name(CN)
+

 

+

6.3.80 "VpnOverIcmpDnsEnable": 启用/禁用 VPN over ICMP / VPN over DNS服务器功能

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + VpnOverIcmpDnsEnable
命令的概要 + 启用/禁用 VPN over ICMP / VPN over DNS服务器功能
说明 + 即使有防火墙或者有屏蔽TCP/IP通信的路由器,您也可以只用 ICMP 或者 DNS 数据包建立一个 VPN 。您需要事先启用如下功能。

注意:本功能仅在紧急情况下使用。它在有防火墙或者路由器被错误配置屏蔽 TCP/IP 时,并且 ICMP 和 DNS 都没有被屏蔽的情况下可使用。它不是为长期稳定使用的。

要执行此命令,您必须具有 VPN Server 管理员权限。
该命令在 VPN Bridge 上不能运行。
命令行格式 + VpnOverIcmpDnsEnable [/ICMP:yes|no] [/DNS:yes|no]
"VpnOverIcmpDnsEnable" 命令中可以指定的参数引数的一览:
/ICMP + 指定 "yes",启用 VPN over ICMP 服务器。指定 "no",禁用。
/DNS + 指定 "yes",启用 VPN over DNS服务器。指定 "no",禁用。
+

 

+

6.3.81 "VpnOverIcmpDnsGet": 获取 VPN over ICMP / VPN over DNS 功能的当前设置

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + VpnOverIcmpDnsGet
命令的概要 + 获取 VPN over ICMP / VPN over DNS 功能的当前设置
说明 + 获得并显示 VPN over ICMP / VPN over DNS 功能的当前状态。

要执行此命令,您必须具有 VPN Server 管理员权限。
该命令在 VPN Bridge 上不能运行。
命令行格式 + VpnOverIcmpDnsGet
"VpnOverIcmpDnsGet" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.82 "DynamicDnsGetStatus": 显示动态 DNS 功能的当前状态

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + DynamicDnsGetStatus
命令的概要 + 显示动态 DNS 功能的当前状态
说明 + 获得并显示动态 DNS 功能的当前状态。

动态 DNS 会为本 VPN Server 分配一个唯一的和永久的 DNS 主机名。您可以在设置 VPN Client 和 VPN Bridge 时使用该主机名指定的 VPN Server。您不必注册并且保存域名。
同时,如果您的 ISP 分派给您一个动态(不稳定) IP 地址,您的动态 DNS 主机名相应的 IP 地址也将会自动改变。它使您只用动态 IP 地址就可以保持 VPN Server 的运行。
因此,您再也不需要为了维持静态全球 IP 地址,每月花费费用了。
[注意]
要禁止动态 DNS 功能,修改 VPN Server 和配置文件。

"declare root" 指令有"declare DDnsClient"指令。在本指令中,那你可以从错误到正确切换"bool disable",并重启 VPN Server ,这样,动态 DNS 功能就禁用了。

要执行此命令,您必须具有 VPN Server 管理员权限。
该命令在 VPN Bridge 上不能运行。
命令行格式 + DynamicDnsGetStatus
"DynamicDnsGetStatus" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.83 "DynamicDnsSetHostname": 设置动态 DNS 主机名

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + DynamicDnsSetHostname
命令的概要 + 设置动态 DNS 主机名
说明 + 您可以用本命令更改动态 DNS 功能分配的主机名。当前分配的主机名可以通过使用 DynamicDnsGetStatus 命令来显示。

动态 DNS 为 VPN Server 分配了一个唯一的和永久的 DNS 主机名。您可以在设置 VPN Client 和 VPN Bridge 时使用该主机名指定的 VPN Server。您不必注册并且保存域名。
同时,如果您的 ISP 分派给您一个动态(不稳定) IP 地址,您的动态 DNS 主机名相应的 IP 地址也将会自动改变。它使您只用动态 IP 地址就可以保持 VPN Server 的运行。
因此,您再也不需要为了维持静态全球 IP 地址,每月花费费用了。
[注意]
要禁止动态 DNS 功能,修改 VPN Server 和配置文件。

"declare root" 指令有"declare DDnsClient"指令。在本指令中,那你可以从错误到正确切换"bool disable",并重启 VPN Server,这样,动态 DNS 功能就禁用了。

要执行此命令,您必须具有 VPN Server 管理员权限。
该命令在 VPN Bridge 上不能运行。
命令行格式 + DynamicDnsSetHostname [hostname]
"DynamicDnsSetHostname" 命令中可以指定的参数引数的一览:
hostname + 指定新的主机名,主机名长度最短3个字母,最长为 31 个字母。仅限数字和字母。
+

 

+

6.3.84 "VpnAzureGetStatus": 显示 VPN Azure 功能的当前状态

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + VpnAzureGetStatus
命令的概要 + 显示 VPN Azure 功能的当前状态
说明 + 获取和显示 VPN Azure 功能的当前状态。

VPN Azure 可以更容易地从你家里的计算机到你办公室的计算机建立一个VPN会话。当一个 VPN 连接建立了,您可以访问您公司专用网络上的任何其他服务器。在办公室的计算机(VPN 服务器)上,你并不需要一个全球 IP 地址。它可以在防火墙或 NAT 后面工作。无需网络管理员的配置。您可以在您的家用电脑使用 Windows 内置的 SSTP VPN 客户端。
VPN Azure 是一个云 VPN 服务由 SoftEther 公司经营。VPN Azure 是免费的,可提供给任何人。访问 http://www.vpnazure.net/ 查看详细信息和如何使用的说明。

VPN Azure 主机名与动态 DNS 设置的主机名相同,但改变的域名后缀为“vpnazure.net”。要改变主机名使用 DynamicDnsSetHostname 命令。

要执行此命令,你必须具有VPN 服务器管理员权限。
此命令不能在 VPN 网桥上运行。
以集群成员运行的 VPN 服务器的虚拟 HUB 不能执行此命令。
命令行格式 + VpnAzureGetStatus
"VpnAzureGetStatus" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.3.85 "VpnAzureSetEnable": 启用/禁用 VPN Azure 功能

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + VpnAzureSetEnable
命令的概要 + 启用/禁用 VPN Azure 功能
说明 + 启用或禁用 VPN Azure 功能。

VPN Azure 可以更容易地从你家里的计算机到你办公室的计算机建立一个 VPN 会话。当一个 VPN 连接建立了,您可以访问您公司专用网络上的任何其他服务器。
在办公室的计算机(VPN 服务器)上,你并不需要一个全球 IP 地址。它可以在防火墙或 NAT 后面工作。无需网络管理员的配置。您可以在您的家用电脑使用 Windows 内置的 SSTP VPN 客户端。
VPN Azure 是一个云 VPN 服务由 SoftEther 公司经营。VPN Azure 是免费的,可提供给任何人。访问 http://www.vpnazure.net/ 查看详细信息和如何使用的说明。

VPN Azure 主机名与动态 DNS 设置的主机名相同,但改变的域名后缀为“vpnazure.net”。要改变主机名使用 DynamicDnsSetHostname 命令。

要执行此命令,你必须具有 VPN 服务器管理员权限。
此命令不能在 VPN 网桥上运行。
以集群成员运行的 VPN 服务器的虚拟 HUB 不能执行此命令。
命令行格式 + VpnAzureSetEnable [yes|no]
"VpnAzureSetEnable" 命令中可以指定的参数引数的一览:
yes|no + 指定“yes”,启用 VPN Azure。“no”禁用它。
+

 

+ + + + + + + + + + +------ 2 ------ + + + + + + + + + +

6.4.1 "Online": 虚拟 HUB 的联机

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + Online
命令的概要 + 虚拟 HUB 的联机
说明 + 如果您正在管理的虚拟 HUB 处于脱机状态,请设置成联机。处于脱机状态的虚拟 HUB,不会接受来自 VPN Client 连接。将虚拟 HUB 设定成联网状态,从而可以接受用户的虚拟连接并提供服务。
此命令,在 VPN Bridge 中不会运行。
此命令在 VPN Server 中的虚拟集群 HUB 中不能运行。
命令行格式 + Online
"Online" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.2 "Offline": 虚拟 HUB 脱机

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + Offline
命令的概要 + 虚拟 HUB 脱机
说明 + 如果您正在管理的虚拟 HUB 在线,设置成脱机。虚拟 HUB 如果有连接程序,将全部断开。虚拟 HUB 处于脱机状态,不会接受来自 VPN Client 连接。
此命令,在 VPN Bridge 中不会运行。
此命令在 VPN Server 中的虚拟集群 HUB 中不能运行。
命令行格式 + Offline
"Offline" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.3 "SetMaxSession": 设定虚拟 HUB 的最大同时在线用户数量

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + SetMaxSession
命令的概要 + 设定虚拟 HUB 的最大同时在线用户数量
说明 + 设定现在正在管理的虚拟 HUB 的最大同时在线客户数量。当超过这个数量时,如果从 VPN Client 和 VPN Bridge 连接的时候,超过了最大并发会话数,更多的客户将无法连接。最大同时在线客户数的限制不包括本地的网桥,虚拟的 NAT,级联连接等生成连接不包括在内。
设置同时在线最大数目,可以通过运行 OptionsGet 命令获得。
此命令,在 VPN Bridge 中不会运行。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + SetMaxSession [max_session]
"SetMaxSession" 命令中可以指定的参数引数的一览:
max_session + 设置最大同时在线客户数,使用整数。当您指定为 0 时,客户数没有限制。
+

 

+

6.4.4 "SetHubPassword": 设置虚拟 HUB 的管理密码

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + SetHubPassword
命令的概要 + 设置虚拟 HUB 的管理密码
说明 + 设置目前正在管理的虚拟 HUB 的管理密码。虚拟 HUB,如果设置了管理密码,您可以应用管理密码,虚拟 HUB,VPN Server 的公用事业,虚拟 HUB 连接,您可以通过指定一个连接密码在虚拟 HUB 的管理模式下实现连接。此外,通过 VPN Client 和 VPN Bridge,用户名用 "Administrator" 通过管理员密码,也可以实现连接。
此命令,不能在 VPN Bridge 中运行。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + SetHubPassword [password]
"SetHubPassword" 命令中可以指定的参数引数的一览:
password + 设定密码。如果您不指定将被提示输入密码。
+

 

+

6.4.5 "SetEnumAllow": 设定虚拟 HUB 允许向匿名用户显示。

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + SetEnumAllow
命令的概要 + 设定虚拟 HUB 允许向匿名用户显示。
说明 + 变更虚拟 HUB 的控制选项,对于匿名用户,允许虚拟 HUB 显示。当您设置了此选项,VPN Client 的用户,在 VPN Server 只需输入地址即可显示虚拟 HUB。虚拟 HUB 一创建成功,即可显示。此外,如果执行 SetEnumDeny 命令,可以禁止向匿名用户显示。虚拟 HUB 是在统计创建时设定允许显示与否。
此命令,在 VPN Bridge 中不会运行。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + SetEnumAllow
"SetEnumAllow" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.6 "SetEnumDeny": 设定虚拟 HUB 禁止向匿名用户显示。

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + SetEnumDeny
命令的概要 + 设定虚拟 HUB 禁止向匿名用户显示。
说明 + 变更虚拟 HUB 的控制选项,对于匿名用户,禁止虚拟 HUB 显示。当您设置了此选项,VPN Client 的用户,在 VPN Server 输入检索虚拟 HUB,虚拟 HUB 也不会显示。此外,如果执行 SetEnumAllow 命令,可以允许向匿名用户显示。虚拟 HUB 是在统计创建时设定允许显示与否。
此命令,在 VPN Bridge 中不会运行。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + SetEnumDeny
"SetEnumDeny" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.7 "OptionsGet": 获得虚拟 HUB 的设置选项

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + OptionsGet
命令的概要 + 获得虚拟 HUB 的设置选项
说明 + 获取虚拟 HUB 的选项设置清单。虚拟 HUB 允许 / 禁止显示设置,最大的同时在线数量,在线 / 离线状态,和集群虚拟环境中 HUB 的类型。
此命令对于一个虚拟集群 HUB 不能运行。
命令行格式 + OptionsGet
"OptionsGet" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.8 "RadiusServerSet": 使用在用户认证中使用的 RADIUS 服务器设置

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + RadiusServerSet
命令的概要 + 使用在用户认证中使用的 RADIUS 服务器设置
说明 + 接受用户当前以 RADIUS 服务器认证模式管理虚拟 HUB ,你需指定外部 RADIUS 服务器,以确认用户名和密码(您可以指定多个主机名,并将它们用逗号或者分号隔开)。
Radius 服务器必须设置为接受来自 VPN Server IP 地址的请求。此外,密码认证协议(PAP)的认证必须被启用。
此命令不能在 VPN Bridge 上运行。
此命令在 VPN Server 以集群运行的虚拟 HUB 上不能运行。
命令行格式 + RadiusServerSet [server_name:port] [/SECRET:secret] [/RETRY_INTERVAL:interval]
"RadiusServerSet" 命令中可以指定的参数引数的一览:
server_name:port + 用 [主机名:端口号] 的格式,指定 RADIUS 服务器的主机名,IP 地址和 UDP 端口号。如果省略端口号则用 1812。您可以指定多个主机名,并将它们用逗号或者分号隔开。
/SECRET + 设置与 RADIUS 服务器之间的通信 (密码)。
+

 

+

6.4.9 "RadiusServerDelete": 删除应用于用户认证的 RADIUS 服务器设置

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + RadiusServerDelete
命令的概要 + 删除应用于用户认证的 RADIUS 服务器设置
说明 + 目前,正在管理的虚拟 HUB,用户以 RADIUS 服务器认证模式连接时,删除外部 RADIUS 服务器设定,使服务器不能验证。目前 RADIUS 服务器的设置,可以运行 RadiusServerGet 命令获得。
此命令,虚拟 VPN Bridge 中不能运行。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + RadiusServerDelete
"RadiusServerDelete" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.10 "RadiusServerGet": 获取用于用户认证的 RADIUS 服务器设置

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + RadiusServerGet
命令的概要 + 获取用于用户认证的 RADIUS 服务器设置
说明 + 用户使用 RADIUS 服务器身份验证模式连接到现在管理的虚拟 HUB,您可以获取 RADIUS 服务器的当前设置。
此命令,在虚拟 VPN Bridge 中不能运行。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + RadiusServerGet
"RadiusServerGet" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.11 "StatusGet": 获取虚拟 HUB 的当前状况

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + StatusGet
命令的概要 + 获取虚拟 HUB 的当前状况
说明 + 获取正在管理的虚拟 HUB 的当前状况,可以获得虚拟 HUB 的种类,连接数量,各种目标数,登陆次数,最后一次登陆时间,最终连接时间,通信的统计数据等。
命令行格式 + StatusGet
"StatusGet" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.12 "LogGet": 获取虚拟 HUB 日志的保存设定

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + LogGet
命令的概要 + 获取虚拟 HUB 日志的保存设定
说明 + 获取虚拟 HUB 日志的保存设置。获取安全日志和数据包日志的保存设定,保存对象等信息。
命令行格式 + LogGet
"LogGet" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.13 "LogEnable": 启用安全日志或数据包日志

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + LogEnable
命令的概要 + 启用安全日志或数据包日志
说明 + 启用现在正在管理的 HUB 的安全日志或数据包日志。
当前的设置,可以通过 LogGet 命令获得。
命令行格式 + LogEnable [security|packet]
"LogEnable" 命令中可以指定的参数引数的一览:
security|packet + 选择启用日志文件的类型。选定 "security" 或 "packet"。
+

 

+

6.4.14 "LogDisable": 禁用安全日志或数据包日志

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + LogDisable
命令的概要 + 禁用安全日志或数据包日志
说明 + 禁止使用现在正在管理的 HUB 的安全日志或数据包日志。
当前的设置,可以通过 LogGet 命令获得。
命令行格式 + LogDisable [security|packet]
"LogDisable" 命令中可以指定的参数引数的一览:
security|packet + 选择禁用日志文件的类型。选定 "security" 或 "packet"。
+

 

+

6.4.15 "LogSwitchSet": 设定替换日志文件的周期

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + LogSwitchSet
命令的概要 + 设定替换日志文件的周期
说明 + 设定现在管理的虚拟 HUB 所保存的安全日志或数据包日志文件的替换周期。替换日志文件的时间是可以设定为 1 秒,1 分钟,1 小时,每天,每月,您也可以设定为不替换。
当前的设置,可以通过 LogGet 命令获得。
命令行格式 + LogSwitchSet [security|packet] [/SWITCH:sec|min|hour|day|month|none]
"LogSwitchSet" 命令中可以指定的参数引数的一览:
security|packet + 选择变更设定的日志文件的类型。 选定 "security" 或 "packet"。
/SWITCH + 设置替换周期。从 sec,min,hour,day,month,none 中选择。
+

 

+

6.4.16 "LogPacketSaveType": 设置保存为数据包日志文件的数据包种类及保存。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + LogPacketSaveType
命令的概要 + 设置保存为数据包日志文件的数据包种类及保存。
说明 + 逐项设定保存在在管理的虚拟 HUB 上的,数据包保存内容和数据包的类型。数据包类型包括,[TCP 连接日志],[TCP 数据包日志],[DHCP 数据包记录],[UDP 数据包日志],[ICMP 数据包日志],[IP 数据包日志],[ARP 数据包日志],[以太网数据包日志] 等。
要想获取当前的设置,可以运行 LogGet 命令。
命令行格式 + LogPacketSaveType [/TYPE:tcpconn|tcpdata|dhcp|udp|icmp|ip|arp|ether] [/SAVE:none|header|full]
"LogPacketSaveType" 命令中可以指定的参数引数的一览:
/TYPE + 保存内容对应的数据包类型,从 tcpconn,tcpdata,dhcp,udp,icmp,ip,arp,ether 中选定。
/SAVE + 设定日志文件的保存内容。从下列选定: +none: 不保存 +header: 仅保存标题 +full: 所有数据包
+

 

+

6.4.17 "CAList": 获取可以信任的机构颁发证书的列表

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CAList
命令的概要 + 获取可以信任的机构颁发证书的列表
说明 + 管理可以信任的机构颁发的证书。VPN Client 如果用认证模式连接时,可以用保存的证书来验证其提供的证书。
此命令,在虚拟 VPN Bridge 中不能运行。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CAList
"CAList" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.18 "CAAdd": 添加可以信任的机构颁发的证书

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CAAdd
命令的概要 + 添加可以信任的机构颁发的证书
说明 + 在虚拟 HUB 管理的可信任的证书颁发机构的证书列表中,添加一个新的证书。如果客户端使用签名认证模式连接,管理中的证书将用来识别客户的证书。
要取得当前的证书列表,可以执行 CAList 命令。
要添加一个证书,必须将证书保存为 X.509 格式保存。
此命令,在虚拟 VPN Bridge 中不能运行。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CAAdd [path]
"CAAdd" 命令中可以指定的参数引数的一览:
path + 指定注册 X.509 证书的文件名。
+

 

+

6.4.19 "CADelete": 删除可以信任的机构颁发的证书

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CADelete
命令的概要 + 删除可以信任的机构颁发的证书
说明 + 从正在管理的可信任机构颁发的证书列表中,删除现有的证书。
如果要获取当前的证书列表,可以执行 CAList 命令。
此命令,在虚拟 VPN Bridge 中不能运行。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CADelete [id]
"CADelete" 命令中可以指定的参数引数的一览:
id + 指定拟删除的证书的 ID。
+

 

+

6.4.20 "CAGet": 获得可信任机构颁发的证书。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CAGet
命令的概要 + 获得可信任机构颁发的证书。
说明 + 获取虚拟 HUB 目前管理的可信任机构颁布的证书的列表,并将其保存为 X.509 的文件格式。
此命令,在虚拟 VPN Bridge 中不能运行。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CAGet [id] [/SAVECERT:path]
"CAGet" 命令中可以指定的参数引数的一览:
id + 制定获得证书的 ID。
/SAVECERT + 指定文件名以保存获取的证书。
+

 

+

6.4.21 "CascadeList": 获取级联接续列表

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeList
命令的概要 + 获取级联接续列表
说明 + 获取当前虚拟 HUB 上登记的级联名单。
如果您使用虚拟 HUB 级联同一台或另一个虚拟机上的 HUB,这两个层可以级联。

[使用级联的警告]
如果您使用级联多个虚拟 HUB 可以构成 2 层的网桥,如果连接方法错误可能会将连接做成绳状。所以使用级联功能,一定要精心设计。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeList
"CascadeList" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.22 "CascadeCreate": 创建一个新的级联接续

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeCreate
命令的概要 + 创建一个新的级联接续
说明 + 在当前虚拟 HUB 上创建一个新的级联接续。
如果您使用虚拟 HUB 级联同一个或者另一个虚拟 HUB,可以建立级联接续。
要创建一个级联,作为初始参数,需设定级联的名称,连接的服务器,目标 HUB 的名称和用户名。创建一个新的级联时,用户身份验证类型被初始化为 [匿名认证],代理服务器和服务器证书验证未设置。要更改这些设置,请在创建一个级联之后用 "Cascade" 命名的指令来执行。

[使用级联的警告]
如果您使用级联多个虚拟 HUB 可以构成 2 层的网桥,如果连接方法错误可能会将连接做成绳状。所以使用级联功能,一定要精心设计。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeCreate [name] [/SERVER:hostname:port] [/HUB:hubname] [/USERNAME:username]
"CascadeCreate" 命令中可以指定的参数引数的一览:
name + 指定新创建级联的名称。
/SERVER + 按照 [主机名:端口号] 的格式,设置 VPN Server 的主机名和端口号,您也可以指定 IP 地址。
/HUB + 选定目标 VPN Server 内的虚拟 HUB。
/USERNAME + 设定连接到 VPN Server 时所须的用户名认证名称。
+

 

+

6.4.23 "CascadeSet": 对级联连接方的设定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeSet
命令的概要 + 对级联连接方的设定
说明 + 对于虚拟 HUB 目前管理的已经连接的级联,设置连接方的 VPN 主机名和端口号,虚拟 HUB 名,用户名等。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeSet [name] [/SERVER:hostname:port] [/HUB:hubname]
"CascadeSet" 命令中可以指定的参数引数的一览:
name + 指定级联名称来改变设置。
/SERVER + 按照 [主机名:端口号] 的格式,设置连接方 VPN Server 的主机名和端口号。您也可以指定 IP 地址。
/HUB + 设置连接方 VPN Server 内的虚拟 HUB。
+

 

+

6.4.24 "CascadeGet": 获取级联连接的设置

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeGet
命令的概要 + 获取级联连接的设置
说明 + 获取当前在虚拟 HUB 上注册的级联的连接设置。
另外,要改变级联的连接设置,可以在您创建一个级联后使用 "Cascade" 开头的命令。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeGet [name]
"CascadeGet" 命令中可以指定的参数引数的一览:
name + 指定级联获取它的连接设置。
+

 

+

6.4.25 "CascadeDelete": 删除级联连接

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeDelete
命令的概要 + 删除级联连接
说明 + 删除目前在虚拟 HUB 中注册的级联连接。如果选定的级联连接处于联机状态,则先断开连接,然后删除。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeDelete [name]
"CascadeDelete" 命令中可以指定的参数引数的一览:
name + 指定您想删除的级联连接的名称。
+

 

+

6.4.26 "CascadeUsernameSet": 设置级联连接的用户名

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeUsernameSet
命令的概要 + 设置级联连接的用户名
说明 + 选定已在虚拟 HUB 上注册的级联,设定其用户名,当连接到 VPN Server 时,用此用户名来进行身份验证。
此外,您可以指定用户身份验证的种类,或可以指定所需的参数。如果您想更改这些设置,可以运行 CascadeAnonymousSet,CascadePasswordSet,CascadeCertSet 等命令。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeUsernameSet [name] [/USERNAME:username]
"CascadeUsernameSet" 命令中可以指定的参数引数的一览:
name + 指定级联名称来改变设置。
/USERNAME + 级联连接到 VPN Server 时,指定用户名要求用户进行身份验证。
+

 

+

6.4.27 "CascadeAnonymousSet": 将级联连接的用户认证类型设置为匿名身份验证

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeAnonymousSet
命令的概要 + 将级联连接的用户认证类型设置为匿名身份验证
说明 + 选定虚拟 HUB 中已经注册的级联,将级联连接到 VPN Server 所需的用户身份验证方法设定为匿名身份验证。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeAnonymousSet [name]
"CascadeAnonymousSet" 命令中可以指定的参数引数的一览:
name + 指定级联名称来改变设置。
+

 

+

6.4.28 "CascadePasswordSet": 将级联连接时所需的用户验证设置为密码验证

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadePasswordSet
命令的概要 + 将级联连接时所需的用户验证设置为密码验证
说明 + 选定虚拟 HUB 中已经注册的级联,将级联连接到 VPN Server 所需的用户身份验证方法设定为密码验证。密码验证的种类指定为,[标准密码验证] 和 [RADIUS 或 NT域身份验证]。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadePasswordSet [name] [/PASSWORD:password] [/TYPE:standard|radius]
"CascadePasswordSet" 命令中可以指定的参数引数的一览:
name + 指定级联名称来改变设置。
/PASSWORD + 指定密码验证所使用的密码。否则,会提示您输入密码。
/TYPE + 密码验证的类型,指定为 "standard" (标准密码验证),或 "radius" (radius 或 NT 域身份验证)。
+

 

+

6.4.29 "CascadeCertSet": 将级联连接时所需的用户验证设置为客户证书验证

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeCertSet
命令的概要 + 将级联连接时所需的用户验证设置为客户证书验证
说明 + 选定虚拟 HUB 中已经注册的级联,将级联连接到 VPN Server 所需的用户身份验证方法设定为客户证书验证。证书应为 X.509 证书文件格式,并且用变换为 Base 64 密钥文件编码。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeCertSet [name] [/LOADCERT:cert] [/LOADKEY:key]
"CascadeCertSet" 命令中可以指定的参数引数的一览:
name + 指定级联名称来改变设置。
/LOADCERT + 选定 X.509 证书名称用来进行证书认证。
/LOADKEY + 选定与证书对应的 Base 64 编码的密钥文件。
+

 

+

6.4.30 "CascadeCertGet": 获取级联连接所需的客户端证书

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeCertGet
命令的概要 + 获取级联连接所需的客户端证书
说明 + 指定当前在虚拟 HUB 上已注册的级联接续,如果您使用客户端证书身份验证,请获取证书,保存为 X.509 格式。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeCertGet [name] [/SAVECERT:cert]
"CascadeCertGet" 命令中可以指定的参数引数的一览:
name + 指定级联名称获取设置。
/SAVECERT + 获取证书指定文件名保存为 X.509 格式。
+

 

+

6.4.31 "CascadeEncryptEnable": 启用级联通信时加密

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeEncryptEnable
命令的概要 + 启用级联通信时加密
说明 + 指定已经在当前虚拟 HUB 注册的级联连接,当此连接和 VPN Server 之间通信时,设置通信内容为 SSL 加密。
通常情况下,和 VPN Server 的通信进行 SSL 加密,以防止窃听和篡改信息。您还可以禁用加密。如果您禁用加密,通信的流速将提高,传输数据以明文传输到网络上。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeEncryptEnable [name]
"CascadeEncryptEnable" 命令中可以指定的参数引数的一览:
name + 指定级联名称来改变设置。
+

 

+

6.4.32 "CascadeEncryptDisable": 级联连接通信时,禁用加密

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeEncryptDisable
命令的概要 + 级联连接通信时,禁用加密
说明 + 指定已经在当前虚拟 HUB 注册的级联连接,当此连接和 VPN Server 之间通信时,设置通信内容为禁止加密。
通常情况下,和 VPN Server 的通信进行 SSL 加密,以防止窃听和篡改信息。您还可以禁用加密。如果您禁用加密,通信的流速将提高,传输数据以明文传输到网络上。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeEncryptDisable [name]
"CascadeEncryptDisable" 命令中可以指定的参数引数的一览:
name + 指定级联名称来改变设置。
+

 

+

6.4.33 "CascadeCompressEnable": 启用级联通信是数据压缩功能

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeCompressEnable
命令的概要 + 启用级联通信是数据压缩功能
说明 + 指定已经在当前虚拟 HUB 注册的级联连接,当此连接和 VPN Server 之间通信时,设置通信内容为压缩内容。
压缩量最大可以达到 80% 。但是,实行压缩,会给客户端和服务器双方的 CPU 造成很高的负荷。如果网络速度在 10 Mbps 以上,实施压缩后会减少传输流量,可能会适得其反。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeCompressEnable [name]
"CascadeCompressEnable" 命令中可以指定的参数引数的一览:
name + 指定级联名称来改变设置。
+

 

+

6.4.34 "CascadeCompressDisable": 级联通信是数据禁止压缩功能

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeCompressDisable
命令的概要 + 级联通信是数据禁止压缩功能
说明 + 指定已经在当前虚拟 HUB 注册的级联连接,当此连接和 VPN Server 之间通信时,设置通信内容为禁止压缩。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeCompressDisable [name]
"CascadeCompressDisable" 命令中可以指定的参数引数的一览:
name + 指定级联名称来改变设置。
+

 

+

6.4.35 "CascadeProxyNone": 将级联的连接方法设置为直接与 TCP/IP 连接

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeProxyNone
命令的概要 + 将级联的连接方法设置为直接与 TCP/IP 连接
说明 + 指定已经在当前虚拟 HUB 注册的级联连接,当此连接和 VPN Server 之间通信时,设置连接方法为 [直接与 TCP/IP 连接],而不通过代理服务器。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeProxyNone [name]
"CascadeProxyNone" 命令中可以指定的参数引数的一览:
name + 指定级联名称来改变设置。
+

 

+

6.4.36 "CascadeProxyHttp": 将级联连接方法设定为通过 HTTP 代理服务器

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeProxyHttp
命令的概要 + 将级联连接方法设定为通过 HTTP 代理服务器
说明 + 指定已经在当前虚拟 HUB 注册的级联连接,当此连接和 VPN Server 之间通信时,设置连接方法为,[通过 HTTP 代理服务器连接],然后设置要通过的 HTTP 代理服务器的主机名和端口号,用户名和密码 (如果需要)。
使用的 HTTP 代理服务器,必须有适合 HTTPS 通信的连接方式。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeProxyHttp [name] [/SERVER:hostname:port] [/USERNAME:username] [/PASSWORD:password]
"CascadeProxyHttp" 命令中可以指定的参数引数的一览:
name + 指定级联名称来改变设置。
/SERVER + [主机:端口的形式],通过指定的 HTTP 代理服务器的主机名或 IP 地址和端口号。
/USERNAME + 如果连接到 HTTP 代理服务器时需要用户验证,则指定用户名。同时设定密码和参数。 如果没有设定用户名和密码 D参数,则不需要设置用户身份验证。
/PASSWORD + 如果连接到 HTTP 代理服务器时需要用户验证,则指定密码。/USERNAME,参数等同时设定。
+

 

+

6.4.37 "CascadeProxySocks": 将级联连接方法设定为通过 SOCKS 代理服务器

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeProxySocks
命令的概要 + 将级联连接方法设定为通过 SOCKS 代理服务器
说明 + 指定已经在当前虚拟 HUB 注册的级联连接,当此连接和 VPN Server 之间通信时,设置连接方法为 [通过 SOCKS 代理服务器],设置 SOCKS8 代理服务器的主机名和端口号,用户名和密码 (如果需要)。
SOCKS 服务器,需与 SOCKS 第 4 版想匹配。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeProxySocks [name] [/SERVER:hostname:port] [/USERNAME:username] [/PASSWORD:password]
"CascadeProxySocks" 命令中可以指定的参数引数的一览:
name + 指定级联名称来改变设置。
/SERVER + 按照 [主机名:端口号] 的格式,设定代理服务器主机名或 IP 地址和端口号。
/USERNAME + 如果连接到 SOCKS 代理服务器时需要用户验证,则指定用户名。同时设定密码和参数。如果没有设定用户名和密码参数,则不需要设置用户身份验证。
/PASSWORD + 如果连接到 SOCKS 代理服务器时需要用户验证,则指定密码。/USERNAME,参数等同时设定。
+

 

+

6.4.38 "CascadeServerCertEnable": 启用级联服务器证书验证选项

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeServerCertEnable
命令的概要 + 启用级联服务器证书验证选项
说明 + 指定已经在当前虚拟 HUB 注册的级联连接,当此连接和 VPN Server 之间通信时,验证目标连接的 VPN 的服务器提供的 SSL 证书是否可以信任。
如果启用此选项,需要将在目标服务器的证书事先通过 CascadeServerCertSet 指令设置到级联的连接设置中,或者在虚拟 HUB 的可信任证书列表中,运行 CAAdd 指令,将有服务器的 SSL 证书署名的路线证书添加进去。
当启用服务器证书验证选项时,如果 VPN Server 提供的证书不可信,连接将断开,并重试。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeServerCertEnable [name]
"CascadeServerCertEnable" 命令中可以指定的参数引数的一览:
name + 指定级联名称来改变设置。
+

 

+

6.4.39 "CascadeServerCertDisable": 禁用级联服务器证书验证选项

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeServerCertDisable
命令的概要 + 禁用级联服务器证书验证选项
说明 + 指定已经在当前虚拟 HUB 注册的级联连接,当此连接和 VPN Server 之间通信时,对于连接方提供的 SSL 证书,不需要检查是否可以信任。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeServerCertDisable [name]
"CascadeServerCertDisable" 命令中可以指定的参数引数的一览:
name + 指定级联名称来改变设置。
+

 

+

6.4.40 "CascadeServerCertSet": 设置级联连接的服务器特定证书

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeServerCertSet
命令的概要 + 设置级联连接的服务器特定证书
说明 + 指定已经在当前虚拟 HUB 注册的级联连接,当此连接和 VPN Server 之间通信时,事先将连接方提供的 SSL 证书注册。
如果启用此选项,需要将在目标服务器的证书事先通过指令设置到级联的连接设置中,或者在虚拟 HUB 的可信任证书列表中,运行 CAAdd 指令,将有服务器的 SSL 证书署名的路线证书添加进去。
当启用服务器证书验证选项时,如果 VPN Server 提供的证书不可信,连接将断开,并重试。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeServerCertSet [name] [/LOADCERT:cert]
"CascadeServerCertSet" 命令中可以指定的参数引数的一览:
name + 指定级联名称来改变设置。
/LOADCERT + 设定文件名保存服务器固有的 X.509 格式的证书。
+

 

+

6.4.41 "CascadeServerCertDelete": 删除级联服务器固有的证书

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeServerCertDelete
命令的概要 + 删除级联服务器固有的证书
说明 + 选定当前虚拟 HUB 中已注册的级联,如果已经注册了服务器证书,将其删除。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeServerCertDelete [name]
"CascadeServerCertDelete" 命令中可以指定的参数引数的一览:
name + 指定级联名称来改变设置。
+

 

+

6.4.42 "CascadeServerCertGet": 获取级联连接服务器的固有证书

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeServerCertGet
命令的概要 + 获取级联连接服务器的固有证书
说明 + 选定在当前虚拟 HUB 上已注册的级联,如果此级联中已经注册了服务器固有证书,则获得该证书,并保存为 X.509 格式。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeServerCertGet [name] [/SAVECERT:path]
"CascadeServerCertGet" 命令中可以指定的参数引数的一览:
name + 指定级联名称来改变设置。
/SAVECERT + 指定名称以 X.509 格式保存服务器的固有证书。
+

 

+

6.4.43 "CascadeDetailSet": 级联通信的高级设置

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeDetailSet
命令的概要 + 级联通信的高级设置
说明 + 选定在当前虚拟 HUB 上已注册的级联,设置级联和 VPN Server 连接通信时使用的 VPN 自定义的通信协议。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeDetailSet [name] [/MAXTCP:max_connection] [/INTERVAL:interval] [/TTL:disconnect_span] [/HALF:yes|no] [/NOQOS:yes|no]
"CascadeDetailSet" 命令中可以指定的参数引数的一览:
name + 指定级联名称来改变设置。
/MAXTCP + VPN 通信中使用的 TCP 连接的数量,用从 1 到 32 的整数来指定。和 VPN Server 之间的 VPN 数据传输,可以通过使用多个 TCP 连接,提高通信速度。 +注意: 如果您使用高速连接到大约使用 8 根,如果是缓慢的拨号服务器,请使用一根。
/INTERVAL + 如果使用多个 TCP 连接进行 VPN 通信时,请设定各个 TCP 连接之间确立连接秒数。默认值为 1 秒。
/TTL + 如果您设置每个 TCP 连接的寿命,从连接到断开用秒表示。0 表示寿命未设置。
/HALF + 如果启动半双工模式选择 "yes"。使用两根以上的 VPN 连接进行 TCP 通信时,可以使用 "半双工模式"。启动半双工模式后,每个 TCP 可以固定一半连接实现单方向的数据传输。例如,使用 8 根 TCP 连接建立 VPN 通信,使用半双工模式后,会有 4 路 TCP 连接上船数据,剩下的 4 路负责下载数据。
/NOQOS + 禁用 VoIP/ QoS 对应功能选择 "yes"。通常选择 "no"。
+

 

+

6.4.44 "CascadePolicySet": 设置级联连接的安全协议

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadePolicySet
命令的概要 + 设置级联连接的安全协议
说明 + 选定当前虚拟 HUB 上已经注册的级联连接,设置级联连接建立时所适用的安全协议。
虚拟 HUB 和别的 VPN Server 进行级联连接时,连接方的虚拟 HUB 中将产生新的级联,运行此命令可以设置级联的安全协议。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + [name] [/NAME:policy_name] [/VALUE:num|yes|no]
"CascadePolicySet" 命令中可以指定的参数引数的一览:
name + 指定级联名称来改变设置。
/NAME + 选定要更改设置的协议名称。变更协议的名称和可变更的值,可通过运行 PolicyList 命令获得列表。
/VALUE + 设定协议的新值,如果协议是数值,请设定为一个整数。如果是选择型,请选 yes 或 no。 设定的值可以通过运行PolicyList命令来获得。
+

 

+

6.4.45 "PolicyList": 查看安全协议和可以设置的值得列表

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + PolicyList
命令的概要 + 查看安全协议和可以设置的值得列表
说明 + 显示 VPN Server 中的用户,群,级联的安全协议的项目名称,说明,以及可以设定的值的清单。
不指定任何参数的前提下运行 PolicyList 命令,你可以获得被支持的安全协议的名称和说明。
如果用 PolicyList 指令指定名称,您可以获得关于这个协议的详细说明,及值的类型和值的范围。
命令行格式 + PolicyList [name]
"PolicyList" 命令中可以指定的参数引数的一览:
name + 选定想要显示的协议名称。如果没有指定,所有的名称和安全协议及其说明将被列表的支持。
+

 

+

6.4.46 "CascadeStatusGet": 获取级联的当前状态

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeStatusGet
命令的概要 + 获取级联的当前状态
说明 + 选定在当前虚拟 HUB 上注册的级联,如果此级联处于连线状态,您将可以获得它的连接状态和其他信息。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeStatusGet [name]
"CascadeStatusGet" 命令中可以指定的参数引数的一览:
name + 指定级联名称,以获取信息。
+

 

+

6.4.47 "CascadeRename": 更改级联的名称

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeRename
命令的概要 + 更改级联的名称
说明 + 选定在当前虚拟 HUB 上注册的级联,改变它的连接名称。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeRename [name] [/NEW:new_name]
"CascadeRename" 命令中可以指定的参数引数的一览:
name + 指定要变更的级联的当前名称。
/NEW + 指定变更后的新名称。
+

 

+

6.4.48 "CascadeOnline": 设置级联接续的在线状态

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeOnline
命令的概要 + 设置级联接续的在线状态
说明 + 选定在当前虚拟 HUB 上注册的级联,将级联的连接状态设定为连接。级联成功连接后,可以通过连接设定连接到 VPN Server。处于在线状态的级联,除非运行 CascadeOffline 脱机命令,则 VPN Server 始终保持连接。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeOnline [name]
"CascadeOnline" 命令中可以指定的参数引数的一览:
name + 指定级联名称设定为联机状态。
+

 

+

6.4.49 "CascadeOffline": 将级联设置为脱机状态

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CascadeOffline
命令的概要 + 将级联设置为脱机状态
说明 + 选定在当前虚拟 HUB 上注册的级联,将级联的连接状态设定为脱机。处于脱机状态的级联,除非运行 CascadeOnline 命令使它连线,否则无法连接到 VPN Server。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + CascadeOffline [name]
"CascadeOffline" 命令中可以指定的参数引数的一览:
name + 指定级联名称设置到脱机状态。
+

 

+

6.4.50 "AccessAdd": 添加规则到允许访问列表 (IPv4)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccessAdd
命令的概要 + 添加规则到允许访问列表 (IPv4)
说明 + 在当前虚拟 HUB 的访问列表中,添加新的规则。
访问列表指的是虚拟 HUB 中,对流动的数据包进行筛选的规则,访问列表中可以登录多条规则,每条规则可以定义优先顺序。所有的数据包,按照最初适用的条件,或是通过或是销毁。不符合任何规则的数据包则将被默许通过。您也可以使用AccessAddEx 命令,来生成延迟、时基误差和数据包丢失。
此命令,在 VPN Bridge 中不会运行。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + AccessAdd [pass|discard] [/MEMO:memo] [/PRIORITY:priority] [/SRCUSERNAME:username] [/DESTUSERNAME:username] [/SRCMAC:mac/mask] [/DESTMAC:mac/mask] [/SRCIP:ip/mask] [/DESTIP:ip/mask] [/PROTOCOL:tcp|udp|icmpv4|icmpv6|ip|num] [/SRCPORT:start-end] [/DESTPORT:start-end] [/TCPSTATE:established|unestablished]
"AccessAdd" 命令中可以指定的参数引数的一览:
pass|discard + 确定数据包跟规则条件一致时的处理。当您指定 pass 意为通过,指定 discard,意为销毁。
/MEMO + 选定规则的解释 (备忘录)。
/PRIORITY + 用 1 以上的整数指定优先顺序。数字越小优先级越高。
/SRCUSERNAME + 作为此规则的条件,只有被指定的用户 / 用户組发送的数据包,才适用与此规则。在这种情况下,需指定用户名 / 用户組名。
/DESTUSERNAME + 作为此规则的条件,只有被指定的用户 / 用户組接受的数据包,才适用与此规则。在这种情况下,需指定用户名 / 用户組名。
/SRCMAC + 作为规则的条件,指定发送原 MAC 地址。MAC 地址像例子 (00-AC-84-EA-33-BC/FF-FF-FF-FF-FF-00) 一样地 '-' 或 '/' 断开十六进制数写。段落文字能省略。
/DESTMAC + 作为规则的条件,指定地址 MAC 地址。指定方法,/SRCMAC 参数同样。
/SRCIP + 作为规则条件制定一个源 IPv4 地址。用点把十进制数值分开的 IP 地址/掩码[格式指定一个 IPv4 地址,例如 192.168.0.1 掩码例如 255.255.255.0 为十进制,以点分隔,或者像 24 这样从开始设定字节长度,以十进位。如果设定为 0.0.0.0/0.0.0.0 则显示所有主机。
/DESTIP + 作为规则的条件必须制定目标 IPv4 地址:用 [IP 地址/掩码]格式制定方法同指定 /SRCIP 参数类似。
/PROTOCOL + 根据规则的条件,需指定协议类型。IP 协议号或者输入一个十进制数,或者 "tcp" (TCP/IP 协议,第 6 号),"udp" (UDP/IP 协议,第 17 号),"icmpv4" (ICMPv4 协议,第 1 号),"icmpv6" (ICMPv6 协议,第 58 号),"ip" (所有的 IP 协议,0 号) 来指定所有 IP 协议中的关键字。如果选定所有的 IP 协议,则选 0。
/SRCPORT + 协议 TCP/IP 或 UDP/IP 的情况下,作为规则需指定源端口号。其他的协议不需要。如果该参数没有指定,则选定所有端口。设定方法,例如 "1-1024" (第 1 到 1024),"23" (只选第 23 只)。
/DESTPORT + 协议 TCP/IP 或 UDP/IP 的情况下,作为规则需指定源端口号。其他的协议不需要。制定方法同指定 /SRCPORT 参数一样。
/TCPSTATE + 作为规则的条件,指定 TCP 连接的状态。 Established 或指定 Unestablished。
+

 

+

6.4.51 "AccessAddEx": 添加扩展访问列表规则 (IPv4:延迟、时基误差/数据包丢失产生)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccessAddEx
命令的概要 + 添加扩展访问列表规则 (IPv4:延迟、时基误差/数据包丢失产生)
说明 + 在当前管理的虚拟 HUB 的访问列表中,使用此命令添加新的规则。当数据包经由虚拟 HUB 通过时,你可以设置产生延迟、时基误差和数据包丢失。
访问列表是一组文件规则被应用到流过虚拟 HUB 的数据包。您可以在一个访问列表中注册多个规则,你也可以定义每个规则的优先级。检查所有的数据包的规则所指定的条件,在访问列表中注册的规则,由第一个匹配的规则根据规定的操作,它们要么通过要么被丢弃。不匹配任何规则的数据包暗中允许通过。您也可以使用 AccessAddEx 的命令来生成延迟、时基误差和数据包丢失。
此命令不能在 VPN Bridge 上运行。
在以成员服务器群集上运行的 VPN Server 的虚拟 HUB 上,您不能执行此命令。
命令行格式 + AccessAddEx [pass|discard] [/MEMO:memo] [/PRIORITY:priority] [/SRCUSERNAME:username] [/DESTUSERNAME:username] [/SRCMAC:mac/mask] [/DESTMAC:mac/mask] [/SRCIP:ip/mask] [/DESTIP:ip/mask] [/PROTOCOL:tcp|udp|icmpv4|icmpv6|ip|num] [/SRCPORT:start-end] [/DESTPORT:start-end] [/SRCUSERNAME:username] [/DESTUSERNAME:username] [/TCPSTATE:established|unestablished] [/DELAY:delay_millisec] [/JITTER:jitter_percent] [/LOSS:loss_percent]
"AccessAddEx" 命令中可以指定的参数引数的一览:
pass|discard + 当一个数据包匹配此规则条件时,该操作就已决定了。当通过被指定时,则数据包允许通过;当丢弃被指定时,数据包被丢弃。如果动作是通过,延迟、时基误差和数据包丢失的设置被应用。
/MEMO + 指定此规则的描述 (备忘录)。
/PRIORITY + 指定 1 或以上的整数作为此规则的优先级。数字越小优先级越高。
/SRCUSERNAME + 您可以将此规则仅用于作为规则条件被指定了用户名的用户会话发送的数据包。在这种情况下,请指定该用户名。
/DESTUSERNAME + 您可以将此规则仅用于作为规则条件被指定了用户名的用户会话接收的数据包。在这种情况下,请指定该用户名。
/SRCMAC + 指定目标 MAC 地址作为一个规则。用'-' 或 '/'分隔符和十六进制数字,如 (00-AC-84-EA-33-BC/FF-FF-FF-FF-FF-00) 来指定 MAC 地址。分隔符可跳过。
/DESTMAC + 指定目标 MAC 地址作为一个规则。指定方法同指定 /SRCPORT 参数一样。
/SRCIP + 指定一个源 IPv4 地址作为一个规则条件。用点把十进制数值分开的 [IP 地址/掩码] 格式指定一个 IPv4 地址,例如: 192.168.0.1。对于掩码,您或者可以指定由点分开的十进制数值,例如 255.255.255.0 也可以指定从标头用十进制数值的比特长度,如 24。 如果您指定: 0.0.0.0/0.0.0.0 这表示所有主机。
/DESTIP + 用 [IP 地址/掩码] 格式指定一个目的 IPv4 地址作为一个规则条件指定方法同指定 /SRCPORT 参数一样。
/PROTOCOL + 指定一个协议类型作为一个规则条件。使用十进制数值输入 IP 协议号,或者指定关键字中的一个 "tcp" (TCP/IP 协议,第 6 号),"udp" (UDP/IP 协议,第 17 号),"icmpv4" (ICMPv4 协议,第 1 号),"icmpv6" (ICMPv6 协议,第 58 号)或者, "ip" (所有的 IP 协议,0 号)。指定数字 0,则规则会应用到全部 IP 协议。
/SRCPORT + 如果已指定的协议是 TCP/IP 或 UDP/IP 的话,指定端口号的目的地作为规则条件。其他的协议会被忽略。如果该参数没有指定,那么规则会应用到所有端口号。当指定时,请使用如下方法: "1-1024" (第 1 到 1024),"23" (仅限 23)。
/DESTPORT + 如果已指定的协议是 TCP/IP 或 UDP/IP 的话,指定目的端口号的目的地作为规则条件。其他协议将被忽略。指定方法同指定 /SRCPORT 参数一样。
/TCPSTATE + 指定 TCP 连接状态作为一个规则。使用 Established (已建立的)或 Unestablished(未建立的)。
/DELAY + 当数据包通过时,设置此数值来生成延迟。以毫秒来指定延迟的时间段。指定 0,意为不会生成延迟。延迟最多为 10000 毫秒、
/JITTER + 当数据包通过时,设置此数值来生成时基误差。用 0% 到 100% 之内的范围来指定时基误差波动的频率。指定 0,意为不会生成时基误差。
/LOSS + 当数据包通过时,设置此数值来生成数据包丢失。用 0% 到 100% 之内的范围来指定丢包的频率。指定 0,意为不会生成丢包。
+

 

+

6.4.52 "AccessAdd6": 添加访问列表规则 (IPv6)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccessAdd6
命令的概要 + 添加访问列表规则 (IPv6)
说明 + 在当前管理的虚拟 HUB 的访问列表中,使用此命令添加新的规则。
访问列表是一组文件规则被应用到流过虚拟 HUB 的数据包。您可以在一个访问列表中注册多个规则,你也可以定义每个规则的优先级。检查所有的数据包的规则所指定的条件,在访问列表中注册的规则,由第一个匹配的规则根据规定的操作,它们要么通过要么被丢弃。不匹配任何规则的数据包暗中允许通过。您也可以使用 AccessAddEx6 的命令来生成延迟、时基误差和数据包丢失。
此命令不能在 VPN Bridge 上运行。
在以成员服务器群集上运行的 VPN Server 的虚拟 HUB 上,您不能执行此命令。
命令行格式 + AccessAdd6 [pass|discard] [/MEMO:memo] [/PRIORITY:priority] [/SRCUSERNAME:username] [/DESTUSERNAME:username] [/SRCMAC:mac/mask] [/DESTMAC:mac/mask] [/SRCIP:ip/mask] [/DESTIP:ip/mask] [/PROTOCOL:tcp|udp|icmpv4|icmpv6|ip|num] [/SRCPORT:start-end] [/DESTPORT:start-end] [/TCPSTATE: established|unestablished]
"AccessAdd6" 命令中可以指定的参数引数的一览:
pass|discard + 当一个数据包匹配此规则条件时,该操作就已决定了。当通过被指定时,则数据包允许通过;当丢弃被指定时,数据包被丢弃。
/MEMO + 指定此规则的描述。 (备忘录)。
/PRIORITY + 指定1或以上的整数作为此规的优先级。数字越小优先级越高。
/SRCUSERNAME + 您可以将此规则仅用于作为规则条件被指定了用户名的用户会话发送的数据包。在这种情况下,请指定该用户名。
/DESTUSERNAME + 您可以将此规则仅用于作为规则条件被指定了用户名的用户会话接收的数据包。在这种情况下,请指定该用户名。
/SRCMAC + 指定目的 MAC 地址作为规则。用分隔符 "-" 或者 ":" 和十六进制的数字,如 00-AC-84-EA-33-BC/FF-FF-FF-FF-FF-00 来指定 MAC 地址。分隔符可以跳过。
/DESTMAC + 指定目标 MAC 地址作为一个规则。方法与指定 /SRCMAC 参数同样。
/SRCIP + 指定一个源 IPv6 地址作为一个规则条件。使用冒号分割十六进制数字的 [IP 地址/掩码] 格式来指定 IPv6 地址。例如 2001:200:0:1:: 对于掩码来讲,您或者可以使用冒号分隔十六位数值的格式,例如 ffff:ffff:ffff:ffff:: 或者您也可以通过用标头的十进制数值像 128,来指定比特长度。如果您要指定 "::/0",意为所有主机。
/DESTIP + 用 [IP 地址/掩码] 格式指定一个目标 IPv6 地址作为一个规则条件。制定方法同指定/SRCIP参数类似。
/PROTOCOL + 指定一个协议类型来作为一个规则条件。输入十进制数值的 IP 协议号或者指定一个关键字 "tcp" (TCP/IP 协议,第 6 号),"udp" (UDP/IP 协议,第 17 号),"icmpv4" (ICMPv4 协议,第 1 号),"icmpv6" (ICMPv6 协议,第 58 号),"ip" (所有的 IP 协议,0 号)。指定]0[,则规则会应用于所有IP协议。
/SRCPORT + 如果指定的协议是 TCP/IP 或 UDP/IP,则指定源端口号作为规则条件。其他协议将被忽略。如果该参数没有指定,规则将会应用到所有端口号。指定时,请使用如下方法 "1-1024" (第 1 到 1024),"23" (仅是第 23 )。
/DESTPORT + 如果指定的协议是 TCP/IP 或 UDP/IP,则指定目标端口号作为规则条件。其他协议将被忽略。指定方法同指定 /SRCPORT 参数一样。
/TCPSTATE + 指定 TCP 连接状态作为一个规则。使用 Established 或 Unestablished。
+

 

+

6.4.53 "AccessAddEx6": 添加扩展访问列表规则 (IPv6,生成延迟,时基误差/数据包丢失)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccessAddEx6
命令的概要 + 添加扩展访问列表规则 (IPv6,生成延迟,时基误差/数据包丢失)
说明 + 在当前管理的虚拟 HUB 的访问列表中,使用此命令添加新的规则。当数据包经由虚拟 HUB 通过时,你可以设置产生延迟、时基误差和数据包丢失。
访问列表是一组文件规则被应用到流过虚拟 HUB 的数据包。您可以在一个访问列表中注册多个规则,你也可以定义每个规则的优先级。检查所有的数据包的规则所指定的条件,在访问列表中注册的规则,由第一个匹配的规则根据规定的操作,它们要么通过要么被丢弃。不匹配任何规则的数据包暗中允许通过。您也可以使用 AccessAddEx6 的命令来生成延迟、时基误差和数据包丢失。
此命令不能在 VPN Bridge 上运行。
在以成员服务器群集上运行的 VPN Server 的虚拟 HUB 上,您不能执行此命令。
命令行格式 + AccessAddEx6 [pass|discard] [/MEMO:memo] [/PRIORITY:priority] [/SRCUSERNAME:username] [/DESTUSERNAME:username] [/SRCMAC:mac/mask] [/DESTMAC:mac/mask] [/SRCIP:ip/mask] [/DESTIP:ip/mask] [/PROTOCOL:tcp|udp|icmpv4|icmpv6|ip|num] [/SRCPORT:start-end] [/DESTPORT:start-end] [/TCPSTATE: established|unestablished] [/DELAY:delay_millisec] [/JITTER:jitter_percent] [/LOSS:loss_percent]
"AccessAddEx6" 命令中可以指定的参数引数的一览:
pass|discard + 如果通过,会产生延迟,抖动和丢包。当一个数据包匹配此规则条件时,该操作就已决定了。当通过被指定时,则数据包允许通过;当丢弃被指定时,数据包被丢弃。如果动作是通过,延迟、时基误差和数据包丢失的设置被应用。
/MEMO + 指定此规则的描述(备忘录)。
/PRIORITY + 指定1或以上的整数作为此规则的优先级。数字越小优先级越高。
/SRCUSERNAME + 您可以将此规则仅用于作为规则条件被指定了用户名的用户会话发送的数据包。在这种情况下,请指定该用户名。
/DESTUSERNAME + 您可以将此规则仅用于作为规则条件被指定了用户名的用户会话接收的数据包。在这种情况下,请指定该用户名。
/SRCMAC + 指定目标 MAC 地址作为规则。用分隔符]-[或者]:[和十六进制的数字,如 "00-AC-84-EA-33-BC/FF-FF-FF-FF-FF-00" 来指定 MAC 地址。分隔符可以跳过。
/DESTMAC + 指定目标 MAC 地址作为一个规则。方法与指定 /SRCMAC 参数同样。
/SRCIP + 指定一个源 IPv6 地址作为一个规则条件。指定一个源 IPv6 地址作为一个规则条件。对于掩码来讲,您或者可以使用冒号分隔十六位数值的格式,例如 "ffff:ffff:ffff:ffff::" 或者您也可以通过用标头的十进制数值像 "64",来指定比特长度。如果您要指定 "::/0",意为所有主机。
/DESTIP + 用 [IP 地址/掩码] 格式指定一个目标 IPv6 地址作为一个规则条件。指定方法同指定 /SRCIP 参数类似。
/PROTOCOL + 指定一个协议类型来作为一个规则条件。输入十进制数值的IP 协议号或者指定一个关键字 "tcp" (TCP/IP 协议,第 6 号),"udp" (UDP/IP 协议,第 17 号),"icmpv4" (ICMPv4 协议,第 1 号),"icmpv6" (ICMPv6 协议,第 58 号),"ip" (所有的 IP 协议,0 号)。指定 0,则规则会应用于所有 IP 协议。
/SRCPORT + 如果已指定的协议是 TCP/IP 或 UDP/IP 的话,指定端口号的目的地作为规则条件。其他的协议会被忽略。如果该参数没有指定,那么规则会应用到所有端口号。当指定时,请使用如下方法: "1-1024" (第 1 到 1024),"23" (仅限 23)。
/DESTPORT + 如果指定的协议是 TCP/IP 或 UDP/IP 的话,则指定目标端口号作为规则条件。其他协议会被忽略。如果该参数没有指定,指定方法同指定 /SRCPORT 参数一样。
/TCPSTATE + 指定 TCP连接状态作为一个规则。使用已建立的(Established) 或未建立的(Unestablished)。
/DELAY + 当数据包通过时,设置本数值来产生延迟。以毫秒为单位来指定延迟周期。指定0,意为不产生延迟。延迟最大为 10000 毫秒。
/JITTER + 当数据包通过时,设置本数值来产生时基误差。当数据包通过时,设置此数值来生成时基误差。用 0% 到 100% 之内的范围来指定时基误差波动的频率。指定 0,意为不会生成时基误差。
/LOSS + 当数据包通过时,设置本数值来产生数据包丢失。指定 0% 至 100% 来作为丢包的比率范围。指定 0,意为无丢包生成。
+

 

+

6.4.54 "AccessList": 获取访问列表规则

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccessList
命令的概要 + 获取访问列表规则
说明 + 获取当前虚拟 HUB 的访问列表中注册的数据包筛选规则一览表。
访问列表,即是虚拟 HUB 内对流动的数据包进行筛选的规则的集合,访问列表中可以登录多条规则,每条规则可以定义优先顺序。通过包过滤规则适用英寸访问列表可以注册一个以上的规则可以定义一个优先考虑每一条规则。所有的数据包,按照最初适用的条件,或是通过或是销毁。不符合任何规则的数据包则将被默许通过。
此命令,在 VPN Bridge 中不会运行。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + AccessList
"AccessList" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.55 "AccessDelete": 从访问列表中删除规则

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccessDelete
命令的概要 + 从访问列表中删除规则
说明 + 从当前虚拟 HUB 中注册的访问列表中,选定数据包过滤规则并加以删除。
要删除规则,需要指定该规则 ID。ID 可以运行 AccessList 获得。
另外不删除而是暂时禁用的规则执行 AccessDisable 命令。
此命令,在 VPN Bridge 中不会运行。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + AccessDelete [id]
"AccessDelete" 命令中可以指定的参数引数的一览:
id + 指定要删除的规则的 ID 或唯一 ID。
+

 

+

6.4.56 "AccessEnable": 启用访问列表规则功能

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccessEnable
命令的概要 + 启用访问列表规则功能
说明 + 从当前虚拟 HUB 中注册的访问列表中,选定数据包筛选规则并激活。激活的规则用于数据包筛选。
要启用该规则,必须指定它的 ID。您可以使用 AccessList 命令获取 ID。
此命令,在 VPN Bridge 中不会运行。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + AccessEnable [id]
"AccessEnable" 命令中可以指定的参数引数的一览:
id + 指定规则的 ID 并激活。
+

 

+

6.4.57 "AccessDisable": 禁用访问列表规则

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccessDisable
命令的概要 + 禁用访问列表规则
说明 + 从当前虚拟 HUB 中注册的访问列表中,选定数据包筛选规则并禁用。被禁用的筛选规则将不会被用于数据包筛选。
要禁用的规则,规则必须指定的 ID。
要禁用该规则,必须指定它的 ID。您可以使用 AccessList 命令获取 ID。
此命令,在 VPN Bridge 中不会运行。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + AccessDisable [id]
"AccessDisable" 命令中可以指定的参数引数的一览:
id + 指定规则的 ID 并禁用。
+

 

+

6.4.58 "UserList": 获取用户列表

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + UserList
命令的概要 + 获取用户列表
说明 + 获取当前虚拟 HUB 中注册的安全帐户数据库信息中的用户清单。
此命令,在 VPN Bridge 中不会运行。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + UserList
"UserList" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.59 "UserCreate": 创建用户

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + UserCreate
命令的概要 + 创建用户
说明 + 在当前虚拟 HUB 中注册的安全帐户数据库中创建一个新用户。
当您创建一个用户,根据用户信息的认证,VPN Client 可以连接到这个虚拟 HUB。
如果您使用 UserCreate 命令创建一个用户,用户身份验证方法是验证密码,注册为一个随机字符串作为密码分配。因此,用户不能直接连接到虚拟 HUB。在创建用户后,则必须运用 UserPasswordSet 命令,设定指定用户的密码。或者使用 UserAnonymousSet 命令,UserCertSet 命令,UserSignedSet 命令,UserRadiusSet 命令,UserNTLMSet 命令来改变用户身份验证方式。
除非真有用户名为 "*" (星号),否则当客户登陆时提供的用户名与已有用户名不一致的情况下,将自动登录为 RADIUS 服务器,或者 NT 控制器来验证。
如果要更改用户信息,可以执行 UserSet 命令。
此命令,在 VPN Bridge 中不会运行。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + UserCreate [name] [/GROUP:group] [/REALNAME:realname] [/NOTE:note]
"UserCreate" 命令中可以指定的参数引数的一览:
name + 指定新创建用户的用户名。
/GROUP + 如果让用户加入一个用户组,请指定组名。如果你让用户不属于任何组,则设定为 /GROUP:none。
/REALNAME + 指定用户的全名。如果不指定,请选 /REALNAME:none。
/NOTE + 指定该用户的说明。否则,选择 /NOTE:none。
+

 

+

6.4.60 "UserSet": 更改用户信息

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + UserSet
命令的概要 + 更改用户信息
说明 + 变更当前虚拟 HUB 中的安全帐户数据库中注册的客户信息。
可以更改的信息,即使创建新用户所需要的 "组名称","全名" 和 "描述" 这三个项目。
要获得用户的名单,请使用 UserList 命令。
此命令,在 VPN Bridge 中不会运行。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + UserSet [name] [/GROUP:group] [/REALNAME:realname] [/NOTE:note]
"UserSet" 命令中可以指定的参数引数的一览:
name + 指定用户名更改设置。
/GROUP + 如果让用户加入一个用户组,请指定组名。如果你让用户不属于任何组,则设定为 /GROUP:none。
/REALNAME + 指定用户的全名。如果不指定,请选 /REALNAME:none。
/NOTE + 指定该用户的说明。否则,选择 /NOTE:none
+

 

+

6.4.61 "UserDelete": 删除用户

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + UserDelete
命令的概要 + 删除用户
说明 + 删除在虚拟 HUB 中的安全帐户数据库中注册的用户。当你删除一个用户,该用户将无法连接到虚拟 HUB。
如果您使用 UserPolicySet 命令,即使不删除也可暂时禁止用户登录。
要获得用户的名单,请使用 UserList 命令。
此命令,在 VPN Bridge 中不会运行。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + UserDelete [name]
"UserDelete" 命令中可以指定的参数引数的一览:
name + 指定用户名将其删除。
+

 

+

6.4.62 "UserGet": 获取用户信息

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + UserGet
命令的概要 + 获取用户信息
说明 + 获取在虚拟 HUB 中的安全帐户数据库中注册用户的登录信息。
这个指令可以得到的信息有 "用户名","全名","描述","组的成员","有效期","安全协议","身份验证方法",以及验证参数。
要获得用户的名单,请使用 UserList 命令。
此命令,在 VPN Bridge 中不会运行。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + UserGet [name]
"UserGet" 命令中可以指定的参数引数的一览:
name + 指定的用户名来获取信息。
+

 

+

6.4.63 "UserAnonymousSet": 将用户身份验证方法设置为匿名验证

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + UserAnonymousSet
命令的概要 + 将用户身份验证方法设置为匿名验证
说明 + 在虚拟 HUB 中的安全帐户数据库中注册用户的验证方法设定为 "匿名验证"。"匿名验证" 的用户连接到 VPN Client HUB 时,不会有任何用户认证即可以连接到 HUB。匿名身份验证设置适合那些公开的谁都可以连接的 VPN Server。
要获得用户的名单,请使用 UserList 命令。
此命令,在 VPN Bridge 中不会运行。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + UserAnonymousSet [name]
"UserAnonymousSet" 命令中可以指定的参数引数的一览:
name + 指定用户名更改设置。
+

 

+

6.4.64 "UserPasswordSet": 将用户身份验证方法设置为密码验证,并设定密码

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + UserPasswordSet
命令的概要 + 将用户身份验证方法设置为密码验证,并设定密码
说明 + 在虚拟 HUB 中的安全帐户数据库中注册用户的验证方法设定为 "密码验证" 所谓 "密码验证" 即所有安全帐户数据库中的用户都设置密码注册。当此用户连接虚拟 HUB 时,会提示输入密码,如果一致,则允许连接。
事实上,由于用户的密码是经过处理以后保存的,因此即使分析原始材料,也不会分析出密码。
要获得用户的名单,请使用 UserList 命令。
此命令,在 VPN Bridge 中不会运行。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + UserPasswordSet [name] [/PASSWORD:password]
"UserPasswordSet" 命令中可以指定的参数引数的一览:
name + 指定用户名更改设置。
/PASSWORD + 指定用户的密码设置。如果您不指定此参数将被提示输入密码。
+

 

+

6.4.65 "UserCertSet": 将用户身份验证方法设置为固有证书验证,并设定证书

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + UserCertSet
命令的概要 + 将用户身份验证方法设置为固有证书验证,并设定证书
说明 + 在虚拟 HUB 中的安全帐户数据库中注册用户的验证方法设定为 "固有证书验证" 所谓 "固有证书验证" 即所有安全帐户数据库中的用户都注册一个 X.509 证书。当此用户连接虚拟 HUB 时,提供的固有证书与登记证书一致,或持有对应证书的密钥,允许是通过验证实现连接。
要获得用户的名单,请使用 UserList 命令。
此命令,在 VPN Bridge 中不会运行。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + UserCertSet [name] [/LOADCERT:cert]
"UserCertSet" 命令中可以指定的参数引数的一览:
name + 指定的用户名更改设置。
/LOADCERT + 指定 X.509 证书文件名,这顶用户证书。
+

 

+

6.4.66 "UserCertGet": 获取注册固有证书认证用户的证书

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + UserCertGet
命令的概要 + 获取注册固有证书认证用户的证书
说明 + 在虚拟 HUB 中的安全帐户数据库中注册用户的 "固有证书认证" 的用户,取得用户的 X.509 证书,并保存。
如果用户未指定 "固有证书认证",则会发生错误。
要获得用户的名单,请使用 UserList 命令。
此命令,在 VPN Bridge 中不会运行。
此命令在集群虚拟 HUB 中不能运行。
命令行格式 + UserCertGet [name] [/SAVECERT:cert]
"UserCertGet" 命令中可以指定的参数引数的一览:
name + 指定的用户名来检索信息。
/SAVECERT + 指定文件名来保存获取的用户的 X.509 证书。
+

 

+

6.4.67 "UserSignedSet": 将用户身份验证方法设置为已签名证明书认证

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + UserSignedSet
命令的概要 + 将用户身份验证方法设置为已签名证明书认证
说明 + 将已注册在目前管理的虚拟 HUB 的安全帐户数据库的用户认证方法设定为已签名认证书认证。用户以已签名证明书认证的用户名链接虚拟 HUB 时,用户所提交的证明书会被验证是否为虚拟 HUB 认可的证明机构的证明书一览中任意证明书的签名,且客户是否持有与证书相应的密钥,用 RSA 算法验证可以链接的认证法。/n还可以设定成已注册用户希望的证明书的通用名 (CN) 及编号,只有通过了上述验证的证明书的内容与设定值一致的情况下才能许可链接。/n要取得目前注册用户一览,请使用用户名单指令。
此指令,虚拟专用桥不能运行。
此指令令在群集内作为群集成员服务器操作的 VPN Server 的虚拟 HUB 上不能运行。
命令行格式 + UserSignedSet [name] [/CN:cn] [/SERIAL:serial]
"UserSignedSet" 命令中可以指定的参数引数的一览:
name + 指定更改设定的用户名
/CN + 如果指定此参数,在验证了用户提交的证明书是否由可信赖的证明机构签名后,该证明书的通用名 (CN) 的值,与根据此参数设定的值相比较,只有取得一致的情况下才允许链接。指定 "none" 的情况下不进行确认。
/SERIAL + 如果指定此参数,在验证了用户提交的证明书是否由可信赖的证明机构签名后,该证明书的序列号的值,与根据此参数设定的值相比较,只有取得一致的情况下才允许链接。指定 "none" 的情况下不进行确认。
+

 

+

6.4.68 "UserRadiusSet": 将用户的认证方法设定为半径认证

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + UserRadiusSet
命令的概要 + 将用户的认证方法设定为半径认证
说明 + 将在目前管理的虚拟 HUB 的安全帐户数据库上注册的用户认证方法设置为 "半径认证"。用户以被半径认证设置的用户名连接虚拟 HUB 时,用户名和用户输入的密码被发送到半径服务器,半径服务器检查用户名和密码后,如过该认证成功,用户被允许 VPN 连接。
要使用半径认证,需要事先使用 RadiusServerSet 指令把要使用的半径服务器设置为虚拟 HUB。
要获得目前注册的用户列表,请使用 UserList 指令。
此指令,虚拟专用桥不能运行。
此指令令在群集内作为群集成员服务器操作的 VPN Server 的虚拟 HUB 上不能运行。
命令行格式 + UserRadiusSet [name] [/ALIAS:alias_name]
"UserRadiusSet" 命令中可以指定的参数引数的一览:
name + 指定更改设定的用户名
/ALIAS + 如果此参数被设置,可以使对半径服务器发送的用户名与虚拟 HUB 上的用户名是不同的。如果没有设置,请指定为 /ALIAS:none (使用虚拟 HUB 上的用户名)。用户名是 "*" 的情况下 /ALIAS 参数被忽略。关于 "*" 用户的描述,输入 UserCreate /HELP 可显示。
+

 

+

6.4.69 "UserNTLMSet": 用户身份验证方法设置为 NT 域认证

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + UserNTLMSet
命令的概要 + 用户身份验证方法设置为 NT 域认证
说明 + 将在目前管理的虚拟 HUB 的安全帐户数据库上注册的用户认证方法设置为 "NT 域验证"。用户以被 NT 域认证设置的用户名连接虚拟 HUB 时,用户名和用户输入的密码被发送到 Windows NT / 2000 / Server 2003 / Server 2008 域控制器或 Active Directory 服务器,认证服务器检查用户名和密码后,如果认证成功后,该用户的 VPN 连接被允许。要使用 NT 域认证,VPN Server 不要在连接到该域的 Windows NT 4.0,Windows 2000,Windows XP,Windows Server 2003 和 Windows Server 2008 的任何操作系统上运行。详情,请与 VPN Server 管理员咨询。
要获得目前注册的用户列表,请使用 UserList 指令。
此指令,虚拟专用桥不能运行。
此指令令在群集内作为群集成员服务器操作的 VPN Server 的虚拟 HUB 上不能运行。
命令行格式 + UserNTLMSet [name] [/ALIAS:alias_name]
"UserNTLMSet" 命令中可以指定的参数引数的一览:
name + 指定更改设定的用户名
/ALIAS + 如果此参数被设置,可以使对 NT 域或 Active Directory 发送的用户名与虚拟 HUB 上的用户名不同。如果没有设置,请指定 /ALIAS:none (使用虚拟 HUB 上的用户名)。用户名是 "*" 的情况下 /ALIAS 参数被忽略。关于 "*" 用户的描述,输入 UserCreate /HELP 可显示。
+

 

+

6.4.70 "UserPolicyRemove": 删除用户的安全策略

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + UserPolicyRemove
命令的概要 + 删除用户的安全策略
说明 + 删除在目前管理的虚拟 HUB 的安全帐户数据库上已注册的用户设置的安全策略设置。被删除安全策略设置的用户,适用该用户所属的组的安全策略设置。如果不属于任何组,或改组没有设置安全策略,则遵从默认值 (允许访问: 启用,TCP连接数最大值: 32 个,超时时间: 20 秒)。
要获得目前注册的用户列表,请使用 UserList 命令。
此指令,虚拟专用桥不能运行。
此指令令在群集内作为群集成员服务器操作的 VPN Server 的虚拟 HUB 上不能运行。
命令行格式 + UserPolicyRemove [name]
"UserPolicyRemove" 命令中可以指定的参数引数的一览:
name + 指定更改设定的用户名
+

 

+

6.4.71 "UserPolicySet": 设置用户的安全策略

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + UserPolicySet
命令的概要 + 设置用户的安全策略
说明 + 变更在目前管理的虚拟 HUB 的安全帐户数据库上已注册的用户设置的安全策略内容。
当用户未设置安全策略时,设置新的默认安全策略后,更改被指定的值。
要获得当前已注册的用户列表,请使用 UserList 指令。
此指令,虚拟专用桥不能运行。
此指令令在群集内作为群集成员服务器操作的 VPN Server 的虚拟 HUB 上不能运行。
命令行格式 + UserPolicySet [name] [/NAME:policy_name] [/VALUE:num|yes|no]
"UserPolicySet" 命令中可以指定的参数引数的一览:
name + 指定更改设定的用户名
/NAME + 指定要变更值的策略的名称。您可以使用 PolicyList 命令显示策略名称和可设定值的列表。
/VALUE + 指定策略的新值。如果其策略是数值型,指定整数。如果是布尔型,指定 "yes" 或 "no"。可以设定的类型和值,可以使用 PolicyList 指令显示。
+

 

+

6.4.72 "UserExpiresSet": 设置用户的有效期限

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + UserExpiresSet
命令的概要 + 设置用户的有效期限
说明 + 设置在目前管理的虚拟 HUB 安全帐户数据库中注册的用户的有效期限。有效期限到期的用户不能连接虚拟 HUB。
要获得当前已注册的用户列表,请使用 UserList 指令。
此指令,虚拟专用桥不能运行。
此指令令在群集内作为群集成员服务器操作的 VPN Server 的虚拟 HUB 上不能运行。
命令行格式 + UserExpiresSet [name] [/EXPIRES:expires]
"UserExpiresSet" 命令中可以指定的参数引数的一览:
name + 指定更改设定的用户名
/EXPIRES + 指定用户有效期限的日期和时间。如 "2005/10/08 19:30:00",以 6 个整数指定年,月,日,时,分,秒,用斜线或冒号分隔。年指定为 4 位数。如果把空格加入到值中,需要把整个值用 "" 围住。可以指定本地时间 (计算机上的命令行管理工具运行的标准时间)。如果指定 /EXPIRES:none,可以解除有效期限。
+

 

+

6.4.73 "GroupList": 获取组列表

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + GroupList
命令的概要 + 获取组列表
说明 + 获取在目前管理的虚拟 HUB 的安全帐户数据库中注册的组列表。
此命令用 VPN Bridge 不能运行。
此命令在群集内作为群集成员服务器操作的 VPN Server 的虚拟 HUB 上不能运行。
命令行格式 + GroupList
"GroupList" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.74 "GroupCreate": 创建组

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + GroupCreate
命令的概要 + 创建组
说明 + 在目前管理的虚拟 HUB 安全帐户数据库内建立新组。
在组内可以登记多个用户。要在组内注册用户,使用 GroupJoin 命令。
此命令用 VPN Bridge 不能运行。
此命令在群集内作为群集成员服务器操作的 VPN Server 的虚拟 HUB 上不能运行。
命令行格式 + GroupCreate [name] [/REALNAME:realname] [/NOTE:note]
"GroupCreate" 命令中可以指定的参数引数的一览:
name + 指定要创建的组名。
/REALNAME + 指定该组的全名。例如,如果组对应于实际的部分或部门名称,指定其名称。如果不指定的情况下,请指定 /REALNAME:none。
/NOTE + 指定组的描述。如果不指定的情况下,请指定 /NOTE:none。
+

 

+

6.4.75 "GroupSet": 设置组信息

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + GroupSet
命令的概要 + 设置组信息
说明 + 设置在目前管理的虚拟 HUB 安全帐户数据库中注册的组信息。
要获取当前已注册的组列表,请使用 GroupList 命令。
此命令用 VPN Bridge 不能运行。
此命令在群集内作为群集成员服务器操作的 VPN Server 的虚拟 HUB 上不能运行。
命令行格式 + GroupSet [name] [/REALNAME:realname] [/NOTE:note]
"GroupSet" 命令中可以指定的参数引数的一览:
name + 指定变更设定的组名。
/REALNAME + 指定该组的全名。例如,如果组对应于实际的部分或部门名称,指定其名称。如果不指定的情况下,请指定 /REALNAME:none。
/NOTE + 指定组的描述。如果不指定的情况下,请指定 /NOTE:none。
+

 

+

6.4.76 "GroupDelete": 删除组

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + GroupDelete
命令的概要 + 删除组
说明 + 删除目前管理的虚拟 HUB 安全帐户数据库中注册的组。
一旦删除组,该组所属的所有用户将成为未分配的。
要获取当前已注册的组列表,请使用 GroupList 命令。
此命令不能运行的 VPN Bridge。
您不能执行这个虚拟的 VPN 作为在群集成员服务器操作系统服务器花鼓命令。
命令行格式 + GroupDelete [name]
"GroupDelete" 命令中可以指定的参数引数的一览:
name + 指定删除的组名。
+

 

+

6.4.77 "GroupGet": 获得组信息和所属用户列表

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + GroupGet
命令的概要 + 获得组信息和所属用户列表
说明 + 获取目前管理的虚拟 HUB 安全帐户数据库中注册的组信息和属于改组的用户列表。
要获取当前已注册的组列表,请使用 GroupList 命令。
此命令用 VPN Bridge 不能运行。
此命令在群集内作为群集成员服务器操作的 VPN Server 的虚拟 HUB 上不能运行。
命令行格式 + GroupGet [name]
"GroupGet" 命令中可以指定的参数引数的一览:
name + 指定获得信息的组名。
+

 

+

6.4.78 "GroupJoin": 用户添加到组

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + GroupJoin
命令的概要 + 用户添加到组
说明 + 在目前管理的虚拟 HUB 的安全帐户数据库注册的组内,添加安全帐户数据库内的用户。
目前注册的用户和组的列表,可使用 UserList 命令和 GroupList 命令获取。
此命令用 VPN Bridge 不能运行。
此命令在群集内作为群集成员服务器操作的 VPN Server 的虚拟 HUB 上不能运行。
命令行格式 + GroupJoin [name] [/USERNAME:username]
"GroupJoin" 命令中可以指定的参数引数的一览:
name + 指定要添加用户的组名。
/USERNAME + 指定往以 name 指定了的组添加的用户名。
+

 

+

6.4.79 "GroupUnjoin": 从组内删除用户

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + GroupUnjoin
命令的概要 + 从组内删除用户
说明 + 从目前管理的虚拟 HUB 安全帐户数据库注册的组中,删除指定用户。用户一旦从组中被删除,该用户成为未分配。
要获取当前组的用户列表,使用 GroupGet 命令。
要获取当前已注册的组列表,使用 GroupList 命令。
此命令用 VPN Bridge 不能运行。
此命令在群集内作为群集成员服务器操作的 VPN Server 的虚拟 HUB 上不能运行。
命令行格式 + GroupUnjoin [name]
"GroupUnjoin" 命令中可以指定的参数引数的一览:
name + 指定要从组内删除的用户名。
+

 

+

6.4.80 "GroupPolicyRemove": 删除组的安全策略

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + GroupPolicyRemove
命令的概要 + 删除组的安全策略
说明 + 对在目前管理的虚拟 HUB 的安全帐户数据胡中注册的组,删除其被设置的安全策略的设置。对所属的组及用户本身没有被设置安全策略的用户,遵照默认值 (允许访问: 启用,TCP 连接数的最大值: 32 个,超时时间: 20 秒)。
要获得当前已注册的组列表,使用 GroupList 命令。
此命令用 VPN Bridge 不能运行。
此命令在群集内作为群集成员服务器操作的 VPN Server 的虚拟 HUB 上不能运行。
命令行格式 + GroupPolicyRemove [name]
"GroupPolicyRemove" 命令中可以指定的参数引数的一览:
name + 指定变更设定的组名。
+

 

+

6.4.81 "GroupPolicySet": 设置组的安全策略

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + GroupPolicySet
命令的概要 + 设置组的安全策略
说明 + 对在目前管理的虚拟 HUB 的安全帐户数据胡中注册的组,更改其被设置的安全策略的设置。
如组尚未设置安全策略,新的默认安全策略设置后,更改被指定的值。
要获得当前已注册的组列表,使用 GroupList 命令。
此命令用 VPN Bridge 不能运行。
此命令在群集内作为群集成员服务器操作的 VPN Server 的虚拟 HUB 上不能运行。
命令行格式 + GroupPolicySet [name] [/NAME:policy_name] [/VALUE:num|yes|no]
"GroupPolicySet" 命令中可以指定的参数引数的一览:
name + 指定变更设定的组名。
/NAME + 指定要更改其值的策略名称。您可以使用 PolicyList 命令显示的策略名称和可以设置值的列表。
/VALUE + 指定一个新的策略值。如果策略是数值型的情况下,指定一个整数。如果是布尔型的情况下,指定 "yes" 或 "no"。可以设定类型和值,可以使用 PolicyList 指令显示。
+

 

+

6.4.82 "SessionList": 获取连接会话的列表

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + SessionList
命令的概要 + 获取连接会话的列表
说明 + 获取目前管理的与虚拟 HUB 连接中的的会话列表。在会话列表中,以下信息将显示为每个连接: [会话名称],[会话场所],[用户名],[连接源主机名称],[TCP 连接],[传输字节数] 和 [传输数据包数]。
如果当前连接的 VPN Server 是群集控制器,管理的虚拟 HUB 是静态的虚拟 HUB,可以得到连接其所有的集群成员的该虚拟 HUB 的会话列表的结合。
在其他情况下,只能获取与目前管理的 VPN Server 实际连接着的会话列表。
命令行格式 + SessionList
"SessionList" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.83 "SessionGet": 获取会话信息

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + SessionGet
命令的概要 + 获取会话信息
说明 + 指定与当目前管理的虚拟 HUB 连接着的会话,并获得其会话信息。会话信息包括以下内容: 连接源主机名和用户名,版本信息,时间信息,TCP 连接数,通讯参数,会话密钥,输入输出的数据统计资料,和其他客户端和服务器信息等。
要获得当前连接的会话列表,请使用 SessionList 命令。
命令行格式 + SessionGet [name]
"SessionGet" 命令中可以指定的参数引数的一览:
name + 指定要获取信息的会话名称。
+

 

+

6.4.84 "SessionDisconnect": 断开会话

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + SessionDisconnect
命令的概要 + 断开会话
说明 + 指定连接到目前管理的虚拟 HUB 的会话,管理员权限以强制断开其会话。
但是,终端的客户端的设置为通信断开后的自动启动重新连接会话的情况下,可能客户端会重新连接。
要获得当前连接会话列表,请使用 SessionList 命令。
命令行格式 + SessionDisconnect [name]
"SessionDisconnect" 命令中可以指定的参数引数的一览:
name + 指定要断开的会话名称。
+

 

+

6.4.85 "MacTable": 获取 MAC 地址表数据库

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + MacTable
命令的概要 + 获取 MAC 地址表数据库
说明 + 获取当前管理的虚拟 HUB 保持的 MAC 地址表的数据库。
MAC 地址表数据库是虚拟 HUB 需要进行交换以太网帧的平台,虚拟 HUB 基于 MAC 地址表的数据库,决定各个以太网帧排序目标会话。MAC 地址数据库自动分析创建虚拟 HUB 流动的通信内容。
指定的会话名称,可以得到与该会话有关的 MAC 地址表项。
命令行格式 + MacTable [session_name]
"MacTable" 命令中可以指定的参数引数的一览:
session_name + 如果指定作为参数的会话名称,可以只显示与该会话相关联的 MAC 地址表项。如果不指定,则显示所有的项。
+

 

+

6.4.86 "MacDelete": 删除 MAC 地址表项

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + MacDelete
命令的概要 + 删除 MAC 地址表项
说明 + 操作目前管理的虚拟 HUB 保持的 MAC 地址表数据库,从数据库中删除指定的 MAC 地址项。
要获取目前的 MAC 地址表数据库的内容,请使用 MacTable 命令。
命令行格式 + MacDelete [id]
"MacDelete" 命令中可以指定的参数引数的一览:
id + 指定要删除的 MAC 地址表项的 ID。
+

 

+

6.4.87 "IpTable": 获取 IP 地址表数据库

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + IpTable
命令的概要 + 获取 IP 地址表数据库
说明 + 目前管理的虚拟 HUB 保持的 IP 地址表的数据库。
IP 地址表数据库是一个自动分析生成通信内容的平台,为使虚拟 HUB 能够掌握哪个会话使用的是哪个 IP 地址,这是经常被使用的虚拟 HUB 安全策略的引擎。
指定的会话名称,可以获取与该会话相关联的 IP 地址表项。
命令行格式 + IpTable [session_name]
"IpTable" 命令中可以指定的参数引数的一览:
session_name + 指定作为参数的会话名称,可以只显示与该会话相关联的 IP 地址表项。如果不指定,则显示所有的项。
+

 

+

6.4.88 "IpDelete": 删除 IP 地址表项

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + IpDelete
命令的概要 + 删除 IP 地址表项
说明 + 操作目前管理的虚拟 HUB 保持的 IP 地址表数据库,从数据库中删除指定的 IP 地址项。
要获取目前的 IP 地址表数据库的内容,请使用 IpTable 命令。
命令行格式 + IpDelete [id]
"IpDelete" 命令中可以指定的参数引数的一览:
id + 指定要删除的 IP 地址表项的 ID。
+

 

+

6.4.89 "SecureNatEnable": 启用虚拟 NAT 和 DHCP 服务器功能 (安全网络功能)

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + SecureNatEnable
命令的概要 + 启用虚拟 NAT 和 DHCP 服务器功能 (安全网络功能)
说明 + 使在目前管理的虚拟 HUB 内启动并运行虚拟 NAT 和 DHCP 服务器功能 (安全网络功能)。执行此指令前,必须先使用 SecureNatHostGet 指令,NatGet 指令和 DhcpGet 指令检查当前虚拟 NAT 功能和 DHCP 服务器的设置内容。
一旦启用安全网络的功能,可以在虚拟 HUB 的虚拟网络上使 NAT 路由器 (IP 伪装) 和 DHCP 服务器功能虚拟性的运行。

[有关安全网络功能的警告]
安全网络的功能是面向系统管理员和对具备有关网络的丰富知识的人的功能。
如果正确使用安全网络功能,可能实现通过 VPN 的安全的远程访问。但是如果错误地使用,可能使整个网络处于危险状态。如果不具备全面的的网络知识,没有得到网络管理员许可的情况下,请禁用安全网络功能。关于安全网络功能的详细说明,请参阅 VPN Server 的手册和在线文档。
此命令在群集内作为群集成员服务器操作的 VPN Server 的虚拟 HUB 上不能运行。
命令行格式 + SecureNatEnable
"SecureNatEnable" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.90 "SecureNatDisable": 禁用虚拟 NAT 和 DHCP 服务器功能 (安全网络功能)

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + SecureNatDisable
命令的概要 + 禁用虚拟 NAT 和 DHCP 服务器功能 (安全网络功能)
说明 + 在当前管理的虚拟 HUB 内禁用虚拟 NAT 和 DHCP 服务器功能 (安全网络功能)。一旦执行该命令,虚拟 NAT 功能立即停止,虚拟 DHCP 服务器功能则删除持有的 DHCP 租赁数据并停止该服务。
该指令在作为进群操作的 VPN Server 的虚拟服务器上不能执行。
命令行格式 + SecureNatDisable
"SecureNatDisable" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.91 "SecureNatStatusGet": 获取虚拟 NAT 和 DHCP 服务器功能 (安全网络功能) 的工作状态

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + SecureNatStatusGet
命令的概要 + 获取虚拟 NAT 和 DHCP 服务器功能 (安全网络功能) 的工作状态
说明 + 如果在目前管理的虚拟 HUB 内操作虚拟 NAT 和 DHCP 服务器功能 (安全网络功能),获得其操作状态。
该指令在作为进群操作的 VPN Server 的虚拟服务器上不能执行。
命令行格式 + SecureNatStatusGet
"SecureNatStatusGet" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.92 "SecureNatHostGet": 获取安全网络功能的虚拟主机的网络接口设置

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + SecureNatHostGet
命令的概要 + 获取安全网络功能的虚拟主机的网络接口设置
说明 + 在当前管理的虚拟 HUB 内获取虚拟 NAT 和 DHCP 服务器功能 (安全网络功能) 中的虚拟主机的网络接口设置。
安全网络功能有一枚在虚拟 HUB 内二级市场中的虚拟 LAN 卡,它被赋予了 MAC 地址和 IP 地址。这样,连接到同一个二级市场的其他主机,能够如存在于网络的真实 IP 主机般与安全网络的虚拟主机通信。

[有关安全网络功能的警告]
安全网络的功能是面向系统管理员和对具备有关网络的丰富知识的人的功能。
如果正确使用安全网络功能,可能实现通过 VPN 的安全的远程访问。但是如果错误地使用,可能使整个网络处于危险状态。如果不具备全面的的网络知识,没有得到网络管理员许可的情况下,请禁用安全网络功能。关于安全网络功能的详细说明,请参阅 VPN Server 的手册和在线文档。
此命令在群集内作为群集成员服务器操作的 VPN Server 的虚拟 HUB 上不能运行。
命令行格式 + SecureNatHostGet
"SecureNatHostGet" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.93 "SecureNatHostSet": 更改安全网络功能的虚拟主机的网络接口设置

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + SecureNatHostSet
命令的概要 + 更改安全网络功能的虚拟主机的网络接口设置
说明 + 当前管理的虚拟 HUB 内,更改和保存虚拟 NAT 和 DHCP 服务器功能 (安全网络功能) 的设置项目中的虚拟主机网络接口设置。
安全网络功能有一枚在虚拟 HUB 内二级市场中的虚拟 LAN 卡,它被赋予了 MAC 地址和 IP 地址。这样,连接到同一个二级市场的其他主机,能够如存在于网络的真实 IP 主机般与安全网络的虚拟主机通信。

[有关安全网络功能的警告]
安全网络的功能是面向系统管理员和对具备有关网络的丰富知识的人的功能。
如果正确使用安全网络功能,可能实现通过 VPN 的安全的远程访问。但是如果错误地使用,可能使整个网络处于危险状态。如果不具备全面的的网络知识,没有得到网络管理员许可的情况下,请禁用安全网络功能。关于安全网络功能的详细说明,请参阅 VPN Server 的手册和在线文档。
此命令在群集内作为群集成员服务器操作的 VPN Server 的虚拟 HUB 上不能运行。
命令行格式 + SecureNatHostSet [/MAC:mac] [/IP:ip] [/MASK:mask]
"SecureNatHostSet" 命令中可以指定的参数引数的一览:
/MAC + 指定分配到虚拟接口的 MAC 地址。MAC 地址用诸如 "00-AC-01-23-45-67" 的字符串指定。一但指定 /MAC:none,则不更改将当前的设置。
/IP + 指定分配到虚拟接口的 IP 地址。一但指定 /IP:none,则不更改将当前的设置。
/MASK + 指定分配到虚拟接口的子网掩码。一但指定 /MASK:none,则不更改将当前的设置。
+

 

+

6.4.94 "NatGet": 获得安全网络功能的虚拟 NAT 功能的设置

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + NatGet
命令的概要 + 获得安全网络功能的虚拟 NAT 功能的设置
说明 + 在当前管理的虚拟 HUB 内,获得虚拟 NAT 和 DHCP 服务器功能 (安全网络功能) 的设置项目中的虚 NAT 设置。
该指令在作为进群操作的 VPN Server 的虚拟服务器上不能执行。
命令行格式 + NatGet
"NatGet" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.95 "NatEnable": 启用安全网络功能的虚拟 NAT 功能

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + NatEnable
命令的概要 + 启用安全网络功能的虚拟 NAT 功能
说明 + 在目前管理的虚拟 HUB 内启用虚拟 NAT 功能。
如果使用此指令启动虚拟 NAT 功能,但 SecureNAT 功能没有工作时,则虚拟的 NAT 不工作。要启动 SecureNAT 功能的工作,使用 SecureNatEnable 命令。
该指令在作为进群操作的 VPN Server 的虚拟服务器上不能执行。
命令行格式 + NatEnable
"NatEnable" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.96 "NatDisable": 禁用安全网络功能的虚拟 NAT 功能

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + NatDisable
命令的概要 + 禁用安全网络功能的虚拟 NAT 功能
说明 + 在目前管理的虚拟 HUB 内禁用虚拟 NAT 功能。
该指令在作为进群操作的 VPN Server 的虚拟服务器上不能执行。
命令行格式 + NatDisable
"NatDisable" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.97 "NatSet": 更改安全网络功能的虚拟 NAT 功能的设置

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + NatSet
命令的概要 + 更改安全网络功能的虚拟 NAT 功能的设置
说明 + 更改目前管理的虚拟 HUB 内的虚拟的 NAT 设置。虚拟的 NAT 设置的内容包括: MTU 值,TCP 会话超时,UDP 会话超时。
该指令在作为进群操作的 VPN Server 的虚拟服务器上不能执行。
命令行格式 + NatSet [/MTU:mtu] [/TCPTIMEOUT:tcp_timeout] [/UDPTIMEOUT:udp_timeout] [/LOG:yes|no]
"NatSet" 命令中可以指定的参数引数的一览:
/MTU + 用字节数单位的整数设置 MTU (最大可转让单位的大小)。此值是不包括虚拟 NAT 发送的以太网帧的 MAC 头最大有效载荷长度,默认值是 1500 字节。
/TCPTIMEOUT + 设置虚拟 NAT 中转 TCP 会话时如果持续多少秒非通信状态即超时并丢弃会话。
/UDPTIMEOUT + 设置虚拟 NAT 中转 UDP 会话时如果持续多少秒非通信状态即超时并丢弃会话。
/LOG + 指定是否将虚拟 NAT 的操作保存在虚拟 HUB 安全日志。指定 "yes" 即保存它,指定 "no" 即不保存。
+

 

+

6.4.98 "NatTable": 获得安全网络功能的虚拟 NAT 功能会话表

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + NatTable
命令的概要 + 获得安全网络功能的虚拟 NAT 功能会话表
说明 + 虚拟 NAT 功能在目前管理的虚拟 HUB 内运作时,经由虚拟 NAT 获取目前通信中的 TCP 及 UDP 会话表 (NAT 表)。
该指令在作为进群操作的 VPN Server 的虚拟服务器上不能执行。
命令行格式 + NatTable
"NatTable" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.99 "DhcpGet": 获得安全网络功能的虚拟 DHCP 服务器功能的设置

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + DhcpGet
命令的概要 + 获得安全网络功能的虚拟 DHCP 服务器功能的设置
说明 + 在当前管理的虚拟 HUB 内获取虚拟 NAT 和 DHCP 服务器功能 (安全网络功能) 的设置项目中的虚拟 DHCP 服务器设置。
该指令在作为进群操作的 VPN Server 的虚拟服务器上不能执行。
命令行格式 + DhcpGet
"DhcpGet" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.100 "DhcpEnable": 启动安全网络功能的虚拟 DHCP 服务器功能

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + DhcpEnable
命令的概要 + 启动安全网络功能的虚拟 DHCP 服务器功能
说明 + 在当前管理的虚拟 HUB 内启动虚拟 DHCP 服务器功能。如果使用此指令启动虚拟 DHCP 服务器功能但 SecureNAT 功能不工作的情况下,则虚拟 DHCP 服务器不工作。要启动 SecureNAT 功能,使用 SecureNatEnable 指令。
该指令在作为进群操作的 VPN Server 的虚拟服务器上不能执行。
命令行格式 + DhcpEnable
"DhcpEnable" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.101 "DhcpDisable": 禁用安全网络功能的虚拟 DHCP 服务器功能

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + DhcpDisable
命令的概要 + 禁用安全网络功能的虚拟 DHCP 服务器功能
说明 + 在目前管理的虚拟 HUB 内禁用 DHCP 服务器。
该指令在作为进群操作的 VPN Server 的虚拟服务器上不能执行。
命令行格式 + DhcpDisable
"DhcpDisable" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.102 "DhcpSet": 更改安全网络功能的虚拟 DHCP 服务器功能的设置

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + DhcpSet
命令的概要 + 更改安全网络功能的虚拟 DHCP 服务器功能的设置
说明 + 在现在管理的虚拟 HUB 内,更改虚拟 DHCP 服务器的设置。虚拟 DHCP 服务器设置包括: 分配 IP 地址范围,子网掩码,出租期限,及分配给客户端的选项值。
该指令在作为进群操作的 VPN Server 的虚拟服务器上不能执行。
命令行格式 + DhcpSet [/START:start_ip] [/END:end_ip] [/MASK:subnetmask] [/EXPIRE:sec] [/GW:gwip] [/DNS:dns] [/DNS2:dns2] [/DOMAIN:domain] [/LOG:yes|no]
"DhcpSet" 命令中可以指定的参数引数的一览:
/START + 指定地址范围的开始点,以分发给客户。(例如: 192.168.30.10)
/END + 指定地址范围的结束点,以分发给客户。(例如: 192.168.30.200)
/MASK + 指定对客户指定的子网掩码。(例如: 255.255.255.0)
/EXPIRE + 以秒为单位对客户指定租赁 IP 地址时的有效期限
/GW + 指定要通知给客户端的默认网关的 IP 地址。如果要与安全网络功能的虚拟 NAT 功能一起启动并使用时,可以指定安全网络的虚拟主机的 IP 地址。如果指定 "0" 或 "none",则不将默认网关通知客户。
/DNS + 指定被通知到客户端的主 DNS 服务器的 IP 地址。当 SecureNAT 功能的虚拟 NAT 功能已经启用并正在运行时,您可以为此指定一个 SecureNAT 虚拟主机 IP 地址。如果您指定的是 0 或者 none,那么客户端就不会被 DNS 服务器地址通知。
/DOMAIN + 指定域名通知客户。如果指定 none,该域名不通知客户。
/LOG + 指定是否将虚拟 DHCP 服务器运行保存为安全日志。指定 "yes" 则保存。此值与虚拟 NAT 功能的日志保存设置是联动的。
+

 

+

6.4.103 "DhcpTable": 获取安全网络功能的虚拟 DHCP 服务器租约表格

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + DhcpTable
命令的概要 + 获取安全网络功能的虚拟 DHCP 服务器租约表格
说明 + 在目前管理的虚拟 HUB 内操作 DHCP 服务器功能时,获取分配到 DHCP 服务器持有的客户端的 IP 地址租约表。
该指令在作为进群操作的 VPN Server 的虚拟服务器上不能执行。
命令行格式 + DhcpTable
"DhcpTable" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.104 "AdminOptionList": 获取虚拟 HUB 管理选项列表

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AdminOptionList
命令的概要 + 获取虚拟 HUB 管理选项列表
说明 + 获取目前管理的虚拟 HUB 设置的虚拟 HUB 管理选项列表。
VPN Server 的管理员委托各个虚拟 HUB 的管理员对虚拟 HUB 进行管理时,为限制其设置范围,使用虚拟 HUB 管理选项。
能够对虚拟 HUB 管理选项进行添加,编辑,删除的,只有掌握着此 VPN Server 全部管理权限的管理员。虚拟 HUB 的管理员可以显示管理选项,但不能更改。
然而,allow_hub_admin_change_option 设置为 1 时,虚拟 HUB 的管理员也可以编辑管理选项。
此命令用 VPN Bridge 不能运行。
此命令在群集内作为群集成员服务器操作的 VPN Server 的虚拟 HUB 上不能运行。
命令行格式 + AdminOptionList
"AdminOptionList" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.105 "AdminOptionSet": 设置虚拟 HUB 管理选项的价值

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AdminOptionSet
命令的概要 + 设置虚拟 HUB 管理选项的价值
说明 + 变更目前管理的虚拟 HUB 设置的虚拟 HUB 管理选项的值。
VPN Server 的管理员委托各个虚拟 HUB 的管理员对虚拟 HUB 进行管理时,为限制其设置范围,使用虚拟 HUB 管理选项。
能够对虚拟 HUB 管理选项进行添加,编辑,删除的,只有掌握着此 VPN Server 全部管理权限的管理员。虚拟 HUB 的管理员可以显示管理选项,但不能更改。
然而,allow_hub_admin_change_option 设置为 1 时,虚拟 HUB 的管理员也可以编辑管理选项。
此命令用 VPN Bridge 不能运行。
此命令在群集内作为群集成员服务器操作的 VPN Server 的虚拟 HUB 上不能运行。
命令行格式 + AdminOptionSet [name] [/VALUE:value]
"AdminOptionSet" 命令中可以指定的参数引数的一览:
name + 指定更改值的管理选项名。以 AdminOptionList 指令可以获取名单。
/VALUE + 以整数指定要设定的值。
+

 

+

6.4.106 "ExtOptionList": 获取虚拟 HUB 扩展选项列表

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ExtOptionList
命令的概要 + 获取虚拟 HUB 扩展选项列表
说明 + 获取目前管理的虚拟 HUB 设置的虚拟 HUB 扩展选项列表。
虚拟 HUB 扩展选项使你可以对虚拟 HUB 进行更多的配置。똨Å况下,VPN Server 的全球管理员和个人虚拟 HUB 的管理员都可以修改虚拟 HUB 扩展选项。
但是,如果虚拟 HUB 管理选项 deny_hub_admin_change_ext_option 被设置为 1,个人虚拟 HUB 管理员就不能修改虚拟 HUB 扩展选项。
此命令不能在 VPN Bridge 上运行。
以集群成员运行的 VPN Server 的虚拟 HUB 不能执行此命令。
命令行格式 + ExtOptionList
"ExtOptionList" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.107 "ExtOptionSet": 设置虚拟 HUB 扩展选项的值

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + ExtOptionSet
命令的概要 + 设置虚拟 HUB 扩展选项的值
说明 + 使用此命令在当前管理的虚拟 HUB 的虚拟 HUB 扩展选项列表设置一个值。
虚拟 HUB 扩展选项使你可以对虚拟 HUB 进行更多的配置。똨Å况下,VPN Server 的全球管理员和个人虚拟 HUB 的管理员都可以修改虚拟 HUB 扩展选项。
但是,如果虚拟 HUB 管理选项 deny_hub_admin_change_ext_option 被设置为 1,个人虚拟 HUB 管理员就不能修改虚拟 HUB 扩展选项。
此命令不能在 VPN Bridge 上运行。
以集群成员运行的 VPN Server 的虚拟 HUB 不能执行此命令。
命令行格式 + ExtOptionSet [name] [/VALUE:value]
"ExtOptionSet" 命令中可以指定的参数引数的一览:
name + 指定您要更改其值的虚拟 HUB 扩展选项的名称。使用 ExtOptionList 命令,你可以得到一个名称列表。
/VALUE + 以整数指定要设定的值。
+

 

+

6.4.108 "CrlList": 获取无效证书名单列表

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CrlList
命令的概要 + 获取无效证书名单列表
说明 + 获取目前管理的虚拟 HUB 设置的无效证书名单列表。
一旦证书注册到无效证书列表内,提交了其证书的客户,将不能用证书认证模式连接虚拟 HUB。
通常情况下,因为泄漏密钥或证书持有人的权限失效时,将该证书作为无效证书注册到虚拟 HUB,而 VPN 客户欲使用该证书连接虚拟 HUB 时会被拒绝用户认证,这种情况下该功能被使用。
此命令用 VPN Bridge 不能运行。
此命令在群集内作为群集成员服务器操作的 VPN Server 的虚拟 HUB 上不能运行。
命令行格式 + CrlList
"CrlList" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.109 "CrlAdd": 添加无效的证书

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CrlAdd
命令的概要 + 添加无效的证书
说明 + 在目前管理的虚拟 HUB 设置的无效的证书名单中添加新的无效证书的定义。
用此指令的参数指定要注册到无效证书列表中的内容。用户用证书认证模式连接到虚拟 HUB 时,如果其证书与无效证书列表中注册的一条以上的内容一致,将拒绝该用户的连接。
与此指令指定的参数定义的所有条件相一致的证书,会被判断为无效。
可以设置该项目为:[名称 (CN)],[所属机构 (O)],[组织单位 (OU)],[国家 (C)],[州 (ST)],[现地 (L)],[序号 (十六进制)],[MD5 摘要值 (十六进制,128 位)],[SHA-1 摘要值 (十六进制,160位)]。摘要值 (哈希值) 的指定,是将证明书指定为事实上的唯一。通常情况下,如果输入 MD5 或 SHA-1摘要值,就不用输入其他项目。
此命令用 VPN Bridge 不能运行。
此命令在群集内作为群集成员服务器操作的 VPN Server 的虚拟 HUB 上不能运行。
命令行格式 + CrlAdd [/SERIAL:serial] [/MD5:md5] [/SHA1:sha1] [/CN:cn] [/O:o] [/OU:ou] [/C:c] [/ST:st] [/L:l]
"CrlAdd" 命令中可以指定的参数引数的一览:
/SERIAL + 作为条件,在设定证书的序列号 (16 进制) 时,以此此参数指定其值。
/MD5 + 作为条件,在设定证书的 MD5 摘要值 (十六进制,128 位) 时,以此参数指定其值。如果不指定 16 进制 32 个字符 (16 字节) 的参数,则被忽略。
/SHA1 + 作为条件,在设定证书的 SHA-1 摘要值的条件 (十六进制,160 位) 时,以此参数指定其值。如不指定十六进制 40 个字符 (20 字节) 的参数,则被忽略。
/CN + 作为条件,指定证书的名称 (CN) 时,以此参数设定其值。
/O + 作为条件,指定证书的所属机构 (O) 时,以此参数设定其值。
/OU + 作为条件,指定证书的组织单位 (OU) 时,以此参数设定其值。
/C + 作为条件,指定证书的国家 (C) 时,以此参数设定其值。
/ST + 作为条件,指定证书的州 (ST) 时,以此参数设定其值。
/L + 作为条件,指定证书的当地 (L) 时,以此参数设定其值。
+

 

+

6.4.110 "CrlDel": 删除无效的证书

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CrlDel
命令的概要 + 删除无效的证书
说明 + 从目前管理的虚拟 HUB设置的无效证书名单中指定并删除无效证书的定义。
目前注册的无效证书的定义列表,可用 CrlList 指令获取。
该指令虚拟专用桥不能运行。
该指令在作为进群操作的 VPN Server 的虚拟服务器上不能执行。
命令行格式 + CrlDel [id]
"CrlDel" 命令中可以指定的参数引数的一览:
id + 指定要删除的无效的证书的定义中的 ID。
+

 

+

6.4.111 "CrlGet": 获取无效的证书

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CrlGet
命令的概要 + 获取无效的证书
说明 + 从目前管理的虚拟 HUB 设置的无效证书名单中指定无效证书的定义,获取其定义的内容。
目前注册的无效证书的定义列表,可用 CrlList 指令获取。
该指令虚拟专用桥不能运行。
该指令在作为进群操作的 VPN Server 的虚拟服务器上不能执行。
命令行格式 + CrlGet [id]
"CrlGet" 命令中可以指定的参数引数的一览:
id + 指定要获取的无效的证书的定义中的 ID。
+

 

+

6.4.112 "AcList": 获取源 IP 地址访问限制列表的规则项目列表

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AcList
命令的概要 + 获取源 IP 地址访问限制列表的规则项目列表
说明 + 用本命令来获取目前管理的虚拟 HUB 上设置的源 IP 地址限制列表规则的列表。
根据客户端电脑的源 IP 地址,您可以允许或拒绝对该虚拟 HUB 的 VPN 连接。可以定义多个规则,设置每个规则的优先顺序。优先顺序按照从高到低顺序,根据最先与 IP 地址匹配的规则运行,允许或拒绝从客户端的连接。
该命令在 VPN Bridge 上不能运行。
以集群成员运行的 VPN Server 的虚拟 HUB 不能执行此命令。
命令行格式 + AcList
"AcList" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.4.113 "AcAdd": 添加规则到 IP 地址限制列表(IPv4)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AcAdd
命令的概要 + 添加规则到 IP 地址限制列表(IPv4)
说明 + 在目前管理的虚拟 HUB 设置的 IP 地址限制列表中添加新规则。
当 VPN Client 试图连接虚拟 HUB 时,在此设置的项目决定允许或拒绝来自该客户端的连接。
你可以指定规则项目的内容相匹配的客户端 IP 地址,或者 IP 地址和子网掩码。如果只指定 IP 地址,仅指定一台与该规则相匹配的计算机;如果指定 IP 网络掩码地址和子网掩码地址,该规则匹配的子网范围内的所有计算机均被指定。
可以设置规则的优先顺序。以大于 1 的整数指定优先顺序,值越小则优先顺序越高。
要获取目前注册的源 IP 地址限制列表,使用 AcList 命令。
该命令在 VPN Bridge 上不能运行。
以集群成员运行的 VPN Server 的虚拟 HUB 不能执行此命令。
命令行格式 + AcAdd [allow|deny] [/PRIORITY:priority] [/IP:ip/mask]
"AcAdd" 命令中可以指定的参数引数的一览:
allow|deny + 设定允许 ("allow") 或拒绝 ("deny") 与规则相一致的来自客户端的连接。
/PRIORITY + 以大于 1 的整数指定该规则的优先顺序。其值越小则优先顺序越高。
/IP + 以 "IP 地址/掩码" 的形式指定客户端 IPv4 地址范围。IPv4 地址为 "192.168.0.1" 那样的,指定为用点分隔的十进制数。掩码为 "255.255.255.0" 那样的,指定为用点分隔的十进制数,可以用十进制数指定 24 位从头开始的比特长度,可作为十进制 10 款规定。要指定一个单独的 IPv4 主机,指定掩码为 "32" 或者 "255.255.255.255"
+

 

+

6.4.114 "AcDel": 源 IP 地址限制列表内的删除规则

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AcDel
命令的概要 + 源 IP 地址限制列表内的删除规则
说明 + 使用本命令删除目前管理的虚拟 HUB 设置的 IP 地址限制列表的规则。
要获取目前注册的 IP 访问控制列表的规则列表,使用AcList命令。
该指令虚拟专用桥不能运行。
该命令在 VPN Bridge 上不能运行。
以集群成员运行的 VPN Server 的虚拟 HUB 不能执行此命令。
命令行格式 + AcDel [id]
"AcDel" 命令中可以指定的参数引数的一览:
id + 指定要删除的源 IP 地址限制列表内的规则的 ID。
+

 

+

6.4.115 "AcAdd6": 添加规则到源 IP 地址访问限制列表(IPv6)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AcAdd6
命令的概要 + 添加规则到源 IP 地址访问限制列表(IPv6)
说明 + 在目前管理的虚拟 HUB 设置的 IP 地址限制列表中添加新规则。
当 VPN Client 试图连接虚拟 HUB 时,在此设置的项目决定允许或拒绝来自该客户端的连接。
你可以指定规则项目的内容相匹配的客户端 IP 地址,或者 IP 地址和子网掩码。如果只指定 IP 地址,仅指定一台与该规则相匹配的计算机;如果指定 IP 网络掩码地址和子网掩码地址,该规则匹配的子网范围内的所有计算机均被指定。
可以设置规则的优先顺序。以大于 1 的整数指定优先顺序,值越小则优先顺序越高。
要获取目前注册的源 IP 地址限制列表,使用 AcList 命令。
该命令在 VPN Bridge 上不能运行。
以集群成员运行的 VPN Server 的虚拟 HUB 不能执行此命令。
命令行格式 + AcAdd6 [allow|deny] [/PRIORITY:priority] [/IP:ip/mask]
"AcAdd6" 命令中可以指定的参数引数的一览:
allow|deny + 设定允许 ("allow") 或拒绝 ("deny") 与规则相一致的来自客户端的连接。
/PRIORITY + 以大于 1 的整数指定该规则的优先顺序。其值越小则优先顺序越高。
/IP + 以 [IP 地址/掩码] 的形式指定客户端 IPv6 地址范围。IPv6 地址为 2001:200:0:1:: 那样的,指定由冒号分隔的十六进制数。掩码为 ffff:ffff:ffff:ffff:: 那样的,指定由冒号分隔的十六进制数,可以用十进制数指定 64 位从头开始的比特长度,可作为十进制 10 款规定。如果设定为 "::/128" 则显示单一的主机。
+

 

+ + + + + + + + + + +------ 3 ------ + + + + + + + + + +

6.5.1 "About": 显示版本信息

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + About
命令的概要 + 显示版本信息
说明 + 这显示了此命令行管理工具的版本信息。版本信息中包括了 vpncmd 版本号,内部标号和内部标号信息。
命令行格式 + About
"About" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.5.2 "VersionGet": 获取 VPN 客户服务的版本信息

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + VersionGet
命令的概要 + 获取 VPN 客户服务的版本信息
说明 + 获取目前管理的 VPN 客户服务程序的版本信息。
命令行格式 + VersionGet
"VersionGet" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.5.3 "PasswordSet": 为连接到 VPN 客户服务的密码的设定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + PasswordSet
命令的概要 + 为连接到 VPN 客户服务的密码的设定
说明 + 对 VPN Client 服务,从命令行管理工具及 VPN Client 经理来进行连接控制时,可以要求输入密码。使用此指令,可以设置要求输入的密码。
以只对从远程 (本地主机以外的电脑) 进行操作时要求其输入密码。
命令行格式 + PasswordSet [password] [/REMOTEONLY:yes|no]
"PasswordSet" 命令中可以指定的参数引数的一览:
password + 指定要设置的密码。如指定为 "none",可以删除密码的设置。
/REMOTEONLY + 如果指定 "yes",只对从远程 (本地主机以外的电脑) 进行操作时要求其输入密码,从本地主机连接时,不要求密码。如果省略此参数,则视为 "no"。
+

 

+

6.5.4 "PasswordGet": 获取为连接到 VPN 客户服务的密码的设定

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + PasswordGet
命令的概要 + 获取为连接到 VPN 客户服务的密码的设定
说明 + 对 VPN Client 服务,从命令行管理工具及 VPN Client 经理来进行连接控制时,获取是否要求输入密码的设置。
而且,对于要求密码的情况下,获取是否设置只对从远程 (本地主机以外的电脑) 进行操作的情况要求输入密码。
命令行格式 + PasswordGet
"PasswordGet" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.5.5 "CertList": 获取信任的证明机构的证书列表

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CertList
命令的概要 + 获取信任的证明机构的证书列表
说明 + VPN Client 管理信用的证明机构的证书列表。已注册的证明机构证书的注册列表,用来进行连接 VPN Server 时的验证服务器证书。
命令行格式 + CertList
"CertList" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.5.6 "CertAdd": 添加信任的证明机构的证书

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CertAdd
命令的概要 + 添加信任的证明机构的证书
说明 + 向 VPN Client 信任的证明机构的证书列表添加新证书。已注册的证明机构证书的注册列表,用来进行连接 VPN Server 时的验证服务器证书。
要获取当前的证书列表,使用 CertList 指令。
要添加证书,该证书需要保存为 X.509 格式的文件。
命令行格式 + CertAdd [path]
"CertAdd" 命令中可以指定的参数引数的一览:
path + 指定要注册的 X.509 证书的文件名。
+

 

+

6.5.7 "CertDelete": 删除信任的证明机构的证书

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CertDelete
命令的概要 + 删除信任的证明机构的证书
说明 + 从 VPN Client 信任的证明机构的证书列表中删除现有的证书。
要获取当前的证书列表,使用 CertList 命令。
命令行格式 + CertDelete [id]
"CertDelete" 命令中可以指定的参数引数的一览:
id + 指定要删除的证书的 ID。
+

 

+

6.5.8 "CertGet": 获得新任的证明机构的证书

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + CertGet
命令的概要 + 获得新任的证明机构的证书
说明 + 获取 VPN Client 信任的证明机构的证书列表中的现有证书,以 X.509 格式文件保存。
命令行格式 + CertGet [id] [/SAVECERT:path]
"CertGet" 命令中可以指定的参数引数的一览:
id + 指定要获取的证书 ID。
/SAVECERT + 指定获取到的证书的保存文件名。
+

 

+

6.5.9 "SecureList": 获取可用的智能卡种类列表

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + SecureList
命令的概要 + 获取可用的智能卡种类列表
说明 + VPN Client 显示的被支持的智能卡类型的列表。
智能卡类型的列表,目前的计算机上被安装驱动程序,且显示以 VPN 软件支持的设备列表。

如果没有显示目前使用的智能卡型,或许可以通过更新 VPN 软件至新的版本来使用。
命令行格式 + SecureList
"SecureList" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.5.10 "SecureSelect": 选择要使用的智能卡种类

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + SecureSelect
命令的概要 + 选择要使用的智能卡种类
说明 + 选择 VPN 客户使用的智能卡类型。
可以使用的智能卡种类列表,可用 SecureList 指令获取。
命令行格式 + SecureSelect [id]
"SecureSelect" 命令中可以指定的参数引数的一览:
id + 指定智能卡种类的 ID。
+

 

+

6.5.11 "SecureGet": 获取使用的智能卡种类的 ID

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + SecureGet
命令的概要 + 获取使用的智能卡种类的 ID
说明 + 获取为当前 VPN 客户的使用而设置的智能卡种类的 ID。通过基于此 ID 上的 SecureList 指令的结果,可以获取当前选择的智能卡类型。
如果当前的智能卡没有被选择,ID 显示是 0。
命令行格式 + SecureGet
"SecureGet" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.5.12 "NicCreate": 新的虚拟 LAN 卡的创建

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + NicCreate
命令的概要 + 新的虚拟 LAN 卡的创建
说明 + 将新的虚拟 LAN 卡添加到系统。可以对虚拟 LAN 卡任意命名。
然而,给虚拟 LAN 卡命名时只能使用英文字母数字,Windows 2000 以上的系统最大可设置 31 个字符,Windows 98,98 SE 和 ME 系统最大可设置 4 个字符。
调用了 NicCreate 指令时,VPN Client 运行的操作系统,将被安装新的虚拟 LAN 卡设备驱动程序。
在此情况下,操作系统可能会显示对话框,确认是否要安装设备驱动程序。
命令行格式 + NicCreate [name]
"NicCreate" 命令中可以指定的参数引数的一览:
name + 指定虚拟 LAN 卡名。
+

 

+

6.5.13 "NicDelete": 删除虚拟 LAN 卡

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + NicDelete
命令的概要 + 删除虚拟 LAN 卡
说明 + 从系统中删除现有的虚拟 LAN 卡。
当从系统中删除虚拟 LAN 卡,使用此虚拟 LAN 卡的连接将被中断。
而且,位使用被删除的虚拟 LAN 卡而设置的连接设置,自动更改设置为使用别的虚拟 LAN 卡。
当 VPN 客户运行 Windows 2000 以上的操纵系统时,此指令可以被使用。
命令行格式 + NicDelete [name]
"NicDelete" 命令中可以指定的参数引数的一览:
name + 指定的虚拟 LAN 卡名
+

 

+

6.5.14 "NicUpgrade": 升级虚拟 LAN 卡设备驱动

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + NicUpgrade
命令的概要 + 升级虚拟 LAN 卡设备驱动
说明 + 如果现有的虚拟 LAN 卡的设备驱动程序版本太旧,在当前正在运行的 VPN Client 升级到同包附带的最新的设备驱动程序。即使不进行升级,也要重新安装设备驱动程序。
操作系统可能会显示对话框,确认是否要安装设备驱动程序。
此指令,在 VPN Client 正运行 Windows 2000 以上的操作系统时能够使用。
命令行格式 + NicUpgrade [name]
"NicUpgrade" 命令中可以指定的参数引数的一览:
name + 指定的虚拟 LAN 卡名
+

 

+

6.5.15 "NicGetSetting": 获取虚拟 LAN 卡的设置

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + NicGetSetting
命令的概要 + 获取虚拟 LAN 卡的设置
说明 + 获取现有的虚拟 LAN 卡的 MAC 地址设置。
当 VPN 客户运行 Windows 2000 以上的操纵系统时,此指令可以被使用。
命令行格式 + NicGetSetting [name]
"NicGetSetting" 命令中可以指定的参数引数的一览:
name + 指定虚拟 LAN 卡名
+

 

+

6.5.16 "NicSetSetting": 更改虚拟 LAN 卡设置

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + NicSetSetting
命令的概要 + 更改虚拟 LAN 卡设置
说明 + 更改现有的虚拟 LAN 卡的 MAC 地址设置。一旦启动该指令,目前运行中的虚拟 LAN 卡设备驱动将被重新启动。
当 VPN 客户运行 Windows 2000 以上的操纵系统时,此指令可以被使用。
命令行格式 + NicSetSetting [name] [/MAC:mac]
"NicSetSetting" 命令中可以指定的参数引数的一览:
name + 指定虚拟 LAN 卡名
/MAC + 指定要设置的 MAC 地址。 +MAC 地址请用 6 字节十六进制字符串指定。 +例如: 00:AC:01:23:45:67 或 00-AC-01-23-45-67
+

 

+

6.5.17 "NicEnable": 启用虚拟 LAN 卡

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + NicEnable
命令的概要 + 启用虚拟 LAN 卡
说明 + 启动现有的被禁用的虚拟 LAN 卡。
当 VPN 客户运行 Windows 2000 以上的操纵系统时,此指令可以被使用。
命令行格式 + NicEnable [name]
"NicEnable" 命令中可以指定的参数引数的一览:
name + 指定虚拟 LAN 卡的名称。
+

 

+

6.5.18 "NicDisable": 禁用虚拟 LAN 卡

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + NicDisable
命令的概要 + 禁用虚拟 LAN 卡
说明 + 禁用现有的正使用的虚拟 LAN 卡。
当 VPN 客户运行 Windows 2000 以上的操纵系统时,此指令可以被使用。
命令行格式 + NicDisable [name]
"NicDisable" 命令中可以指定的参数引数的一览:
name + 指定虚拟 LAN 卡的名称。
+

 

+

6.5.19 "NicList": 获取虚拟 LAN 卡列表

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + NicList
命令的概要 + 获取虚拟 LAN 卡列表
说明 + 获取在当前系统注册的虚拟 LAN 卡列表
命令行格式 + NicList
"NicList" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.5.20 "AccountList": 获取连接设置列表

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountList
命令的概要 + 获取连接设置列表
说明 + 获取登录到 VPN Client 的连接设置列表
命令行格式 + AccountList
"AccountList" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.5.21 "AccountCreate": 创建新的连接设置

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountCreate
命令的概要 + 创建新的连接设置
说明 + 在 VPN Client 创建新的连接设置。
要创建连接设置,作为初始参数需要指定加在连接设置名称和连接终端的服务器,及连接终端的虚拟 HUB,用户名上使用的虚拟 LAN 卡名。创建了新的连接设置时,用户认证的类型被初始设置为 [匿名认证],代理服务器的设置和服务器证书的检查选项不被设置。若要更改这些设置和其他的详细设置,创建连接设置后,使用以 "Account" 名字开始的其他指令。
命令行格式 + AccountCreate [name] [/SERVER:hostname:port] [/HUB:hubname] [/USERNAME:username] [/NICNAME:nicname]
"AccountCreate" 命令中可以指定的参数引数的一览:
name + 指定要创建的连接设置名
/SERVER + 以 [主机名:端口号] 的形式指定终端 VPN Server 的主机名,端口号。可以通过 IP 地址进行指定。
/HUB + 在终端 VPN Server 上指定虚拟 HUB。
/USERNAME + 指定在连接到终端 VPN Server 时用于用户认证的用户名。
/NICNAME + 指定用于连接的虚拟 LAN 卡名。
+

 

+

6.5.22 "AccountSet": 设定连接设置连接终端

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountSet
命令的概要 + 设定连接设置连接终端
说明 + 设置注册在 VPN 客户的连接设置的终端 VPN Server 主机名和端口号,虚拟 HUB 名,及用于连接的用户名,加在其上使用的虚拟 LAN 卡名。
命令行格式 + AccountSet [name] [/SERVER:hostname:port] [/HUB:hubname]
"AccountSet" 命令中可以指定的参数引数的一览:
name + 指定要更改设置的连接设置名。
/SERVER + 以 [主机名:端口号] 的形式指定终端 VPN Server 的主机名,端口号。可以通过 IP 地址进行指定。
/HUB + 指定终端的 VPN Server 上的虚拟 HUB。
+

 

+

6.5.23 "AccountGet": 取得连接设置的设置

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountGet
命令的概要 + 取得连接设置的设置
说明 + 获取注册到 VPN Client 的连接设置的连接设置内容。
而且,要改变连接设置的连接设置内容,在创建连接设置后使用其他的以 "Account" 名开始的的指令。
命令行格式 + AccountGet [name]
"AccountGet" 命令中可以指定的参数引数的一览:
name + 指定要获取的连接设置名。
+

 

+

6.5.24 "AccountDelete": 删除连接设置

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountDelete
命令的概要 + 删除连接设置
说明 + 删除注册到 VPN Client 的连接设置。如果指定的连接设置处于在线状态,将会自动断开连接并删除。
命令行格式 + AccountDelete [name]
"AccountDelete" 命令中可以指定的参数引数的一览:
name + 指定要删除的连接设置名。
+

 

+

6.5.25 "AccountUsernameSet": 设置用于连接的连接设置的用户名

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountUsernameSet
命令的概要 + 设置用于连接的连接设置的用户名
说明 + 指定注册到 VPN Client 的连接设置,且其连接设置连接到 VPN Server 上时,指定需要进行用户认证的用户名。
而且,在一些情况下有必要指定用户认证的种类和需要的参数。要更改这些信息,可以使用如下指令: AccountAnonymousSet, AccountPasswordSet, AccountCertSet 和 AccountSecureCertSet。
命令行格式 + AccountUsernameSet [name] [/USERNAME:username]
"AccountUsernameSet" 命令中可以指定的参数引数的一览:
name + 指定更改设置的连接设置名。
/USERNAME + 指定连接设置连接到 VPN Server 上时需要进行用户认证的用户名。
+

 

+

6.5.26 "AccountAnonymousSet": 设定连接设置的用户认证种类为匿名认证

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountAnonymousSet
命令的概要 + 设定连接设置的用户认证种类为匿名认证
说明 + 指定注册到 VPN Client 的连接设置,把其连接设置连接到 VPN Server 上时的用户认证方法,设置为 [匿名认证]。
命令行格式 + AccountAnonymousSet [name]
"AccountAnonymousSet" 命令中可以指定的参数引数的一览:
name + 指定更改设置的连接设置名。
+

 

+

6.5.27 "AccountPasswordSet": 设定连接设置的用户证类型为密码认证

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountPasswordSet
命令的概要 + 设定连接设置的用户证类型为密码认证
说明 + 指定注册到 VPN Client 的连接设置,把其连接设置连接到 VPN Server 上时的用户认证方法,设置为 [密码认证]。指定 [标准密码认证] 和 [RADIUS 或 NT 域认证] 作为密码认证种类。
命令行格式 + AccountPasswordSet [name] [/PASSWORD:password] [/TYPE:standard|radius]
"AccountPasswordSet" 命令中可以指定的参数引数的一览:
name + 指定更改设置的连接设置名。
/PASSWORD + 指定密码认证使用的密码。如果不指定,将显示输入密码的提示。
/TYPE + 作为密码认证类型,指定 "standard" (标准密码认证) 或 "radius" (RADIUS 或 NT 域认证) 的二者之一。
+

 

+

6.5.28 "AccountCertSet": 设置连接设置的用户认证类型为用户证书认证

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountCertSet
命令的概要 + 设置连接设置的用户认证类型为用户证书认证
说明 + 指定注册到 VPN Client 的连接设置,把其连接设置连接到 VPN Server 上时的用户认证方法,设置为 [用户证书认证]。作为该证书,必须指定证书文件为 X.509 格式且私钥文件是 Base 64 编码。
命令行格式 + AccountCertSet [name] [/LOADCERT:cert] [/LOADKEY:key]
"AccountCertSet" 命令中可以指定的参数引数的一览:
name + 指定要更改设置的连接设置名
/LOADCERT + 指定以证书认证提交的 X.509 格式证书的文件名。
/LOADKEY + 指定以对应证书的 Base 64 格式的编码私钥文件名。
+

 

+

6.5.29 "AccountCertGet": 获取用于连接设置的客户端证书

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountCertGet
命令的概要 + 获取用于连接设置的客户端证书
说明 + 当指定注册到 VPN Client 的连接设置,其连接设置使用使用客户证书认证时,获取作为客户证书提出的证书,并保存该证书文件为 X.509 格式。
命令行格式 + AccountCertGet [name] [/SAVECERT:cert]
"AccountCertGet" 命令中可以指定的参数引数的一览:
name + 指定要获取设置的连接设置名。
/SAVECERT + 指定以 X.509 格式保存获取的证书的文件名。
+

 

+

6.5.30 "AccountEncryptDisable": 禁用连接设置进行通信时的加密

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountEncryptDisable
命令的概要 + 禁用连接设置进行通信时的加密
说明 + 当指定注册到 VPN Client 的连接设置,且其连接设置与 VPN Server 间进行 VPN 连接通信时,将与 VPN Server 间的通信内容以 SSL 设置为不加密。
通常,将与 VPN Server 间的通信以 SSL 加密,是防止信息的窃听和篡改。也可以禁用加密。当禁用加密时,通信量将扩大但是通信数据将以纯文本格式在网络上传输。
命令行格式 + AccountEncryptDisable [name]
"AccountEncryptDisable" 命令中可以指定的参数引数的一览:
name + 指定要更改设置的连接设置名。
+

 

+

6.5.31 "AccountEncryptEnable": 启用连接设置进行通信的加密

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountEncryptEnable
命令的概要 + 启用连接设置进行通信的加密
说明 + 当指定注册到 VPN Client 的连接设置,且其连接设置与 VPN Server 间进行 VPN 连接通信时,将与 VPN Server 间的通信内容以 SSL 设置为加密。
通常,将与 VPN Server 间的通信以 SSL 加密,是防止信息的窃听和篡改。也可以禁用加密。当禁用加密时,通信量将扩大但是通信数据将以纯文本格式在网络上传输。
命令行格式 + AccountEncryptEnable [name]
"AccountEncryptEnable" 命令中可以指定的参数引数的一览:
name + 指定要更改设置的连接设置名。
+

 

+

6.5.32 "AccountCompressEnable": 启用连接设置进行通信时的数据压缩

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountCompressEnable
命令的概要 + 启用连接设置进行通信时的数据压缩
说明 + 当指定注册到 VPN Client 的连接设置,且其连接设置与 VPN Server 间进行 VPN 连接通信时,将与 VPN Server 间的通信内容设置为压缩。
最大可以进行约 80% 的压缩。但是,压缩会使客户端及服务器双方的 CPU 产生较高的负荷。当线路速度为约 10 Mbps 以上时,压缩可能会降低吞吐量,产生反面效果。
命令行格式 + AccountCompressEnable [name]
"AccountCompressEnable" 命令中可以指定的参数引数的一览:
name + 指定要更改设置的连接设置名。
+

 

+

6.5.33 "AccountCompressDisable": 禁用连接设置进行通信时的数据压缩

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountCompressDisable
命令的概要 + 禁用连接设置进行通信时的数据压缩
说明 + 当指定注册到 VPN Client 的连接设置,且其连接设置与 VPN Server 间进行 VPN 连接通信时,将与 VPN Server 间的通信内容设置为不压缩。
命令行格式 + AccountCompressDisable [name]
"AccountCompressDisable" 命令中可以指定的参数引数的一览:
name + 指定要更改设置的连接设置名。
+

 

+

6.5.34 "AccountProxyNone": 将连接设置的连接方法直接设置为 TCP/IP 连接

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountProxyNone
命令的概要 + 将连接设置的连接方法直接设置为 TCP/IP 连接
说明 + 当指定注册到 VPN Client 的连接设置,将其连接设置与 VPN Server 间进行 VPN 连接时使用的连接方法设置为 [直接 TCP/IP连接],不通过代理服务器。
命令行格式 + AccountProxyNone [name]
"AccountProxyNone" 命令中可以指定的参数引数的一览:
name + 指定要更改设置的连接设置名。
+

 

+

6.5.35 "AccountProxyHttp": 将连接设置的连接方法设置为通过 HTTP 代理服务器连接

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountProxyHttp
命令的概要 + 将连接设置的连接方法设置为通过 HTTP 代理服务器连接
说明 + 当指定注册到 VPN Client 的连接设置,将其连接设置与 VPN Server 间进行 VPN 连接时使用的连接方法设置为 [通过 HTTP 代理服务器连接],指定将通过的 HTTP 代理服务器的主机名和端口号,用户名和密码 (如果需要)。
通过 HTTP 代理服务器,必须对应因进行 HTTPS 通信的 CONNECT 方法。
命令行格式 + AccountProxyHttp [name] [/SERVER:hostname:port] [/USERNAME:username] [/PASSWORD:password]
"AccountProxyHttp" 命令中可以指定的参数引数的一览:
name + 指定要更改设置的连接设置名。
/SERVER + 以 [主机名:端口号] 的形式,指定通过 HTTP 代理服务器的主机名或 IP 地址和端口号。
/PASSWORD + 如果因为连接通过 HTTP 代理服务器而需要用户认证时,指定密码。与 /USERNAME 参数一起指定。
+

 

+

6.5.36 "AccountProxySocks": 将连接设置的连接方法设置为通过 SOCKS 代理服务器连接

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountProxySocks
命令的概要 + 将连接设置的连接方法设置为通过 SOCKS 代理服务器连接
说明 + 当指定注册到 VPN Client 的连接设置,将其连接设置与 VPN Server 间进行 VPN 连接时使用的连接方法设置为 [通过 SOCKS 服务器连接],并指定要通过的 SOCKS 代理服务器的主机名和端口号,用户名和密码 (如果需要)。
通过 SOCKS 服务器,必须对应 SOCKS 版本 4。
命令行格式 + AccountProxySocks [name] [/SERVER:hostname:port] [/USERNAME:username] [/PASSWORD:password]
"AccountProxySocks" 命令中可以指定的参数引数的一览:
name + 指定要更改设置的连接设置名。
/SERVER + 以 [主机名:端口号] 形式,指定要通过的 SOCKS 代理服务器主机名或 IP 地址和端口号。
/PASSWORD + 如果因为连接通过 SOCKS 代理服务器而需要用户认证时,指定密码。与 /USERNAME 参数一起指定。
+

 

+

6.5.37 "AccountServerCertEnable": 启用连接设置服务器证书验证选项

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountServerCertEnable
命令的概要 + 启用连接设置服务器证书验证选项
说明 + 指定注册到 VPN Client 的连接设置,其连接设置连接到 VPN Server 时,启动检查连接终端的 VPN Server 提交的 SSL 证书是否可信的选项。
如果启用此选项,可以预先将连接目标服务器的 SSL 证书以 AccountServerCertSet 指令保存在连接设置的设置内,或建议将服务器的 SSL 证书签名了的根证书,以 CertAdd 指令注册到虚拟 HUB 信任的证明机构的证书列表中。如果没有注册,初次连接时可能会显示确认信息。
验证连接设置的服务器证书的选项处于启动状态,连接了的 VPN Server 的证书不可信时,立即解除连接,反复重试。
命令行格式 + AccountServerCertEnable [name]
"AccountServerCertEnable" 命令中可以指定的参数引数的一览:
name + 指定要更改设置的连接设置名。
+

 

+

6.5.38 "AccountServerCertDisable": 禁用连接设置服务器证书验证选项

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountServerCertDisable
命令的概要 + 禁用连接设置服务器证书验证选项
说明 + 指定注册到 VPN Client 的连接设置,其连接设置与 VPN Server 连接时,禁止检验由目标 VPN Server 提供的 SSL 证明书是否可信的选项。
命令行格式 + AccountServerCertDisable [name]
"AccountServerCertDisable" 命令中可以指定的参数引数的一览:
name + 指定要更改设置的连接设置名。
+

 

+

6.5.39 "AccountServerCertSet": 设置连接设置的服务器固有证明书

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountServerCertSet
命令的概要 + 设置连接设置的服务器固有证明书
说明 + 指定注册到 VPN Client 的连接设置,其连接设置连接到 VPN Server 时,预先注册与连接目标的 VPN Server 提交的 SSL 证书相同的证书。
如果启动了连接设置的服务器证书验证选项,可以预先将连接目标服务器的 SSL 证书以此指令保存在连接设置的设置内,或需要将服务器的 SSL 证书签名了的根证书,以 CAAdd 指令注册到虚拟 HUB 信任的证明机构的证书列表中。
验证连接设置的服务器证书的选项处于启动状态,连接了的 VPN Server 的证书不可信时,立即解除连接,反复重试。
命令行格式 + AccountServerCertSet [name] [/LOADCERT:cert]
"AccountServerCertSet" 命令中可以指定的参数引数的一览:
name + 指定要更改设置的连接设置名。
/LOADCERT + 指定以 X.509 证书格式保存的设置服务器固有证书的证书文件名。
+

 

+

6.5.40 "AccountServerCertDelete": 删除连接设置的服务器固有证书

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountServerCertDelete
命令的概要 + 删除连接设置的服务器固有证书
说明 + 指定注册到到 VPN Client 的连接设置,且其连接设置注册了服务器固有证书时,删除证书。
命令行格式 + AccountServerCertDelete [name]
"AccountServerCertDelete" 命令中可以指定的参数引数的一览:
name + 指定要更改设置的连接设置名。
+

 

+

6.5.41 "AccountServerCertGet": 获取连接设置的服务器固有证明书

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountServerCertGet
命令的概要 + 获取连接设置的服务器固有证明书
说明 + 指定注册到到 VPN Client 的连接设置,且其连接设置注册了服务器固有证书时,获取该证书并以 X.509 格式保存证明书文件。
命令行格式 + AccountServerCertGet [name] [/SAVECERT:path]
"AccountServerCertGet" 命令中可以指定的参数引数的一览:
name + 指定要更改设置的连接设置名。
/SAVECERT + 指定以 X.509 证书格式保存的服务器固有证书的证书文件名。
+

 

+

6.5.42 "AccountDetailSet": 设置接续设置的高级通信设置

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountDetailSet
命令的概要 + 设置接续设置的高级通信设置
说明 + 指定注册到 VPN Client 的连接设置,并定制其连接设置与 VPN Server 通信时使用的 VPN 协议的通信设置。
命令行格式 + AccountDetailSet [name] [/MAXTCP:max_connection] [/INTERVAL:additional_interval] [/TTL:disconnect_span] [/HALF:yes|no] [/BRIDGE:yes|no] [/MONITOR:yes|no] [/NOTRACK:yes|no] [/NOQOS:yes|no]
"AccountDetailSet" 命令中可以指定的参数引数的一览:
name + 指定要更改设置的连接设置名。
/MAXTCP + VPN 通信使用的 TCP 连接数,指定从 1 到 32 的整数。在与 VPN Server 之间的 VPN 通信会话上的数据传送,通过使用多个 TCP 连接,可以提高通信速度。 +注意: 如果连接服务器的线路是高速线路时,建议 8 个左右,如果是拨号等低速线路时,建议 1 个。
/INTERVAL + 建立多个 TCP 连接进行 VPN 通信时,以秒为单位指定每个 TCP 连接的建立间隔。规定值为 1 秒。
/TTL + 如果设置的每个 TCP 连接的寿命时,从 TCP 连接的建立到断开的寿命以秒数来指定。如果指定 "0",则寿命未被设置。
/HALF + 要启动半双工模式,指定 "yes"。将两个以上的 TCP 连接捆绑,进行 VPN 通信时,可以使用 "半双工模式"。启动半双工模式,能够自动将各 TCP 连接的数据传输方向固定各一半。例如,使用 8 个 TCP 连接建立了 VPN 会话时,启动半双工模式,则固定 4 个 TCP 连接为上传方向专用,剩下 4 个 TCP 连接为下载方向专用,进行通信。
/BRIDGE + 与 VPN Server 以 "桥 / 路由器模式" 连接时,指定 "yes"。使用桥/路由器模式连接时,VPN Client 的虚拟 LAN 卡方将能够与其他网络进行桥或路由。然而,如果用于连接的用户的安全策略禁用桥或路由时,则连接失败。
/MONITOR + 与 VPN Server 以 "监控模式" 连接时,指定 "yes"。如果使用监测模式连接时,可以接收虚拟 HUB 内传送的所有的数据包。然而,用于连接的用户安全策略不允许监视模式时,则连接失败。
/NOTRACK + 指定 "yes",禁用路由器表项调节器。通常情况下,指定 "no"。
/NOQOS + 禁用 VoIP / QoS 功能时指定 "yes"。通常指定 "no"。
+

 

+

6.5.43 "AccountRename": 更改连接设置名称

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountRename
命令的概要 + 更改连接设置名称
说明 + 指定在 VPN Client 注册的连接设置,更改其连接设置名称。
命令行格式 + AccountRename [name] [/NEW:new_name]
"AccountRename" 命令中可以指定的参数引数的一览:
name + 指定要更改名称的连接设置的当前名称。
/NEW + 指定变更后的新名称。
+

 

+

6.5.44 "AccountConnect": 使用连接设置,开始连接 VPN Server

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountConnect
命令的概要 + 使用连接设置,开始连接 VPN Server
说明 + 指定注册到 VPN Client 的连接设置,并启动连接设置连接到 VPN Server 上。处于正在连接中或已连接状态的连接设置,将一直连接 VPN Server,或不断尝试连接 VPN Server,直到使用 AccountDisconnect 指令断开连接。(但是,如果使用 AccountRetrySet 指令指定了重试次数时,连接尝试将在达到被指定次数时中断。)
命令行格式 + AccountConnect [name]
"AccountConnect" 命令中可以指定的参数引数的一览:
name + 指定要启动的连接设置名。
+

 

+

6.5.45 "AccountDisconnect": 断开连接中的连接设置

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountDisconnect
命令的概要 + 断开连接中的连接设置
说明 + 指定注册到 VPN Client 的连接设置,其连接设置处于连接处理中或已连接的状态时,立即将其断开。
命令行格式 + AccountDisconnect [name]
"AccountDisconnect" 命令中可以指定的参数引数的一览:
name + 指定要断开的连接设置名。
+

 

+

6.5.46 "AccountStatusGet": 获取当前连接设置的状态

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountStatusGet
命令的概要 + 获取当前连接设置的状态
说明 + 指定注册到 VPN Client 的连接设置,且该连接设置当前已连接时,获取其连接状态和和其他信息。
命令行格式 + AccountStatusGet [name]
"AccountStatusGet" 命令中可以指定的参数引数的一览:
name + 指定要获取信息的连接设置名。
+

 

+

6.5.47 "AccountNicSet": 设置连接设置时使用的虚拟 LAN 卡

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountNicSet
命令的概要 + 设置连接设置时使用的虚拟 LAN 卡
说明 + 更改注册到 VPN 客户上的现有的连接设置用于连接 VPN Server 的虚拟 LAN 卡名。
命令行格式 + AccountNicSet [name] [/NICNAME:nicname]
"AccountNicSet" 命令中可以指定的参数引数的一览:
name + 指定要更改设置的连接设置名。
/NICNAME + 指定连接 VPN Server 时使用的虚拟 LAN 卡名。
+

 

+

6.5.48 "AccountStatusShow": 设置成在连接到 VPN Server 时显示连接状态和错误的画面

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountStatusShow
命令的概要 + 设置成在连接到 VPN Server 时显示连接状态和错误的画面
说明 + 指定注册到 VPN Client 的连接设置且用其连接设置连接到 VPN Server 时,设置在计算机上显示连接状态和错误画面。
命令行格式 + AccountStatusShow [name]
"AccountStatusShow" 命令中可以指定的参数引数的一览:
name + 指定要更改设置的连接设置名。
+

 

+

6.5.49 "AccountStatusHide": 设置成在连接到 VPN Server 时不显示连接状态和错误的画面

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountStatusHide
命令的概要 + 设置成在连接到 VPN Server 时不显示连接状态和错误的画面
说明 + 指定注册到 VPN Client 的连接设置且用其连接设置连接到 VPN Server 时,设置在计算机上不显示连接状态和错误画面。
命令行格式 + AccountStatusHide [name]
"AccountStatusHide" 命令中可以指定的参数引数的一览:
name + 指定要更改设置的连接设置名。
+

 

+

6.5.50 "AccountSecureCertSet": 将连接设置的用户认证类型设置为智能卡认证

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountSecureCertSet
命令的概要 + 将连接设置的用户认证类型设置为智能卡认证
说明 + 指定注册到 VPN Client 的连设置,将其连接设置连接到 VPN Server 时的用户认证方法设置为 [智能卡认证]。此外,必须指定存储在智能卡上的证书对象名和密钥对象名。
命令行格式 + AccountSecureCertSet [name] [/CERTNAME:cert] [/KEYNAME:key]
"AccountSecureCertSet" 命令中可以指定的参数引数的一览:
name + 指定要更改设置的连接设置名。
/CERTNAME + 指定存储在智能卡中的证书对象名。
/KEYNAME + 指定存储在智能卡中的密钥对象名。
+

 

+

6.5.51 "AccountRetrySet": 设置连接设置的连接失败或断开时建立重新连接的次数和间隔

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountRetrySet
命令的概要 + 设置连接设置的连接失败或断开时建立重新连接的次数和间隔
说明 + 指定注册到 VPN Client 的连接设置,且其连接设置试图连接到 VPN Server 时,还有连接中的与 VPN Server 的通信被断开或连接失败时,指定连接的重试次数和连接重试的间隔。
而且,如果用户认证类型为 [智能卡认证] 时,不管连接重试次数如何设置,都将不进行连接重试。
命令行格式 + AccountRetrySet [name] [/NUM:num_retry] [/INTERVAL:retry_interval]
"AccountRetrySet" 命令中可以指定的参数引数的一览:
name + 指定要更改设置的连接设置名。
/NUM + 指定连续进行重新连接的次数。 如指定 "999",重试次数为无限次 (永久连接)。如指定 "0",不进行重新连接。
/INTERVAL + 重新进行连接时,设置距离上次断开或连接失败后需多少秒开始重新连接处理。
+

 

+

6.5.52 "AccountStartupSet": 设定连接设置的启动连接

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountStartupSet
命令的概要 + 设定连接设置的启动连接
说明 + 指定注册到 VPN Client 的连接设置,并将其设定为启动连接。设置为启动连接的连接设置,在 VPN Client 服务运行的同时将自动启动连接程序。
命令行格式 + AccountStartupSet [name]
"AccountStartupSet" 命令中可以指定的参数引数的一览:
name + 指定要更改设置的连接设置名。
+

 

+

6.5.53 "AccountStartupRemove": 解除连接设置的启动连接

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountStartupRemove
命令的概要 + 解除连接设置的启动连接
说明 + 指定注册到 VPN Client 的连接设置,并把其连接设置设置为当前启动连接时,解除启动连接设置。
命令行格式 + AccountStartupRemove [name]
"AccountStartupRemove" 命令中可以指定的参数引数的一览:
name + 指定要更改设置的连接设置名。
+

 

+

6.5.54 "AccountExport": 导出连接设置

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountExport
命令的概要 + 导出连接设置
说明 + 指定注册到 VPN Client 的连接设置,将其连接设置的内容作为文本文件导出。因为而后要导入被导出的连接设置,可以复制连接设置的内容。而且,因为以文本文件保存,可以用一般的文本编辑器进行编辑。
导出目标文件,以 UTF-8 格式的文本文件保存。还有,如果在文件名称上添加 .vpn 的扩展名,因为能与 Windows 版 VPN Client 连接员产生关联,会很方便。
命令行格式 + AccountExport [name] [/SAVEPATH:savepath]
"AccountExport" 命令中可以指定的参数引数的一览:
name + 指定导出连接设置的连接设置名。
/SAVEPATH + 指定保存目标文件名
+

 

+

6.5.55 "AccountImport": 导入连接设置

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + AccountImport
命令的概要 + 导入连接设置
说明 + 导入由 AccountExport 指令导出的连接设置文件,添加到 VPN 客户。
命令行格式 + AccountImport [path]
"AccountImport" 命令中可以指定的参数引数的一览:
path + 指定导入源文件名。
+

 

+

6.5.56 "RemoteEnable": 允许 VPN 客户服务的远程管理

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + RemoteEnable
命令的概要 + 允许 VPN 客户服务的远程管理
说明 + 对 VPN Client 服务,从本地主机以外的远程计算机上,允许通过命令行管理设施或 VPN Client 管理器员进行连接和管理。
命令行格式 + RemoteEnable
"RemoteEnable" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.5.57 "RemoteDisable": 禁止 VPN 客户服务的远程管理

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + RemoteDisable
命令的概要 + 禁止 VPN 客户服务的远程管理
说明 + 对 VPN Client 服务,从本地主机以外的远程计算机上,禁止通过命令行管理设施或 VPN Client 管理器员进行连接和管理。
命令行格式 + RemoteDisable
"RemoteDisable" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.5.58 "KeepEnable": 启动 Internet 保持连接功能

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + KeepEnable
命令的概要 + 启动 Internet 保持连接功能
说明 + 启动 [互联网保持连接功能]。启动此功能后,如果一段时间没有通信数据,导致连接将被断开时,会自动发送数据包到任何服务器,互联网服务器一定的间隔,从而可以保持连接。
目标主机名等,可以通过 KeepSet 指令来设置。
VPN Server 或 VPN Bridge 运行此命令时,您必须具有管理员的权限。
命令行格式 + KeepEnable
"KeepEnable" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.5.59 "KeepDisable": 禁用保持互联网连接功能

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + KeepDisable
命令的概要 + 禁用保持互联网连接功能
说明 + 解除 [保持互联网连接功能]。
VPN Server 或 VPN Bridge 运行此命令,您必须具有管理员权限。
命令行格式 + KeepDisable
"KeepDisable" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.5.60 "KeepSet": 设置 Internet 保持连接功能

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + KeepSet
命令的概要 + 设置 Internet 保持连接功能
说明 + 设置 [保持互联网连接功能] 的目标主机名。 如果一段时间没有任何通信数据,连接将被断开时,使用 [保持互联网连接功能 ] 可以,设定时间向 Internet 上的任何服务器发送数据包,从而可以保持您的 Internet 连接。
在此功能中,可以设置目标 [主机名],[端口号],[数据包发送时间间隔],以及 [协议]。
发送的数据包为随机内容,不会讲计算机和个人的识别信息发送。
保持 Internet 连接功能,可以通过 KeepEnable 命令,或使用命令 KeepDisable,实现启用 / 禁用。不可以用 KeepSet 来改变启用 / 禁用的状态。
VPN Server 或 VPN Bridge 运行此命令,您必须具有管理员权限。
命令行格式 + KeepSet [/HOST:host:port] [/PROTOCOL:tcp|udp] [/INTERVAL:interval]
"KeepSet" 命令中可以指定的参数引数的一览:
/HOST + 用 [主机:端口] 的格式,来设定目标主机名或 IP 地址和端口号。
/PROTOCOL + 设定 tcp 或 udp。
/INTERVAL + 以秒为单位设定发送数据包之间的间隔时间。
+

 

+

6.5.61 "KeepGet": 获取保持互联网连接的功能

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + KeepGet
命令的概要 + 获取保持互联网连接的功能
说明 + 获取 [保持互联网连接功能] 的当前设置。可以得到 [主机名],[端口],[数据包发送时间间隔],和 [协议],还包括当前 [保持互联网连接功能] 是否启用的当前状态。
命令行格式 + KeepGet
"KeepGet" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.5.62 "MakeCert": 创建新的 X.509 证书和密钥

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + MakeCert
命令的概要 + 创建新的 X.509 证书和密钥
说明 + 创建新的 X.509 证书和密钥,将其保存为一个文件。
证书公共密钥和秘密密钥的生成算法使用 RSA 1024 位。
作为证书类型,可以创建由根证书 (自签名证书) 和其他证书签名的某个证书。要创建由其他证书签名的证书,需要与用于签名的证书 (X.509格式文件) 相对应的密钥文件 (Base 64 编码)。

创建的证书可以指定名称 (CN),所属机构 (O),组织单位 (OU),国家 (C),州 (ST),当地 (L),序列号,有效期限。
创建的证书以 X.509 格式的文件,密钥文件以 RSA 1024 位的 Base 64 编码文件,被分别保存。

MakeCert 指令是一个工具,它提供创建证书所需的最低功能。如果想创建一个真正的证书,建议使用 OpenSSL 等免费软件和出售的 CA (认证机构) 软件。

※注意: 此指令可以从 PacketiX VPN 命令行管理工具调用。虽然目前以管理模式连接到 VPN Server 和 VPN Client 时可以运行,但要实际运行 RSA 演算,生成证书数据的,是运行此指令的计算机,和以管理模式连接的链接目标计算机没有任何关系。
命令行格式 + MakeCert [/CN:cn] [/O:o] [/OU:ou] [/C:c] [/ST:st] [/L:l] [/SERIAL:serial] [/EXPIRES:expires] [/SIGNCERT:signcert] [/SIGNKEY:signkey] [/SAVECERT:savecert] [/SAVEKEY:savekey]
"MakeCert" 命令中可以指定的参数引数的一览:
/CN + 指定创建证书的名称 (CN) 项目。还可以指定 none。
/O + 指定创建证书的所属机构 (O) 项目。还可以指定 none。
/OU + 指定创建证书的组织单位 (OU) 项目。还可以指定 none。
/C + 指定创建证书的国家 (C) 项目。还可以指定 none。
/ST + 指定创建证书的州 (ST) 项目。还可以指定 none。
/L + 指定创建证书的当地 (L) 项目。还可以指定 none。
/SERIAL + 指定创建证书的序列号项目。以 16 进制指定。还可以指定 none。
/EXPIRES + 指定创建证书的有效期限。如果指定 none 或 0,将被使用 3650 天 (约 10 年)。最大可以指定 10950 天 (约 30 年)。
/SIGNCERT + 根据现有的证书对要创建的证书签名时,指定用来签名的 X.509 形式的证书文件名。如果省略参数,将作为根证书而创建没有签名的新证书。
/SIGNKEY + 指定与 /SIGNCERT 指定的证书相应的密钥 (RSA,Base 64 的编码)
/SAVECERT + 指定文件名以保存创建的证书。该证书以包含 RSA 形式的 1024 位公开密钥的 X.509 文件格式被保存。
/SAVEKEY + 指定文件名保存对应创建的证书的密钥。该密钥以 RSA 形式的 1024 位密钥文件被保存。
+

 

+

6.5.63 "TrafficClient": 在用户模式下,运行网络流量速度测试工具

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + TrafficClient
命令的概要 + 在用户模式下,运行网络流量速度测试工具
说明 + 运行通信吞吐量测量工具的客户端程序。
通信吞吐量测量工具,作为 TrafficClient 和 TrafficServer 两个指令使用,可以测量在 IP 网络上连接的 2 台计算机之间可传送的通信吞吐量。在另一台计算机上使用 TrafficServer 指令使通信吞吐量测量工具服务器处于待机状态,用 TrafficClient 指令指定并连接其服务器的主机名或 IP 地址和端口号,测量通信速度。
同时建立多个连接,计算各连接最大限度传送流数据的结果,及在指定时间内能够实际传送的数据的比特数,以此为依据计算通信吞吐量的平均值 (bps),用此方法进行通信速度的测量。通常,用一个 TCP 连接时,由于 TCP 算法的限制,大多数时候只能用比实际的网络吞吐量慢的速度通信。因此,建议测量同时建立多个 TCP 连接进行通信的结果。用此方法测量的吞吐量,以实际上作为 TCP 流到达接收方的数据的比特长度来计算,因此途中产生的数据包丢失和数据包损坏不包括在实际到达的数据包中,因而能够计算出纯粹的网络最大通信带宽的近似值。
用作为测量结构的,在 TCP 内被传输的 TCP 流的大小,来计算在网络上实际传输的数据量的近似值,将其除以时间,计算出比特每秒 (bps)。假定计算的物理网络类型为以太网 (IEEE802.3) ,MAC 帧有效载荷的大小是 1,500 比特 (TCP 的 MSS 是 1,460 比特)。如果指定 /RAW 选项,不会对 TCP/IP 头和 MAC 头的数据量进行更正计算。

※注意: 此指令可以从 PacketiX VPN 命令行管理工具调用。虽然目前以管理模式连接到 VPN Server 和 VPN Client 时可以运行,但要实际进行通信,测量吞吐量的,是运行此指令的计算机,与以管理模式连接的连接目标计算机没有任何关系。
命令行格式 + TrafficClient [host:port] [/NUMTCP:numtcp] [/TYPE:download|upload|full] [/SPAN:span] [/DOUBLE:yes|no] [/RAW:yes|no]
"TrafficClient" 命令中可以指定的参数引数的一览:
host:port + 指定通信吞吐量测量服务器 (TrafficServer) 待机时的主机名,或 IP 地址和端口号。如果省略端口号,9821 将被使用。
/NUMTCP + 指定同时在客户端和服务器进行数据传输的 TCP 连接数量。如果省略,32 将被使用。
/TYPE + 指定进行吞吐量测量时的数据传输流方向。指定下列选项之一: "download","upload" 或 "full"。指定 "download",则数据从服务器端向客户端传送。指定 "upload",则数据从客户端向服务器端传送。指定 "full",数据将双向传送。当指定 "full" 时,NUMTCP 的值必须指定是 2 以上的偶数 (同时被连接的 TCP 连接中一半用于下载的方向,而另一半用于上传的方向)。如果省略此参数,将使用 "full"。
/SPAN + 以秒为单位指定为测量吞吐量而进行数据传输时间。如果省略此参数,"15秒" 将被使用。
/DOUBLE + 指定 "yes" 时,测量结果的吞吐量将显示为 2 倍。在中途有网络设备等,测量其其网络设备的输入输出合计的吞吐量能力时,此选项被使用。
/RAW + 通过指定 "yes",不进行修正 TCP/IP 头和 MAC 头的数据量计算。
+

 

+

6.5.64 "TrafficServer": 在服务器模式下,运行网络流量速度测试工具

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + TrafficServer
命令的概要 + 在服务器模式下,运行网络流量速度测试工具
说明 + 运行通信吞吐量测量工具的服务器程序。
通信吞吐量测量工具,作为 TrafficClient 和 TrafficServer 两个指令使用,可以测量在 IP 网络上连接的 2 台计算机之间可传送的通信吞吐量。
要使此计算机上的 TCP 端口处于待机状态,等待从另一台计算机的 TrafficClient 连接,启动 TrafficServer 指令并指定端口号。
关于通信吞吐量测量工具的详细情况,输入 TrafficClient /? 将显示。

※注意: 此指令可以从 PacketiX VPN 命令行管理工具调用。虽然目前以管理模式连接 VPN Server 和 VPN Client 时可以运行,但要进行实际通信并测量吞吐量的,是运行此指令的计算机,与用管理模式连接终端的计算机没有任何关系。
命令行格式 + TrafficServer [port]
"TrafficServer" 命令中可以指定的参数引数的一览:
port + 以整数指定等待连接的端口号。被指定的端口,如果已经由另一个程序在使用,或不能打开该端口时,将发生错误。
+

 

+

6.5.65 "Check": 检测 PacketiX VPN 是否能正常运行

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + Check
命令的概要 + 检测 PacketiX VPN 是否能正常运行
说明 + 正在运行 vpncmd 的计算机上,正检测 PacketiX VPN Server / Bridge 的运行平台是否适合。
通过了这一检查的系统,PacketiX VPN 软件有较高的可能性进行正常运行。此外,无法通过此检查的系统,如果使用了 PacketiX VPN 软件可能会发生一些问题。
命令行格式 + Check
"Check" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+ + + + + + + + + + +------ 4 ------ + + + + + + + + + +

6.6.1 "About": 显示版本信息

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + About
命令的概要 + 显示版本信息
说明 + 这显示了此命令行管理工具的版本信息。版本信息中包括了 vpncmd 版本号,内部标号和内部标号信息。
命令行格式 + About
"About" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

+

6.6.2 "MakeCert": 创建新的 X.509 证书和密钥

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + MakeCert
命令的概要 + 创建新的 X.509 证书和密钥
说明 + 创建新的 X.509 证书和密钥,将其保存为一个文件。
证书公共密钥和秘密密钥的生成算法使用 RSA 1024 位。
作为证书类型,可以创建由根证书 (自签名证书) 和其他证书签名的某个证书。要创建由其他证书签名的证书,需要与用于签名的证书 (X.509格式文件) 相对应的密钥文件 (Base 64 编码)。

创建的证书可以指定名称 (CN),所属机构 (O),组织单位 (OU),国家 (C),州 (ST),当地 (L),序列号,有效期限。
创建的证书以 X.509 格式的文件,密钥文件以 RSA 1024 位的 Base 64 编码文件,被分别保存。

MakeCert 指令是一个工具,它提供创建证书所需的最低功能。如果想创建一个真正的证书,建议使用 OpenSSL 等免费软件和出售的 CA (认证机构) 软件。

※注意: 此指令可以从 PacketiX VPN 命令行管理工具调用。虽然目前以管理模式连接到 VPN Server 和 VPN Client 时可以运行,但要实际运行 RSA 演算,生成证书数据的,是运行此指令的计算机,和以管理模式连接的链接目标计算机没有任何关系。
命令行格式 + MakeCert [/CN:cn] [/O:o] [/OU:ou] [/C:c] [/ST:st] [/L:l] [/SERIAL:serial] [/EXPIRES:expires] [/SIGNCERT:signcert] [/SIGNKEY:signkey] [/SAVECERT:savecert] [/SAVEKEY:savekey]
"MakeCert" 命令中可以指定的参数引数的一览:
/CN + 指定创建证书的名称 (CN) 项目。还可以指定 none。
/O + 指定创建证书的所属机构 (O) 项目。还可以指定 none。
/OU + 指定创建证书的组织单位 (OU) 项目。还可以指定 none。
/C + 指定创建证书的国家 (C) 项目。还可以指定 none。
/ST + 指定创建证书的州 (ST) 项目。还可以指定 none。
/L + 指定创建证书的当地 (L) 项目。还可以指定 none。
/SERIAL + 指定创建证书的序列号项目。以 16 进制指定。还可以指定 none。
/EXPIRES + 指定创建证书的有效期限。如果指定 none 或 0,将被使用 3650 天 (约 10 年)。最大可以指定 10950 天 (约 30 年)。
/SIGNCERT + 根据现有的证书对要创建的证书签名时,指定用来签名的 X.509 形式的证书文件名。如果省略参数,将作为根证书而创建没有签名的新证书。
/SIGNKEY + 指定与 /SIGNCERT 指定的证书相应的密钥 (RSA,Base 64 的编码)
/SAVECERT + 指定文件名以保存创建的证书。该证书以包含 RSA 形式的 1024 位公开密钥的 X.509 文件格式被保存。
/SAVEKEY + 指定文件名保存对应创建的证书的密钥。该密钥以 RSA 形式的 1024 位密钥文件被保存。
+

 

+

6.6.3 "TrafficClient": 在用户模式下,运行网络流量速度测试工具

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + TrafficClient
命令的概要 + 在用户模式下,运行网络流量速度测试工具
说明 + 运行通信吞吐量测量工具的客户端程序。
通信吞吐量测量工具,作为 TrafficClient 和 TrafficServer 两个指令使用,可以测量在 IP 网络上连接的 2 台计算机之间可传送的通信吞吐量。在另一台计算机上使用 TrafficServer 指令使通信吞吐量测量工具服务器处于待机状态,用 TrafficClient 指令指定并连接其服务器的主机名或 IP 地址和端口号,测量通信速度。
同时建立多个连接,计算各连接最大限度传送流数据的结果,及在指定时间内能够实际传送的数据的比特数,以此为依据计算通信吞吐量的平均值 (bps),用此方法进行通信速度的测量。通常,用一个 TCP 连接时,由于 TCP 算法的限制,大多数时候只能用比实际的网络吞吐量慢的速度通信。因此,建议测量同时建立多个 TCP 连接进行通信的结果。用此方法测量的吞吐量,以实际上作为 TCP 流到达接收方的数据的比特长度来计算,因此途中产生的数据包丢失和数据包损坏不包括在实际到达的数据包中,因而能够计算出纯粹的网络最大通信带宽的近似值。
用作为测量结构的,在 TCP 内被传输的 TCP 流的大小,来计算在网络上实际传输的数据量的近似值,将其除以时间,计算出比特每秒 (bps)。假定计算的物理网络类型为以太网 (IEEE802.3) ,MAC 帧有效载荷的大小是 1,500 比特 (TCP 的 MSS 是 1,460 比特)。如果指定 /RAW 选项,不会对 TCP/IP 头和 MAC 头的数据量进行更正计算。

※注意: 此指令可以从 PacketiX VPN 命令行管理工具调用。虽然目前以管理模式连接到 VPN Server 和 VPN Client 时可以运行,但要实际进行通信,测量吞吐量的,是运行此指令的计算机,与以管理模式连接的连接目标计算机没有任何关系。
命令行格式 + TrafficClient [host:port] [/NUMTCP:numtcp] [/TYPE:download|upload|full] [/SPAN:span] [/DOUBLE:yes|no] [/RAW:yes|no]
"TrafficClient" 命令中可以指定的参数引数的一览:
host:port + 指定通信吞吐量测量服务器 (TrafficServer) 待机时的主机名,或 IP 地址和端口号。如果省略端口号,9821 将被使用。
/NUMTCP + 指定同时在客户端和服务器进行数据传输的 TCP 连接数量。如果省略,32 将被使用。
/TYPE + 指定进行吞吐量测量时的数据传输流方向。指定下列选项之一: "download","upload" 或 "full"。指定 "download",则数据从服务器端向客户端传送。指定 "upload",则数据从客户端向服务器端传送。指定 "full",数据将双向传送。当指定 "full" 时,NUMTCP 的值必须指定是 2 以上的偶数 (同时被连接的 TCP 连接中一半用于下载的方向,而另一半用于上传的方向)。如果省略此参数,将使用 "full"。
/SPAN + 以秒为单位指定为测量吞吐量而进行数据传输时间。如果省略此参数,"15秒" 将被使用。
/DOUBLE + 指定 "yes" 时,测量结果的吞吐量将显示为 2 倍。在中途有网络设备等,测量其其网络设备的输入输出合计的吞吐量能力时,此选项被使用。
/RAW + 通过指定 "yes",不进行修正 TCP/IP 头和 MAC 头的数据量计算。
+

 

+

6.6.4 "TrafficServer": 在服务器模式下,运行网络流量速度测试工具

+ + + + + + + + + + + + + + + + + + + + + + + + +
命令名 + TrafficServer
命令的概要 + 在服务器模式下,运行网络流量速度测试工具
说明 + 运行通信吞吐量测量工具的服务器程序。
通信吞吐量测量工具,作为 TrafficClient 和 TrafficServer 两个指令使用,可以测量在 IP 网络上连接的 2 台计算机之间可传送的通信吞吐量。
要使此计算机上的 TCP 端口处于待机状态,等待从另一台计算机的 TrafficClient 连接,启动 TrafficServer 指令并指定端口号。
关于通信吞吐量测量工具的详细情况,输入 TrafficClient /? 将显示。

※注意: 此指令可以从 PacketiX VPN 命令行管理工具调用。虽然目前以管理模式连接 VPN Server 和 VPN Client 时可以运行,但要进行实际通信并测量吞吐量的,是运行此指令的计算机,与用管理模式连接终端的计算机没有任何关系。
命令行格式 + TrafficServer [port]
"TrafficServer" 命令中可以指定的参数引数的一览:
port + 以整数指定等待连接的端口号。被指定的端口,如果已经由另一个程序在使用,或不能打开该端口时,将发生错误。
+

 

+

6.6.5 "Check": 检测 PacketiX VPN 是否能正常运行

+ + + + + + + + + + + + + + + + + + + + + + + +
命令名 + Check
命令的概要 + 检测 PacketiX VPN 是否能正常运行
说明 + 正在运行 vpncmd 的计算机上,正检测 PacketiX VPN Server / Bridge 的运行平台是否适合。
通过了这一检查的系统,PacketiX VPN 软件有较高的可能性进行正常运行。此外,无法通过此检查的系统,如果使用了 PacketiX VPN 软件可能会发生一些问题。
命令行格式 + Check
"Check" 命令中可以指定的参数引数的一览:
这个命令中没有任何应该指定的参数。
+

 

diff --git a/src/Ham/generated_manual_ja.html b/src/Ham/generated_manual_ja.html new file mode 100644 index 00000000..2c456a28 --- /dev/null +++ b/src/Ham/generated_manual_ja.html @@ -0,0 +1,9862 @@ + + + + + + + + + + +------ 1 ------ + + + + + + + + + +

6.3.1 "About": バージョン情報の表示

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + About
コマンドの概要 + バージョン情報の表示
説明 + このコマンドライン管理ユーティリティのバージョン情報を表示します。バージョン情報には、vpncmd のバージョン番号、ビルド番号、ビルド情報などが含まれます。
コマンドライン書式 + About
"About" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.2 "ServerInfoGet": サーバー情報の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ServerInfoGet
コマンドの概要 + サーバー情報の取得
説明 + 現在接続している VPN Server または VPN Bridge のサーバー情報を取得します。サーバーの情報には、バージョン番号、ビルド番号、ビルド情報などが含まれます。また、現在のサーバーの動作モードや動作しているオペレーティングシステムの情報なども取得できます。
コマンドライン書式 + ServerInfoGet
"ServerInfoGet" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.3 "ServerStatusGet": サーバーの現在の状態の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ServerStatusGet
コマンドの概要 + サーバーの現在の状態の取得
説明 + 現在接続している VPN Server または VPN Bridge の現在の状態をリアルタイムに取得します。サーバー上に存在する各種オブジェクトの個数や、データ通信の統計情報などを取得できます。また、OS によっては現在コンピュータで使用されているメモリ量などを取得することもできます。
コマンドライン書式 + ServerStatusGet
"ServerStatusGet" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.4 "ListenerCreate": TCP リスナーの追加

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ListenerCreate
コマンドの概要 + TCP リスナーの追加
説明 + サーバーに新しい TCP リスナーを追加します。TCP リスナーを追加すると、サーバーは指定した TCP/IP ポート番号でクライアントからの接続の待機を開始します。
一度追加した TCP リスナーは、ListenerDelete コマンドで削除することができます。
なお、現在の登録されている TCP リスナーの一覧は、ListenerList コマンドで取得することができます。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
コマンドライン書式 + ListenerCreate [port]
"ListenerCreate" コマンドで指定することができるパラメータ引数の一覧:
port + 新しく追加する TCP/IP リスナーのポート番号を整数で指定します。すでに別のプログラムが使用しているポート番号を使用することもできますが、そのプログラムがポートの使用を終了するまで、VPN Server はそのポートを使用できません。ポート番号は 1 以上 65535 以下で指定してください。
+

 

+

6.3.5 "ListenerDelete": TCP リスナーの削除

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ListenerDelete
コマンドの概要 + TCP リスナーの削除
説明 + サーバーに登録されている TCP リスナーを削除します。TCP リスナーが動作状態にある場合は、自動的に動作を停止してからリスナーが削除されます。
なお、現在の登録されている TCP リスナーの一覧は、ListenerList コマンドで取得することができます。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
コマンドライン書式 + ListenerDelete [port]
"ListenerDelete" コマンドで指定することができるパラメータ引数の一覧:
port + 削除したい TCP/IP リスナーのポート番号を、整数で指定します。
+

 

+

6.3.6 "ListenerList": TCP リスナー一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ListenerList
コマンドの概要 + TCP リスナー一覧の取得
説明 + 現在サーバーに登録されている TCP リスナーの一覧を取得します。各 TCP リスナーが動作中、またはエラー状態であるかどうかの情報も取得します。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
コマンドライン書式 + ListenerList
"ListenerList" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.7 "ListenerEnable": TCP リスナーの動作開始

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ListenerEnable
コマンドの概要 + TCP リスナーの動作開始
説明 + 現在サーバーに登録されている TCP リスナーが停止している場合は、その動作を開始します。
なお、現在の登録されている TCP リスナーの一覧は、ListenerList コマンドで取得することができます。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
コマンドライン書式 + ListenerEnable [port]
"ListenerEnable" コマンドで指定することができるパラメータ引数の一覧:
port + 開始する TCP/IP リスナーのポート番号を、整数で指定します。
+

 

+

6.3.8 "ListenerDisable": TCP リスナーの動作停止

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ListenerDisable
コマンドの概要 + TCP リスナーの動作停止
説明 + 現在サーバーに登録されている TCP リスナーが動作している場合は、その動作を停止します。
なお、現在の登録されている TCP リスナーの一覧は、ListenerList コマンドで取得することができます。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
コマンドライン書式 + ListenerDisable [port]
"ListenerDisable" コマンドで指定することができるパラメータ引数の一覧:
port + 停止する TCP/IP リスナーのポート番号を、整数で指定します。
+

 

+

6.3.9 "ServerPasswordSet": VPN Server の管理者パスワードの設定

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ServerPasswordSet
コマンドの概要 + VPN Server の管理者パスワードの設定
説明 + VPN Server の管理者パスワードを設定します。パラメータとしてパスワードを指定することができます。パラメータを指定しない場合は、パスワードと、その確認入力を行なうためのプロンプトが表示されます。パスワードをパラメータに与えた場合、そのパスワードが一時的に画面に表示されるため危険です。できる限り、パラメータを指定せずに、パスワードプロンプトを用いてパスワードを入力することを推奨します。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
コマンドライン書式 + ServerPasswordSet [password]
"ServerPasswordSet" コマンドで指定することができるパラメータ引数の一覧:
password + 新しく設定するパスワードを指定します。
+

 

+

6.3.10 "ClusterSettingGet": 現在の VPN Server のクラスタリング構成の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ClusterSettingGet
コマンドの概要 + 現在の VPN Server のクラスタリング構成の取得
説明 + 現在の VPN Server のクラスタリング構成を取得します。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
コマンドライン書式 + ClusterSettingGet
"ClusterSettingGet" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.11 "ClusterSettingStandalone": VPN Server の種類をスタンドアロンに設定

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ClusterSettingStandalone
コマンドの概要 + VPN Server の種類をスタンドアロンに設定
説明 + VPN Server の種類を、「スタンドアロンサーバー」に設定します。スタンドアロンサーバーとは、いずれのクラスタにも属していない状態の VPN Server を意味します。VPN Server をインストールした状態ではデフォルトでスタンドアロンサーバーモードになります。特にクラスタを構成する予定がない場合は、スタンドアロンサーバーモードで動作させることを推奨します。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
また、このコマンドを実行すると、VPN Server は自動的に再起動します。
このコマンドは、VPN Bridge では実行できません。
コマンドライン書式 + ClusterSettingStandalone
"ClusterSettingStandalone" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.12 "ClusterSettingController": VPN Server の種類をクラスタコントローラに設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ClusterSettingController
コマンドの概要 + VPN Server の種類をクラスタコントローラに設定
説明 + VPN Server の種類を、「クラスタコントローラ」に設定します。クラスタコントローラとは、複数台の VPN Server でクラスタリングを構築する場合における、各クラスタメンバサーバーの中心となるコンピュータで、クラスタ内に 1 台必要です。同一クラスタを構成する他のクラスタメンバサーバーは、クラスタコントローラに接続することによりクラスタメンバとしての動作を開始します。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
また、このコマンドを実行すると、VPN Server は自動的に再起動します。
このコマンドは、VPN Bridge では実行できません。
コマンドライン書式 + ClusterSettingController [/WEIGHT:weight] [/ONLY:yes|no]
"ClusterSettingController" コマンドで指定することができるパラメータ引数の一覧:
/WEIGHT + この VPN Server の性能基準比の値を設定します。クラスタ内でロードバランシングを行う際に基準となる値です。通常は 100 です。たとえば、他のメンバが 100 の状態で、1 台だけ 200 にすると、他のメンバの 2 倍接続を受け持つようにロードバランシング時に調整されます。値は 1 以上で指定します。このパラメータを指定しない場合は、100 が使用されます。
/ONLY + "yes" を指定すると、VPN Server がクラスタ内でコントローラとしての機能のみを動作させ、一般の VPN Client の接続は、自分自身以外のメンバに必ず振り分けるようになります。この機能は、負荷が高い環境で使用します。このパラメータを指定しない場合は、"no" が使用されます。
+

 

+

6.3.13 "ClusterSettingMember": VPN Server の種類をクラスタメンバに設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ClusterSettingMember
コマンドの概要 + VPN Server の種類をクラスタメンバに設定
説明 + VPN Server の種類を、「クラスタメンバサーバー」に設定します。クラスタメンバサーバーとは、複数台の VPN Server でクラスタリングを構築する場合における、特定の既存のクラスタコントローラが中心となって構成されるクラスタに属する他のメンバコンピュータで、クラスタに必要なだけ複数追加することができます。
クラスタメンバサーバーとして VPN Server を設定するには、事前に参加する予定のクラスタのコントローラの管理者に、コントローラの IP アドレスとポート番号、この VPN Server の公開 IP アドレスおよび公開ポート番号 (必要な場合)、およびパスワードを問い合わせる必要があります。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
また、このコマンドを実行すると、VPN Server は自動的に再起動します。
このコマンドは、VPN Bridge では実行できません。
コマンドライン書式 + ClusterSettingMember [server:port] [/IP:ip] [/PORTS:ports] [/PASSWORD:password] [/WEIGHT:weight]
"ClusterSettingMember" コマンドで指定することができるパラメータ引数の一覧:
server:port + [ホスト名:ポート番号] の形式のパラメータで、接続先のクラスタコントローラのホスト名、または IP アドレス、およびポート番号を指定します。
/IP + このサーバーの公開 IP アドレスを指定します。公開 IP アドレスを指定しない場合、"/IP:none" のように指定してください。公開 IP アドレスを指定しなければ、クラスタコントローラへの接続の際に使用されるネットワークインターフェイスの IP アドレスが自動的に使われます。
/PORTS + このサーバーの公開ポート番号の一覧を指定します。公開ポート番号は、少なくとも 1 つ以上設定する必要があり、複数個設定することも可能です。その場合は、"/PORTS:443,992,8888" のようにカンマ記号で区切ってください。
/PASSWORD + 接続先のコントローラに接続するためのパスワードを指定します。接続先のコントローラの管理パスワードと同一です。
/WEIGHT + この VPN Server の性能基準比の値を設定します。クラスタ内で、ロードバランシングを行う際の基準となる値です。たとえば、他のメンバが 100 の状態で、1 台だけ 200 にすると、他のメンバの 2 倍の接続を受け持つように調整されます。値は 1 以上で指定します。このパラメータを指定しない場合は、100 が使用されます。
+

 

+

6.3.14 "ClusterMemberList": クラスタメンバの一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ClusterMemberList
コマンドの概要 + クラスタメンバの一覧の取得
説明 + VPN Server がクラスタコントローラとして動作している場合、そのクラスタ内のクラスタメンバサーバーの一覧を、クラスタコントローラ自身を含めて取得します。
各メンバ毎に、[種類]、[接続時刻]、[ホスト名]、[ポイント]、[セッション数]、[TCP コネクション数]、[動作仮想 HUB 数]、[消費クライアント接続ライセンス]、[消費ブリッジ接続ライセンス] の一覧も取得します。
このコマンドは、VPN Bridge では実行できません。
コマンドライン書式 + ClusterMemberList
"ClusterMemberList" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.15 "ClusterMemberInfoGet": クラスタメンバの情報の取得

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ClusterMemberInfoGet
コマンドの概要 + クラスタメンバの情報の取得
説明 + VPN Server がクラスタコントローラとして動作している場合、そのクラスタ内のクラスタメンバサーバーの ID を指定して、そのメンバサーバーの情報を取得することができます。
指定されたクラスタメンバサーバーの [サーバーの種類]、[接続確立時刻]、[IP アドレス]、[ホスト名]、[ポイント]、[公開ポートの一覧]、[動作している仮想 HUB 数]、[1 個目の仮想 HUB]、[セッション数]、[TCP コネクション数] が取得できます。
このコマンドは、VPN Bridge では実行できません。
コマンドライン書式 + ClusterMemberInfoGet [id]
"ClusterMemberInfoGet" コマンドで指定することができるパラメータ引数の一覧:
id + 情報を取得するクラスタメンバの ID を指定します。クラスタメンバサーバーの ID は、ClusterMemberList コマンドで取得することができます。
+

 

+

6.3.16 "ClusterMemberCertGet": クラスタメンバの証明書の取得

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ClusterMemberCertGet
コマンドの概要 + クラスタメンバの証明書の取得
説明 + VPN Server がクラスタコントローラとして動作している場合、そのクラスタ内のクラスタメンバサーバーの ID を指定して、そのメンバサーバーの公開している X.509 証明書を取得することができます。証明書は、X.509 形式のファイルに保存することができます。
このコマンドは、VPN Bridge では実行できません。
コマンドライン書式 + ClusterMemberCertGet [id] [/SAVECERT:cert]
"ClusterMemberCertGet" コマンドで指定することができるパラメータ引数の一覧:
id + 証明書を取得するクラスタメンバの ID を指定します。クラスタメンバサーバーの ID は、ClusterMemberList コマンドで取得することができます。
/SAVECERT + 取得した証明書を保存するファイルのパス名を指定します。証明書は X.509 形式で保存されます。
+

 

+

6.3.17 "ClusterConnectionStatusGet": クラスタコントローラへの接続状態の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ClusterConnectionStatusGet
コマンドの概要 + クラスタコントローラへの接続状態の取得
説明 + VPN Server がクラスタメンバサーバーとして動作している場合、クラスタコントローラへの接続状態を取得します。
取得できる情報には、[コントローラの IP アドレス]、[ポート番号]、[接続状態]、[接続開始時刻]、[最初の接続確立成功時刻]、[現在の接続成功確立時刻]、[接続試行回数]、[接続に成功した回数]、[接続に失敗した回数] があります。
このコマンドは、VPN Bridge では実行できません。
コマンドライン書式 + ClusterConnectionStatusGet
"ClusterConnectionStatusGet" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.18 "ServerCertGet": VPN Server の SSL 証明書の取得

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ServerCertGet
コマンドの概要 + VPN Server の SSL 証明書の取得
説明 + VPN Server が、接続したクライアントに対して提示する SSL 証明書を取得します。証明書は、X.509 形式のファイルに保存することができます。
コマンドライン書式 + ServerCertGet [cert]
"ServerCertGet" コマンドで指定することができるパラメータ引数の一覧:
cert + 取得した証明書を保存するファイルのパス名を指定します。証明書は X.509 形式で保存されます。
+

 

+

6.3.19 "ServerKeyGet": VPN Server の SSL 証明書の秘密鍵の取得

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ServerKeyGet
コマンドの概要 + VPN Server の SSL 証明書の秘密鍵の取得
説明 + VPN Server が接続したクライアントに対して提示する SSL 証明書の秘密鍵を取得します。秘密鍵は、Base 64 でエンコードされたファイルに保存することができます。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
コマンドライン書式 + ServerKeyGet [key]
"ServerKeyGet" コマンドで指定することができるパラメータ引数の一覧:
key + 取得した秘密鍵を保存するファイルのパス名を指定します。秘密鍵は Base 64 エンコードされて保存されます。
+

 

+

6.3.20 "ServerCertSet": VPN Server の SSL 証明書と秘密鍵の設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ServerCertSet
コマンドの概要 + VPN Server の SSL 証明書と秘密鍵の設定
説明 + VPN Server が接続したクライアントに対して提示する SSL 証明書と、その証明書に対応する秘密鍵を設定します。証明書は X.509 形式、秘密鍵は Base 64 エンコードされた形式である必要があります。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
コマンドライン書式 + ServerCertSet [/LOADCERT:cert] [/LOADKEY:key]
"ServerCertSet" コマンドで指定することができるパラメータ引数の一覧:
/LOADCERT + 使用する X.509 形式の証明書ファイルを指定します。
/LOADKEY + 使用する Base 64 エンコードされた、証明書に対応する秘密鍵ファイルを指定します。
+

 

+

6.3.21 "ServerCipherGet": VPN 通信で使用される暗号化アルゴリズムの取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ServerCipherGet
コマンドの概要 + VPN 通信で使用される暗号化アルゴリズムの取得
説明 + VPN Server と、接続したクライアントとの間で通信に使用する SSL コネクションにおける暗号化、および電子署名に用いられるアルゴリズムの現在の設定と、VPN Server 上で使用可能なアルゴリズムの一覧を取得します。
コマンドライン書式 + ServerCipherGet
"ServerCipherGet" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.22 "ServerCipherSet": VPN 通信で使用される暗号化アルゴリズムの設定

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ServerCipherSet
コマンドの概要 + VPN 通信で使用される暗号化アルゴリズムの設定
説明 + VPN Server と、接続したクライアントとの間で通信に使用する SSL コネクションにおける暗号化、および電子署名に用いられるアルゴリズムを設定します。
アルゴリズム名を指定すると、以後この VPN Server に接続した VPN Client や、VPN Bridge との間で、指定したアルゴリズムが使用され、データが暗号化されます。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
コマンドライン書式 + ServerCipherSet [name]
"ServerCipherSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定するる暗号化および電子署名アルゴリズムを指定します。使用可能なアルゴリズムの一覧は、ServerCipherGet コマンドで取得することができます。
+

 

+

6.3.23 "Debug": デバッグコマンドの実行

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + Debug
コマンドの概要 + デバッグコマンドの実行
説明 + VPN Server / Bridge の実行中のプロセスでデバッグコマンドを実行します。
このコマンドは、ソフトイーサ株式会社からのサポートの指示があった場合のみ使用してください。
むやみにこのコマンドを使用すると、動作中の VPN Server / Bridge が停止する原因になります。
コマンドライン書式 + Debug [id] [/ARG:arg]
"Debug" コマンドで指定することができるパラメータ引数の一覧:
id + デバッグコマンド番号を整数で指定します。
/ARG + デバッグコマンドに渡す文字列を指定します。スペースを含む場合は、" " で囲んでください。
+

 

+

6.3.24 "Crash": VPN Server / Bridge プロセスでエラーを発生させプロセスを強制終了する

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + Crash
コマンドの概要 + VPN Server / Bridge プロセスでエラーを発生させプロセスを強制終了する
説明 + VPN Server / Bridge の実行中のプロセスで致命的なエラー (メモリ保護違反など) を発生させ、プロセスをクラッシュさせます。その結果、VPN Server / Bridge がサービスモードで起動している場合は、自動的にプロセスが再起動します。VPN Server がユーザーモードで起動している場合は、プロセスは自動的に再起動しません。
このコマンドは、VPN Server / Bridge で何らかの回復不能なエラーが発生したり、プロセスが暴走したりしているときに、すぐにプロセスを再起動しなければならないような場合に利用してください。このコマンドを実行すると、現在 VPN Server / Bridge に接続されているすべての VPN セッションは切断されます。また、VPN Server がメモリ内に保有している未保存のデータはすべて失われます。
このコマンドを実行する前に、Flush コマンドを実行してVPN Server / Bridge の未保存の設定データを設定ファイルに強制保存することをお勧めします。
このコマンドは、VPN Server / Bridge 全体の管理者のみが実行できます。
コマンドライン書式 + Crash [yes]
"Crash" コマンドで指定することができるパラメータ引数の一覧:
yes + 確認のため、"yes" と指定してください。
+

 

+

6.3.25 "Flush": VPN Server / Bridge の未保存の設定データを設定ファイルに強制保存する

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + Flush
コマンドの概要 + VPN Server / Bridge の未保存の設定データを設定ファイルに強制保存する
説明 + 通常、VPN Server / Bridge は設定内容をメモリ内に保持し、vpn_server.config または vpn_bridge.config ファイルに定期的に保存します。これらの設定ファイルへの保存処理は、通常、300 秒 (5 分) ごとに自動的に行われます (この間隔は、設定ファイルの AutoSaveConfigSpan 項目を編集することで変更できます)。なお、VPN Server / Bridge サービスが正常終了しようとする際にもこれらの設定ファイルは自動的に保存されます。
Flush コマンドを実行すると、VPN Server / Bridge は、すぐに設定ファイルへの保存処理を実施します。これにより、現在の最新の設定データが必ずサーバーコンピュータのディスクドライブにフラッシュされます。たとえば、やむを得ずサービスプロセスを正常終了する時間的余裕がない場合は、Flush コマンドを用いてデータを強制保存してから、サービスプロセスやサーバーコンピュータを強制シャットダウンしてください。
このコマンドは、VPN Server / Bridge 全体の管理者のみが実行できます。
コマンドライン書式 + Flush
"Flush" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.26 "KeepEnable": インターネット接続の維持機能の有効化

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + KeepEnable
コマンドの概要 + インターネット接続の維持機能の有効化
説明 + [インターネット接続の維持機能] を有効にします。[インターネット接続の維持機能] を使用すると、一定期間無通信状態が続くと、自動的に接続が切断されるようなネットワーク接続環境の場合、インターネット上の任意のサーバーに対して一定間隔ごとにパケットを送信することにより、インターネット接続を維持することができます。
接続先のホスト名などについては、KeepSet コマンドで設定することができます。
VPN Server または VPN Bridge で、このコマンドを実行するには、管理者権限が必要です。
コマンドライン書式 + KeepEnable
"KeepEnable" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.27 "KeepDisable": インターネット接続の維持機能の無効化

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + KeepDisable
コマンドの概要 + インターネット接続の維持機能の無効化
説明 + [インターネット接続の維持機能] を無効にします。
VPN Server または VPN Bridge で、このコマンドを実行するには、管理者権限が必要です。
コマンドライン書式 + KeepDisable
"KeepDisable" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.28 "KeepSet": インターネット接続の維持機能の設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + KeepSet
コマンドの概要 + インターネット接続の維持機能の設定
説明 + [インターネット接続の維持機能] の接続先ホスト名などの設定を行ないます。一定期間無通信状態が続くと自動的に接続が切断されるようなネットワーク接続環境で、[インターネット接続の維持機能] を使用すると、インターネット上の任意のサーバーに対して、一定間隔ごとにパケットを送信することにより、インターネット接続を維持することができます。
このコマンドでは、通信先の [ホスト名]、[ポート番号]、[パケット送出間隔]、および [プロトコル] を指定することができます。
インターネット接続維持のために送信されるパケットは、ランダムな内容であり、コンピュータやユーザーを識別する個人情報などが送信されることはありません。
インターネット接続の維持機能は、KeepEnable コマンド、または KeepDisable コマンドを用いて、有効化 / 無効化することができます。KeepSet は有効 / 無効の状態を変更しません。
VPN Server または VPN Bridge で、このコマンドを実行するには、管理者権限が必要です。
コマンドライン書式 + KeepSet [/HOST:host:port] [/PROTOCOL:tcp|udp] [/INTERVAL:interval]
"KeepSet" コマンドで指定することができるパラメータ引数の一覧:
/HOST + [ホスト名:ポート番号] の形式で、通信先のホスト名、または IP アドレスとポート番号を指定します。
/PROTOCOL + tcp または udp を指定します。
/INTERVAL + パケットを送出する間隔を秒単位で指定します。
+

 

+

6.3.29 "KeepGet": インターネット接続の維持機能の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + KeepGet
コマンドの概要 + インターネット接続の維持機能の取得
説明 + [インターネット接続の維持機能] の、現在の設定内容を取得します。通信先の [ホスト名]、[ポート番号]、[パケット送出間隔]、および [プロトコル] に加えて、現在の [インターネット接続の維持機能] の有効状態が取得できます。
コマンドライン書式 + KeepGet
"KeepGet" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.30 "SyslogEnable": syslog 送信機能の設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + SyslogEnable
コマンドの概要 + syslog 送信機能の設定
説明 + syslog 送信機能の使用方法と使用する syslog サーバーを設定します。
コマンドライン書式 + SyslogEnable [1|2|3] [/HOST:host:port]
"SyslogEnable" コマンドで指定することができるパラメータ引数の一覧:
1|2|3 + syslog 送信機能使用設定を 1 ~ 3 のいずれかの整数で指定します。 +1: サーバーログを syslog で送信。 +2: サーバーおよび仮想 HUB セキュリティログを syslog で送信。 +3: サーバー、仮想 HUB セキュリティおよびパケットログを syslog で送信。
/HOST + [ホスト名:ポート番号] の形式で、syslog サーバーのホスト名、または IP アドレスとポート番号を指定します。ポート番号を省略すると 514 を使用します。
+

 

+

6.3.31 "SyslogDisable": syslog 送信機能の無効化

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + SyslogDisable
コマンドの概要 + syslog 送信機能の無効化
説明 + syslog 送信機能を使用しないようにします。
コマンドライン書式 + SyslogDisable
"SyslogDisable" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.32 "SyslogGet": syslog 送信機能の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + SyslogGet
コマンドの概要 + syslog 送信機能の取得
説明 + syslog 送信機能の現在の設定内容を取得します。syslog 機能の使用方法の設定、および使用する syslog サーバーのホスト名とポート番号が取得できます。
コマンドライン書式 + SyslogGet
"SyslogGet" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.33 "ConnectionList": VPN Server に接続中の TCP コネクション一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ConnectionList
コマンドの概要 + VPN Server に接続中の TCP コネクション一覧の取得
説明 + 現在、VPN Server に接続中の TCP/IP コネクションの一覧を取得します。ただし、VPN セッションとして確立された TCP/IP コネクションは表示されません。VPN セッションとして確立された TCP/IP コネクションの一覧は、SessionList コマンドを用いて取得できます。
[コネクション名]、[接続元]、[接続時刻] および [種類] を取得することができます。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
コマンドライン書式 + ConnectionList
"ConnectionList" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.34 "ConnectionGet": VPN Server に接続中の TCP コネクションの情報の取得

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ConnectionGet
コマンドの概要 + VPN Server に接続中の TCP コネクションの情報の取得
説明 + VPN Server に接続中の指定された TCP/IP コネクションに関する詳細な情報を取得します。
[コネクション名]、[コネクションの種類]、[接続元ホスト名]、[接続元 IP アドレス]、[接続元ポート番号 (TCP)]、[接続時刻]、[サーバー製品名]、[サーバー バージョン]、[サーバー ビルド番号]、[クライアント製品名]、[クライアントバージョン]、[クライアントビルド番号] が取得できます。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
コマンドライン書式 + ConnectionGet [name]
"ConnectionGet" コマンドで指定することができるパラメータ引数の一覧:
name + 情報を取得するコネクション名を指定します。コネクション名の一覧は、ConnectionList コマンドで取得できます。
+

 

+

6.3.35 "ConnectionDisconnect": VPN Server に接続中の TCP コネクションの切断

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ConnectionDisconnect
コマンドの概要 + VPN Server に接続中の TCP コネクションの切断
説明 + VPN Server に接続中の指定された TCP/IP コネクションを強制的に切断します。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
コマンドライン書式 + ConnectionDisconnect [name]
"ConnectionDisconnect" コマンドで指定することができるパラメータ引数の一覧:
name + 切断するコネクション名を指定します。コネクション名の一覧は ConnectionList コマンドで取得できます。
+

 

+

6.3.36 "BridgeDeviceList": ローカルブリッジに使用できる LAN カード一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + BridgeDeviceList
コマンドの概要 + ローカルブリッジに使用できる LAN カード一覧の取得
説明 + ローカルブリッジ接続で、ブリッジ先のデバイスとして使用できる Ethernet デバイス (LAN カード) の一覧を取得します。
ここで表示されるデバイス名は、BridgeCreate コマンドで使用することができます。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
コマンドライン書式 + BridgeDeviceList
"BridgeDeviceList" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.37 "BridgeList": ローカルブリッジ接続の一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + BridgeList
コマンドの概要 + ローカルブリッジ接続の一覧の取得
説明 + 現在定義されているローカルブリッジ接続の一覧を取得します。
ローカルブリッジ接続の仮想 HUB 名と、ブリッジ先の Ethernet デバイス (LAN カード) 名、または tap デバイス名および動作状況が取得できます。
コマンドライン書式 + BridgeList
"BridgeList" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.38 "BridgeCreate": ローカルブリッジ接続の作成

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + BridgeCreate
コマンドの概要 + ローカルブリッジ接続の作成
説明 + 新しいローカルブリッジ接続を VPN Server 上に作成します。
ローカルブリッジを使用すると、この VPN Server 上で動作する仮想 HUB と、物理的な Ethernet デバイス (LAN カード) との間でレイヤ 2 ブリッジ接続を構成することができます。
システムに tap デバイス (仮想のネットワークインターフェイス) を作成し、仮想 HUB との間でブリッジ接続することもできます (tap デバイスは Linux 版のみサポートされています)。
ブリッジ先の Ethernet デバイス (LAN カード) には、稼働中の任意の LAN カードとの間でブリッジできますが、高負荷環境においてはブリッジ専用に LAN カードを用意することをお勧めします。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
コマンドライン書式 + BridgeCreate [hubname] [/DEVICE:device_name] [/TAP:yes|no]
"BridgeCreate" コマンドで指定することができるパラメータ引数の一覧:
hubname + ブリッジする仮想 HUB を指定します。仮想 HUB の一覧は、HubList コマンドで取得できます。ただし、必ずしも現在動作している仮想 HUB 名を指定する必要はありません。現在動作していない、または存在しない仮想 HUB 名を指定すると、その仮想 HUB が実際に動作を開始した際にローカルブリッジ接続が有効になります。
/DEVICE + ブリッジ先の Ethernet デバイス (LAN カード) 名、または tap デバイス名を指定します。Ethernet デバイス名の一覧は、BridgeDeviceList コマンドで取得することができます。
/TAP + ブリッジ先として LAN カードではなく、tap デバイスを使用する場合は yes を指定します (Linux 版のみサポートされます)。省略した場合は no と見なされます。
+

 

+

6.3.39 "BridgeDelete": ローカルブリッジ接続の削除

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + BridgeDelete
コマンドの概要 + ローカルブリッジ接続の削除
説明 + 既存のローカルブリッジ接続を削除します。現在のローカルブリッジ接続の一覧は、BridgeDeviceList コマンドで取得できます。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
コマンドライン書式 + BridgeDelete [hubname] [/DEVICE:device_name]
"BridgeDelete" コマンドで指定することができるパラメータ引数の一覧:
hubname + 削除するローカルブリッジの、仮想 HUB を指定します。
/DEVICE + 削除するローカルブリッジの、デバイス名 (LAN カード名または tap デバイス名) を指定します。
+

 

+

6.3.40 "Caps": サーバーの機能・能力一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + Caps
コマンドの概要 + サーバーの機能・能力一覧の取得
説明 + 現在接続して管理している VPN Server の持つ機能と能力の一覧を取得します。
VPN Server の機能や能力は、動作している VPN Server のエディションやバージョンによって異なります。コマンドライン管理ユーティリティにあるコマンドでも、接続先の VPN Server の機能や能力によっては動作しない場合があります。このコマンドは、接続先の VPN Server の能力を調査して報告します。
VPN Server のバージョンの方がコマンドライン管理ユーティリティよりも新しく、コマンドライン管理ユーティリティが把握していない機能がある場合は、その内部文字列 (変数名) が、そのまま表示されることがあります。
コマンドライン書式 + Caps
"Caps" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.41 "Reboot": VPN Server サービスの再起動

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + Reboot
コマンドの概要 + VPN Server サービスの再起動
説明 + VPN Server サービスを再起動します。
VPN Server を再起動すると、現在接続しているセッションや TCP コネクションはすべて切断され、再起動が完了するまで新たな接続は受け付けなくなります。
このコマンドでは、VPN Server サービスプログラムのみが再起動され、VPN Server が動作している物理的なコンピュータが再起動することはありません。この管理セッションも切断されるため、管理を続行するには再接続してください。
また、/RESETCONFIG:yes パラメータを指定すると、現在の VPN Server が持っているコンフィグレーションファイル (.config) の内容を初期化します。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
コマンドライン書式 + Reboot [/RESETCONFIG:yes|no]
"Reboot" コマンドで指定することができるパラメータ引数の一覧:
/RESETCONFIG + yes を指定すると、現在の VPN Server が持っているコンフィグレーションファイル (.config) の内容を初期化します。このパラメータは慎重に設定してください。
+

 

+

6.3.42 "ConfigGet": VPN Server の現在のコンフィグレーションの取得

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ConfigGet
コマンドの概要 + VPN Server の現在のコンフィグレーションの取得
説明 + VPN Server の、現在のコンフィグレーションの内容を構造化したテキストファイル (.config ファイル) として取得します。このコマンドを実行した瞬間の VPN Server 内の状態が取得できます。
コンフィグレーションファイルの内容は、パラメータを指定しない場合は、画面上にそのまま表示されます。パラメータで保存するファイル名を指定すると、そのファイル名で内容が保存されます。
コンフィグレーションファイルは、通常のテキストエディタ等で編集可能です。編集したコンフィグレーションを VPN Server に書き込むには、ConfigSet コマンドを使用します。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
コマンドライン書式 + ConfigGet [path]
"ConfigGet" コマンドで指定することができるパラメータ引数の一覧:
path + コンフィグレーションファイルの内容をファイルに保存したい場合は、そのファイル名を指定します。何も指定しない場合は、コンフィグレーションの内容は画面に表示されます。コンフィグレーションファイルにマルチバイト文字が含まれる場合は、Unicode (UTF-8) でエンコードされて保存されます。
+

 

+

6.3.43 "ConfigSet": VPN Server へのコンフィグレーションの書き込み

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ConfigSet
コマンドの概要 + VPN Server へのコンフィグレーションの書き込み
説明 + VPN Server にコンフィグレーションを書き込みます。このコマンドを実行すると、指定したコンフィグレーションファイルの内容が VPN Server に適用され、VPN Server プログラムは自動的に再起動され、新しいコンフィグレーションの内容に従って動作を開始します。
コンフィグレーションファイルは、すべての内容を管理者が記述するのは困難であるため、ConfigGet コマンドで、まず現在の VPN Server のコンフィグレーションの内容を取得してファイルに保存し、その内容を通常のテキストエディタなどで編集したものを ConfigSet コマンドで VPN Server に書き戻すことを推奨します。
このコマンドは、VPN Server に関する詳しい知識をお持ちの方のためのコマンドであり、不正なコンフィグレーションファイルを書き込んだ場合は、エラーが発生したり現在の設定内容が失われたりする可能性がありますので、十分注意してください。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
コマンドライン書式 + ConfigSet [path]
"ConfigSet" コマンドで指定することができるパラメータ引数の一覧:
path + 書き込むコンフィグレーションファイルのファイル名を指定します。書き込むファイルにマルチバイト文字が含まれている場合は、Unicode (UTF-8) でエンコードされている必要があります。
+

 

+

6.3.44 "RouterList": 仮想レイヤ 3 スイッチ一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + RouterList
コマンドの概要 + 仮想レイヤ 3 スイッチ一覧の取得
説明 + VPN Server 上に定義されている仮想レイヤ 3 スイッチの一覧を取得します。仮想レイヤ 3 スイッチの [スイッチ名]、[動作状況]、[インターフェイス数]、[ルーティングテーブル数] が取得できます。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
また、このコマンドは VPN Bridge では動作しません。
コマンドライン書式 + RouterList
"RouterList" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.45 "RouterAdd": 新しい仮想レイヤ 3 スイッチの定義

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + RouterAdd
コマンドの概要 + 新しい仮想レイヤ 3 スイッチの定義
説明 + VPN Server 上に、新しい仮想レイヤ 3 スイッチを定義します。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
また、このコマンドは VPN Bridge では動作しません。

[仮想レイヤ 3 スイッチ機能についての説明]
この VPN Server 内で動作している複数の仮想 HUB 間で、仮想のレイヤ 3 スイッチを定義し、異なった IP ネットワーク間をルーティングすることができます。

[仮想レイヤ 3 スイッチ機能に関するご注意]
仮想レイヤ 3 スイッチ機能は、ネットワークおよび IP ルーティングに関する詳しい知識をお持ちの方やネットワーク管理者のための機能です。通常の VPN 機能を使用する場合は、仮想レイヤ 3 スイッチ機能を使用する必要はありません。
仮想レイヤ 3 スイッチ機能を使用する場合は、IP ルーティングに関する十分な知識をお持ちの上で、ネットワークに与える影響を十分考慮してから設定してください。
コマンドライン書式 + RouterAdd [name]
"RouterAdd" コマンドで指定することができるパラメータ引数の一覧:
name + 新しく作成する仮想レイヤ 3 スイッチの名前を指定します。既に存在する仮想レイヤ 3 スイッチと同一の名前を付けることはできません。
+

 

+

6.3.46 "RouterDelete": 仮想レイヤ 3 スイッチの削除

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + RouterDelete
コマンドの概要 + 仮想レイヤ 3 スイッチの削除
説明 + VPN Server 上に定義されている、既存の仮想レイヤ 3 スイッチを削除します。指定した仮想レイヤ 3 スイッチが動作中の場合は、自動的に動作を停止してから削除を行ないます。
既存の仮想レイヤ 3 スイッチの一覧を取得するには、RouterList コマンドを使用します。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
また、このコマンドは VPN Bridge では動作しません。
コマンドライン書式 + RouterDelete [name]
"RouterDelete" コマンドで指定することができるパラメータ引数の一覧:
name + 削除する仮想レイヤ 3 スイッチの名前を指定します。
+

 

+

6.3.47 "RouterStart": 仮想レイヤ 3 スイッチの動作の開始

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + RouterStart
コマンドの概要 + 仮想レイヤ 3 スイッチの動作の開始
説明 + VPN Server 上に定義されている、既存の仮想レイヤ 3 スイッチの動作が停止している場合は、その動作を開始します。
既存の仮想レイヤ 3 スイッチの一覧を取得するには、RouterList コマンドを使用します。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
また、このコマンドは VPN Bridge では動作しません。

[仮想レイヤ 3 スイッチ機能についての説明]
この VPN Server 内で動作している、複数の仮想 HUB 間で仮想のレイヤ 3 スイッチを定義し、異なった IP ネットワーク間をルーティングすることができます。

[仮想レイヤ 3 スイッチ機能に関するご注意]
仮想レイヤ 3 スイッチ機能は、ネットワークおよび IP ルーティングに関する詳しい知識をお持ちの方や、ネットワーク管理者のための機能です。通常の VPN 機能を使用する場合は、仮想レイヤ 3 スイッチ機能を使用する必要はありません。
仮想レイヤ 3 スイッチ機能を使用する場合は、IP ルーティングに関する十分な知識をお持ちの上で、ネットワークに与える影響を十分考慮してから設定してください。
コマンドライン書式 + RouterStart [name]
"RouterStart" コマンドで指定することができるパラメータ引数の一覧:
name + 開始する仮想レイヤ 3 スイッチの名前を指定します。
+

 

+

6.3.48 "RouterStop": 仮想レイヤ 3 スイッチの動作の停止

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + RouterStop
コマンドの概要 + 仮想レイヤ 3 スイッチの動作の停止
説明 + VPN Server 上に定義されている、既存の仮想レイヤ 3 スイッチの動作が動作している場合は、その動作を停止します。
既存の仮想レイヤ 3 スイッチの一覧を取得するには、RouterList コマンドを使用します。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
コマンドライン書式 + RouterStop [name]
"RouterStop" コマンドで指定することができるパラメータ引数の一覧:
name + 停止する仮想レイヤ 3 スイッチの名前を指定します。
+

 

+

6.3.49 "RouterIfList": 仮想レイヤ 3 スイッチに登録されているインターフェイス一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + RouterIfList
コマンドの概要 + 仮想レイヤ 3 スイッチに登録されているインターフェイス一覧の取得
説明 + 指定した仮想レイヤ 3 スイッチに仮想インターフェイスが定義されている場合は、仮想インターフェイスの一覧を取得します。
1 つの仮想レイヤ 3 スイッチには、複数個の仮想インターフェイスとルーティングテーブルを定義することができます。
仮想インターフェイスは仮想 HUB に関連付けられ、仮想 HUB が動作しているときに、仮想 HUB 内で 1 台の IP ホストのように動作します。複数の仮想 HUB に対して、それぞれ別々の IP ネットワークに所属する仮想インターフェイスが定義されているとき、それらのインターフェイス間で IP ルーティングが自動的に行われます。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
また、このコマンドは VPN Bridge では動作しません。
コマンドライン書式 + RouterIfList [name]
"RouterIfList" コマンドで指定することができるパラメータ引数の一覧:
name + 仮想レイヤ 3 スイッチの名前を指定します。
+

 

+

6.3.50 "RouterIfAdd": 仮想レイヤ 3 スイッチへの仮想インターフェイスの追加

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + RouterIfAdd
コマンドの概要 + 仮想レイヤ 3 スイッチへの仮想インターフェイスの追加
説明 + 指定した仮想レイヤ 3 スイッチに、同じ VPN Server 上で動作している仮想 HUB へ接続する仮想インターフェイスを追加します。
1 つの仮想レイヤ 3 スイッチには、複数個の仮想インターフェイスとルーティングテーブルを定義することができます。
仮想インターフェイスは仮想 HUB に関連付けられ、仮想 HUB が動作しているときに、仮想 HUB 内で 1 台の IP ホストのように動作します。複数の仮想 HUB に対して、それぞれ別々の IP ネットワークに所属する仮想インターフェイスが定義されているとき、それらのインターフェイス間で IP ルーティングが自動的に行われます。
仮想インターフェイスが所属する IP ネットワーク空間と、インターフェイス自身の IP アドレスを定義する必要があります。
また、インターフェイスが接続する先の仮想 HUB 名を指定する必要があります。
仮想 HUB 名には現在存在していない仮想 HUB を指定することもできます。
仮想インターフェイスは、仮想 HUB 内で 1 つの IP アドレスを持つ必要があります。また、その IP アドレスの属する IP ネットワークのサブネットマスクを指定する必要もあります。
複数の仮想 HUB 内の IP 空間同士の仮想レイヤ 3 スイッチを経由したルーティングは、ここで指定した IP アドレスに基づいて動作します。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
また、このコマンドは VPN Bridge では動作しません。
このコマンドを実行するには、操作対象の仮想レイヤ 3 スイッチが停止している必要があります。もし停止していない場合は、RouterStop コマンドで停止させてからこのコマンドを実行してください。
コマンドライン書式 + RouterIfAdd [name] [/HUB:hub] [/IP:ip/mask]
"RouterIfAdd" コマンドで指定することができるパラメータ引数の一覧:
name + 仮想レイヤ 3 スイッチの名前を指定します。
/HUB + 新しく追加する仮想インターフェイスの接続先の仮想 HUB 名を指定します。仮想 HUB の一覧は、HubList コマンドで取得できます。ただし、必ずしも現在動作している仮想 HUB 名を指定する必要はありません。現在動作していない、または存在しない仮想 HUB 名を指定すると、その仮想 HUB が実際に動作を開始した際に、仮想レイヤ 3 スイッチが有効になります。
/IP + [IP アドレス/サブネットマスク] の形式で、新しく追加する仮想インターフェイスの持つ IP アドレスと、サブネットマスクを指定します。IP アドレスは 192.168.0.1 のように、10 進数をドットで区切って指定します。サブネットマスクは 255.255.255.0 のように 10 進数をドットで区切って指定するか、24 のように先頭からのビット長を 10 進数で指定できます。
+

 

+

6.3.51 "RouterIfDel": 仮想レイヤ 3 スイッチの仮想インターフェイスの削除

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + RouterIfDel
コマンドの概要 + 仮想レイヤ 3 スイッチの仮想インターフェイスの削除
説明 + 指定した仮想レイヤ 3 スイッチ内に、すでに定義されている仮想インターフェイスを削除します。
現在定義されている仮想インターフェイスの一覧は、RouterIfList コマンドで取得することができます。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
また、このコマンドは VPN Bridge では動作しません。
このコマンドを実行するには、操作対象の仮想レイヤ 3 スイッチが停止している必要があります。もし停止していない場合は、RouterStop コマンドで停止させてからこのコマンドを実行してください。
コマンドライン書式 + RouterIfDel [name] [/HUB:hub]
"RouterIfDel" コマンドで指定することができるパラメータ引数の一覧:
name + 仮想レイヤ 3 スイッチの名前を指定します。
/HUB + 削除する仮想インターフェイスの接続先の仮想 HUB 名を指定します。
+

 

+

6.3.52 "RouterTableList": 仮想レイヤ 3 スイッチのルーティングテーブル一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + RouterTableList
コマンドの概要 + 仮想レイヤ 3 スイッチのルーティングテーブル一覧の取得
説明 + 指定した仮想レイヤ 3 スイッチに、ルーティングテーブルが定義されている場合は、ルーティングテーブルの一覧を取得します。
仮想レイヤ 3 スイッチの IP ルーティングエンジンは、IP パケットの宛先 IP アドレスが、各仮想インターフェイスの所属する IP ネットワークのいずれにも所属しない場合は、このルーティングテーブルを参照してルーティングを行います。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
また、このコマンドは VPN Bridge では動作しません。
コマンドライン書式 + RouterTableList [name]
"RouterTableList" コマンドで指定することができるパラメータ引数の一覧:
name + 仮想レイヤ 3 スイッチの名前を指定します。
+

 

+

6.3.53 "RouterTableAdd": 仮想レイヤ 3 スイッチへのルーティングテーブルエントリの追加

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + RouterTableAdd
コマンドの概要 + 仮想レイヤ 3 スイッチへのルーティングテーブルエントリの追加
説明 + 指定した仮想レイヤ 3 スイッチのルーティングテーブルに、新しいルーティングテーブルエントリを追加します。
仮想レイヤ 3 スイッチの IP ルーティングエンジンは、IP パケットの宛先 IP アドレスが、各仮想インターフェイスの所属する IP ネットワークのいずれにも所属しない場合、ルーティングテーブルを参照してルーティングを行います。
仮想レイヤ 3 スイッチに追加するルーティングテーブルのエントリの内容を指定する必要があります。ゲートウェイアドレスとしては、この仮想レイヤ 3 スイッチの仮想インターフェイスのうち、いずれかと同じ IP ネットワークに所属する IP アドレスを指定する必要があります。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
また、このコマンドは VPN Bridge では動作しません。
このコマンドを実行するには、操作対象の仮想レイヤ 3 スイッチが停止している必要があります。もし停止していない場合は、RouterStop コマンドで停止させてからこのコマンドを実行してください。
コマンドライン書式 + RouterTableAdd [name] [/NETWORK:ip/mask] [/GATEWAY:gwip] [/METRIC:metric]
"RouterTableAdd" コマンドで指定することができるパラメータ引数の一覧:
name + 仮想レイヤ 3 スイッチの名前を指定します。
/NETWORK + [IP アドレス/サブネットマスク] の形式で、新しく追加するルーティングテーブルエントリの、ネットワークアドレスとサブネットマスクを指定します。ネットワークアドレスは、192.168.0.1 のように 10 進数をドットで区切って指定します。サブネットマスクは、255.255.255.0 のように 10 進数をドットで区切って指定するか、24 のように先頭からのビット長を 10 進数で指定できます。0.0.0.0/0.0.0.0 を指定すると、デフォルトルートの意味になります。
/GATEWAY + ゲートウェイの IP アドレスを指定します。
/METRIC + メトリック値を指定します。1 以上の整数で指定してください。
+

 

+

6.3.54 "RouterTableDel": 仮想レイヤ 3 スイッチのルーティングテーブルエントリの削除

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + RouterTableDel
コマンドの概要 + 仮想レイヤ 3 スイッチのルーティングテーブルエントリの削除
説明 + 指定した仮想レイヤ 3 スイッチ内に定義されているルーティングテーブルのエントリを削除します。
すでに定義されているルーティンクテーブルエントリの一覧は、RouterTableList コマンドで取得できます。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
また、このコマンドは VPN Bridge では動作しません。
このコマンドを実行するには、操作対象の仮想レイヤ 3 スイッチが停止している必要があります。もし停止していない場合は、RouterStop コマンドで停止させてからこのコマンドを実行してください。
コマンドライン書式 + RouterTableDel [name] [/NETWORK:ip/mask] [/GATEWAY:gwip] [/METRIC:metric]
"RouterTableDel" コマンドで指定することができるパラメータ引数の一覧:
name + 仮想レイヤ 3 スイッチの名前を指定します。
/NETWORK + [IP アドレス/サブネットマスク] の形式で、削除するルーティングテーブルエントリの、ネットワークアドレスを指定します。
/GATEWAY + ゲートウェイの IP アドレスを指定します。
/METRIC + メトリック値を指定します。1 以上の整数で指定してください。
+

 

+

6.3.55 "LogFileList": ログファイル一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + LogFileList
コマンドの概要 + ログファイル一覧の取得
説明 + VPN Server のコンピュータ上に保存されている、VPN Server が出力したログファイルの一覧を表示します。ここで表示されるログファイルのファイル名を指定して LogFileGet コマンドを呼び出すことにより、ログファイルの内容をダウンロードすることもできます。
VPN Server にサーバー管理モードで接続している場合は、すべての仮想 HUB のパケットログ、セキュリティログ、および VPN Server のサーバー ログを表示またはダウンロードすることができます。
仮想 HUB 管理モードで接続している場合は、管理対象の仮想 HUB のパケットログとセキュリティログのみを表示またはダウンロードすることができます。
コマンドライン書式 + LogFileList
"LogFileList" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.56 "LogFileGet": ログファイルのダウンロード

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + LogFileGet
コマンドの概要 + ログファイルのダウンロード
説明 + VPN Server のコンピュータ上に保存されているログファイルをダウンロードします。ログファイルをダウンロードするには、まず LogFileList コマンドでログファイルの一覧を表示してから、次に LogFileGet コマンドでダウンロードすることができます。VPN Server にサーバー管理モードで接続している場合は、すべての仮想 HUB のパケットログ、セキュリティログ、および VPN Server のサーバー ログを表示またはダウンロードすることができます。仮想 HUB 管理モードで接続している場合は、管理対象の仮想 HUB のパケットログと、セキュリティログのみを表示、またはダウンロードすることができます。
パラメータとしてファイル名を指定した場合は、ダウンロードしたログファイルは、そのファイル名のファイルに保存されます。ファイル名を指定しなかった場合は、画面上に表示されます。
ログファイルのサイズは、巨大になる場合がありますので、注意してください。
コマンドライン書式 + LogFileGet [name] [/SERVER:server] [/SAVEPATH:savepath]
"LogFileGet" コマンドで指定することができるパラメータ引数の一覧:
name + ダウンロードするログファイル名を指定します。LogFileList コマンドで、ダウンロードできるログファイル名の一覧を取得できます。
/SERVER + クラスタコントローラに対してダウンロード要求を行う場合は、ログファイルが保存されているサーバー名を指定します。LogFileGet コマンドで表示されるサーバーを指定してください。
/SAVEPATH + ダウンロードしたログファイルを保存する場合は、ファイル名を指定します。指定しない場合は、画面上に表示されます。
+

 

+

6.3.57 "HubCreate": 新しい仮想 HUB の作成

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + HubCreate
コマンドの概要 + 新しい仮想 HUB の作成
説明 + VPN Server 上に新しい仮想 HUB を作成します。
作成した仮想 HUB は、直ちに動作を開始します。
VPN Server がクラスタ内で動作している場合は、このコマンドはクラスタコントローラに対してのみ有効です。また、新しい仮想 HUB は、ダイナミック仮想 HUB として動作します。HubSetStatic コマンドで、スタティック仮想 HUB に変更することもできます。すでに VPN Server 上に存在する仮想 HUB の一覧を取得するには、HubList コマンドを使用します。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
また、このコマンドは VPN Bridge およびクラスタメンバサーバーとして動作している VPN Server では動作しません。
なお、クラスタ上でクラスタコントローラに対して仮想 HUB の作成コマンドを発行する場合は、HubCreateStatic コマンドまたは HubCreateDynamic コマンドを使用してください (クラスタコントローラに対して HubCreate コマンドを使用すると HubCreateDynamic コマンドと同等に動作します)。
コマンドライン書式 + HubCreate [name] [/PASSWORD:password]
"HubCreate" コマンドで指定することができるパラメータ引数の一覧:
name + 作成する仮想 HUB の名前を指定します。
/PASSWORD + 作成する仮想 HUB の管理パスワードを設定する場合は、その管理パスワードを指定します。指定しない場合は、入力するためのプロンプトが表示されます。
+

 

+

6.3.58 "HubCreateDynamic": 新しいダイナミック仮想 HUB の作成 (クラスタリング用)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + HubCreateDynamic
コマンドの概要 + 新しいダイナミック仮想 HUB の作成 (クラスタリング用)
説明 + VPN Server 上に新しいダイナミック仮想 HUB を作成します。
作成した仮想 HUB は、直ちに動作を開始します。
VPN Server がクラスタ内で動作している場合は、このコマンドはクラスタコントローラに対してのみ有効です。また、新しい仮想 HUB は、ダイナミック仮想 HUB として動作します。HubSetStatic コマンドで、スタティック仮想 HUB に変更することもできます。すでに VPN Server 上に存在する仮想 HUB の一覧を取得するには、HubList コマンドを使用します。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
また、このコマンドは VPN Bridge およびクラスタメンバサーバー、またはスタンドアロンサーバーとして動作している VPN Server では動作しません。
コマンドライン書式 + HubCreateDynamic [name] [/PASSWORD:password]
"HubCreateDynamic" コマンドで指定することができるパラメータ引数の一覧:
name + 作成する仮想 HUB の名前を指定します。
/PASSWORD + 作成する仮想 HUB の管理パスワードを設定する場合は、その管理パスワードを指定します。指定しない場合は、入力するためのプロンプトが表示されます。
+

 

+

6.3.59 "HubCreateStatic": 新しいスタティック仮想 HUB の作成 (クラスタリング用)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + HubCreateStatic
コマンドの概要 + 新しいスタティック仮想 HUB の作成 (クラスタリング用)
説明 + VPN Server 上に新しいスタティック仮想 HUB を作成します。
作成した仮想 HUB は、直ちに動作を開始します。
VPN Server がクラスタ内で動作している場合は、このコマンドはクラスタコントローラに対してのみ有効です。また、新しい仮想 HUB は、ダイナミック仮想 HUB として動作します。HubSetStatic コマンドで、スタティック仮想 HUB に変更することもできます。すでに VPN Server 上に存在する仮想 HUB の一覧を取得するには、HubList コマンドを使用します。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
また、このコマンドは VPN Bridge およびクラスタメンバサーバー、またはスタンドアロンサーバーとして動作している VPN Server では動作しません。
コマンドライン書式 + HubCreateStatic [name] [/PASSWORD:password]
"HubCreateStatic" コマンドで指定することができるパラメータ引数の一覧:
name + 作成する仮想 HUB の名前を指定します。
/PASSWORD + 作成する仮想 HUB の管理パスワードを設定する場合は、その管理パスワードを指定します。指定しない場合は、入力するためのプロンプトが表示されます。
+

 

+

6.3.60 "HubDelete": 仮想 HUB の削除

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + HubDelete
コマンドの概要 + 仮想 HUB の削除
説明 + VPN Server 上の、既存の仮想 HUB を削除します。
仮想 HUB を削除すると、現在仮想 HUB に接続しているセッションがすべて切断され、新たなセッションが仮想 HUB に接続できなくなります。
また、仮想 HUB のすべての設定、ユーザー オブジェクト、グループオブジェクト、証明書、およびカスケード接続が削除されます。
仮想 HUB を削除すると、元に戻すことはできません。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
また、このコマンドは VPN Bridge、およびクラスタメンバサーバーとして動作している VPN Server では動作しません。
コマンドライン書式 + HubDelete [name]
"HubDelete" コマンドで指定することができるパラメータ引数の一覧:
name + 削除する仮想 HUB の名前を指定します。
+

 

+

6.3.61 "HubSetStatic": 仮想 HUB の種類をスタティック仮想 HUB に変更

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + HubSetStatic
コマンドの概要 + 仮想 HUB の種類をスタティック仮想 HUB に変更
説明 + VPN Server がクラスタ内で動作している場合、仮想 HUB の種類を、スタティック仮想 HUB に設定します。仮想 HUB の種類を変更すると、現在仮想 HUB に接続しているすべてのセッションは一旦切断されます。
スタティック仮想 HUB として動作している仮想 HUB がある場合、すべてのクラスタメンバサーバー上で、その名前の仮想 HUB が生成されます。その仮想 HUB に接続しようとしたユーザーは、各サーバーの負荷状況を元にしたアルゴリズムによって、その仮想 HUB をホスティングしている、いずれかのクラスタメンバに接続されます。
スタティック仮想 HUB は、一例として、企業におけるインターネットから社内 LAN へのリモートアクセス用途において、同時に数千~数万単位の大量のユーザーが同時に接続する可能性があるリモートアクセス VPN 用に利用することが可能です。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
また、このコマンドは VPN Bridge およびクラスタメンバサーバー、またはスタンドアロンサーバーとして動作している VPN Server では動作しません。
このコマンドはビルド 5190 より新しい VPN Server では使用できません。
コマンドライン書式 + HubSetStatic [name]
"HubSetStatic" コマンドで指定することができるパラメータ引数の一覧:
name + スタティック仮想 HUB に設定する仮想 HUB の名前を指定します。
+

 

+

6.3.62 "HubSetDynamic": 仮想 HUB の種類をダイナミック仮想 HUB に変更

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + HubSetDynamic
コマンドの概要 + 仮想 HUB の種類をダイナミック仮想 HUB に変更
説明 + VPN Server がクラスタ内で動作している場合、仮想 HUB の種類を、ダイナミック仮想 HUB に設定します。仮想 HUB の種類を変更すると、現在仮想 HUB に接続しているすべてのセッションは一旦切断されます。
クラスタ内に定義されているダイナミック仮想 HUB にクライアントが 1 台も接続していないとき、その仮想 HUB はどのクラスタメンバ上にも存在しません。ダイナミック仮想 HUB に 1 台目のクライアントが接続しようとすると、クラスタ内で最も負荷の低いサーバーがその仮想 HUB をホスティングします。2 台目以降のクライアントがその仮想 HUB に接続しようとすると、仮想 HUB をホスティングしているサーバーに自動的に接続します。各ダイナミック仮想 HUB は、すべてのクライアントが切断すると、どのサーバーにも実体が存在しない状態に戻ります。
ダイナミック仮想 HUB の応用例は幅広く、たとえば社内において部課毎に仮想 HUB を定義しておき、各社員が自分が所属している部課の仮想 HUB に接続して作業を行うといったことを、単一のクラスタを設置するだけで、集中管理することができます。
このコマンドを実行するには、VPN Server の管理者権限が必要です。
また、このコマンドは VPN Bridge およびクラスタメンバサーバー、またはスタンドアロンサーバーとして動作している VPN Server では動作しません。
このコマンドはビルド 5190 より新しい VPN Server では使用できません。
コマンドライン書式 + HubSetDynamic [name]
"HubSetDynamic" コマンドで指定することができるパラメータ引数の一覧:
name + ダイナミック仮想 HUB に設定する仮想 HUB の名前を指定します。
+

 

+

6.3.63 "HubList": 仮想 HUB の一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + HubList
コマンドの概要 + 仮想 HUB の一覧の取得
説明 + VPN Server 内の、既存の仮想 HUB の一覧を取得します。それぞれの仮想 HUB について、[仮想 HUB 名]、[状態]、[種類]、[ユーザー数]、[グループ数]、[セッション数]、[MAC テーブル数]、[IP テーブル数]、[ログイン回数]、[最終ログイン日時]、[最終通信日時] を取得できます。
ただし、仮想 HUB 管理モードで接続している場合は、管理権限のない仮想 HUB のオプションで、匿名ユーザーに対して仮想 HUB を列挙しないオプションが有効になっている場合、その仮想 HUB は列挙されません。サーバー管理モードで接続している場合は、すべての仮想 HUB の一覧が表示されます。
クラスタリング環境におけるクラスタコントローラ以外のクラスタメンバに接続して管理している場合は、その VPN Server が、現在ホスティングしている仮想 HUB のみが表示されます。クラスタコントローラに接続して管理している場合は、すべての仮想 HUB が表示されます。
コマンドライン書式 + HubList
"HubList" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.64 "Hub": 管理する仮想 HUB の選択

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + Hub
コマンドの概要 + 管理する仮想 HUB の選択
説明 + 管理対象の仮想 HUB を選択します。VPN Server に接続した状態の管理ユーティリティでは、仮想 HUB に関する設定・管理を行なうコマンドを実行する前に、管理を行なう仮想 HUB を Hub コマンドで選択しておく必要があります。
VPN Server に仮想 HUB 管理モードで接続している状態では、管理対象となっている 1 つの仮想 HUB を選択することができ、他の仮想 HUB を選択することはできません。VPN Server にサーバー管理モードで接続している状態では、すべての仮想 HUB の管理を行なうことができます。
現在サーバー上に存在する仮想 HUB の一覧を取得するには、HubList コマンドを使用します。
VPN Bridge では、"BRIDGE" という名前の仮想 HUB 以外を選択することはできません。
コマンドライン書式 + Hub [name]
"Hub" コマンドで指定することができるパラメータ引数の一覧:
name + 管理する仮想 HUB の名前を指定します。パラメータを指定していない場合は、管理対象の仮想 HUB の選択を解除します。
+

 

+

6.3.65 "MakeCert": 新しい X.509 証明書と秘密鍵の作成

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + MakeCert
コマンドの概要 + 新しい X.509 証明書と秘密鍵の作成
説明 + 新しい X.509 証明書と秘密鍵を作成し、ファイルとして保存します。
証明書の公開鍵と秘密鍵の生成アルゴリズムには、RSA 1024 bit が使用されます。
証明書の種類として、ルート証明書 (自己署名証明書) と他の証明書によって署名された証明書のどちらでも作成することができます。他の証明書によって署名された証明書を作成するためには、署名に使用する証明書 (X.509 形式のファイル) と対応する秘密鍵ファイル (Base 64 エンコード) が必要です。

作成する証明書には、名前 (CN)、所属機関 (O)、組織単位 (OU)、国 (C)、都道府県 (ST)、ローカル (L)、シリアル番号、有効期限を指定することができます。
作成された証明書は X.509 形式のファイルとして、秘密鍵ファイルは RSA 1024 bit 形式の Base 64 エンコードされたファイルとしてそれぞれ保存されます。

MakeCert コマンドは、証明書を作成するための必要最低限の機能を用意したツールです。本格的な証明書を作成したい場合は、OpenSSL などのフリーソフトや、市販の CA (証明機関) ソフトウェアを使用することを推奨します。

※注意: このコマンドは PacketiX VPN コマンドライン管理ユーティリティから呼び出すことが可能です。現在 VPN Server や VPN Client に管理モードで接続している場合も実行できますが、実際に RSA 演算を行い、証明書データを生成しファイルに保存するのはこのコマンドを実行しているコンピュータであり、管理モードで接続先のコンピュータとは一切関係ないコンテキストで実行されます。
コマンドライン書式 + MakeCert [/CN:cn] [/O:o] [/OU:ou] [/C:c] [/ST:st] [/L:l] [/SERIAL:serial] [/EXPIRES:expires] [/SIGNCERT:signcert] [/SIGNKEY:signkey] [/SAVECERT:savecert] [/SAVEKEY:savekey]
"MakeCert" コマンドで指定することができるパラメータ引数の一覧:
/CN + 作成する証明書の名前 (CN) 項目を指定します。none を指定することもできます。
/O + 作成する証明書の所属機関 (O) 項目を指定します。none を指定することもできます。
/OU + 作成する証明書の組織単位 (OU) 項目を指定します。none を指定することもできます。
/C + 作成する証明書の国 (C) 項目を指定します。none を指定することもできます。
/ST + 作成する証明書の都道府県 (ST) 項目を指定します。none を指定することもできます。
/L + 作成する証明書のローカル (L) 項目を指定します。none を指定することもできます。
/SERIAL + 作成する証明書のシリアル番号項目を指定します。16 進数で指定します。none を指定することもできます。
/EXPIRES + 作成する証明書の有効期限を指定します。none または 0 を指定すると、3650 日 (約 10 年) が使用されます。最大 10950 日 (約 30 年) まで指定できます。
/SIGNCERT + 作成する証明書を、既存の証明書によって署名する場合は、署名に使用する X.509 形式の証明書のファイル名を指定します。パラメータを省略した場合は、署名は行わず新しい証明書をルート証明書として作成します。
/SIGNKEY + /SIGNCERT で指定した証明書に対応する秘密鍵 (RSA, Base-64 エンコード) を指定します。
/SAVECERT + 作成した証明書を保存するファイル名を指定します。証明書は RSA 形式の 1024 bit の公開鍵を含んだ X.509 ファイルとして保存されます。
/SAVEKEY + 作成した証明書に対応する秘密鍵を保存するファイル名を指定します。秘密鍵は RSA 形式の 1024 bit の秘密鍵ファイルとして保存されます。
+

 

+

6.3.66 "TrafficClient": 通信スループット測定ツールクライアントの実行

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + TrafficClient
コマンドの概要 + 通信スループット測定ツールクライアントの実行
説明 + 通信スループット測定ツールの、クライアントプログラムを実行します。
通信スループット測定ツールは TrafficClient と TrafficServer の 2 つのコマンドとして利用し、IP ネットワーク上で接続された 2 台のコンピュータの間で伝送することができる通信スループットを計測することができます。すでに別のコンピュータ上で、TrafficServer コマンドを用いて通信スループット測定ツールサーバーを待機させておき、TrafficClient コマンドで、そのサーバーのホスト名または IP アドレスとポート番号を指定して接続し、通信速度を測定することができます。
通信速度の測定は、同時に複数本の TCP コネクションを確立し、それぞれのコネクションで最大限にストリームデータを伝送した結果、指定された時間内に実際に伝送することができたデータのビット数を計算し、それを元に通信スループットの平均値 (bps) を算出する方法で行われます。通常、1 本の TCP コネクションを用いた場合は TCP のアルゴリズム上の限界により、実際のネットワークスループットよりも遅い速度でしか通信できない場合が多いため、複数本の TCP コネクションを同時に確立して通信した結果を測定することを推奨します。この測定方法によって計測されたスループットは実際に TCP でストリームとして受信側に届いたデータのビット長から計算されるため、途中で発生したパケットロスやデータ破損したパケットは、実際に届いたパケットには含まれず、純粋なネットワークの最大通信可能帯域幅に近い値を算出することができます。
測定結果として TCP 内で伝送されたストリームサイズから、実際にネットワーク上を流れたデータ量の近似値を計算し、それを時間で割ってビット毎秒 (bps) を算出します。物理的なネットワークの種類は Ethernet (IEEE802.3) で、MAC フレームのペイロードサイズは 1,500 Bytes (TCP の MSS は 1,460 Bytes) と仮定して計算が行われます。/RAW オプションを指定すると、TCP/IP ヘッダや MAC ヘッダのデータ量を補正する計算は行われません。

※注意: このコマンドは PacketiX VPN コマンドライン管理ユーティリティから呼び出すことが可能です。現在 VPN Server や VPN Client に管理モードで接続している場合も実行できますが、実際に通信を行ってスループットを測定するのは、このコマンドを実行しているコンピュータであり、管理モードで接続先のコンピュータとは一切関係ないコンテキストで実行されます。
コマンドライン書式 + TrafficClient [host:port] [/NUMTCP:numtcp] [/TYPE:download|upload|full] [/SPAN:span] [/DOUBLE:yes|no] [/RAW:yes|no]
"TrafficClient" コマンドで指定することができるパラメータ引数の一覧:
host:port + 通信スループット測定ツールサーバー (TrafficServer) が待機しているホスト名、または IP アドレスとポート番号を指定します。ポート番号を省略した場合は、9821 が使用されます。
/NUMTCP + 同時にクライアントとサーバーとの間で確立されデータが伝送される TCP コネクション数を指定します。省略した場合は 32 が使用されます。
/TYPE + スループット測定を行う際の、データの流れる方向を指定します。"download"、"upload"、"full" のうち 1 つを指定します。download を指定すると、サーバー側からクライアント側にデータが伝送されます。upload を指定すると、クライアント側からサーバー側にデータが伝送されます。full を指定すると、双方向にデータが伝送されます。full を指定する場合は、NUMTCP の値は 2 以上の偶数に指定する必要があります (同時に接続される TCP コネクションのうち半数がダウンロード方向、残りの半数がアップロード方向に使用されます)。このパラメータを省略した場合は full が使用されます。
/SPAN + スループットを測定するためのデータ伝送を行う時間を、秒数単位で指定します。このパラメータを省略した場合は 15 秒が使用されます。
/DOUBLE + "yes" を指定した場合、計測した結果のスループットを 2 倍にして表示します。このオプションは、途中にネットワーク装置などがあり、そのネットワーク装置が入出力した合計のスループット能力を測定する場合に使用します。
/RAW + "yes" を指定すると、TCP/IP ヘッダや MAC ヘッダのデータ量を補正する計算を行いません。
+

 

+

6.3.67 "TrafficServer": 通信スループット測定ツールサーバーの実行

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + TrafficServer
コマンドの概要 + 通信スループット測定ツールサーバーの実行
説明 + 通信スループット測定ツールのサーバープログラムを実行します。
通信スループット測定ツールは、TrafficClient と TrafficServer の 2 つのコマンドとして利用し、IP ネットワーク上で接続された 2 台のコンピュータの間で伝送することができる通信スループットを計測することができます。
このコンピュータ上の TCP ポートを待機状態にして、別のコンピュータからの TrafficClient からの接続を待ち受けるには、TrafficServer コマンドにポート番号を指定して起動します。
通信スループット測定ツールに関する詳細は、TrafficClient /? と入力すると表示されます。

※注意: このコマンドは PacketiX VPN コマンドライン管理ユーティリティから呼び出すことが可能です。現在 VPN Server や VPN Client に管理モードで接続している場合も実行できますが、実際に通信を行ってスループットを測定するのは、このコマンドを実行しているコンピュータであり、管理モードで接続先のコンピュータとは一切関係ないコンテキストで実行されます。
コマンドライン書式 + TrafficServer [port]
"TrafficServer" コマンドで指定することができるパラメータ引数の一覧:
port + 接続を待ち受けるポート番号を整数で指定します。指定されたポートが、すでに別のプログラムによって使用中の場合や、ポートを開くことができない場合はエラーが発生します。
+

 

+

6.3.68 "Check": PacketiX VPN の動作が可能かどうかチェックする

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + Check
コマンドの概要 + PacketiX VPN の動作が可能かどうかチェックする
説明 + 現在 vpncmd を動作させているコンピュータが、PacketiX VPN Server / Bridge の動作プラットフォームとして適切であるかどうかをチェックします。
このチェックを通過したシステム上では、PacketiX VPN ソフトウェアが正しく動作する可能性が高いと思われます。
また、このチェックを通過できないシステム上では、PacketiX VPN ソフトウェアを使用した場合に、何らかの問題が発生する可能性があります。
コマンドライン書式 + Check
"Check" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.69 "IPsecEnable": IPsec VPN サーバー機能の有効化 / 無効化

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + IPsecEnable
コマンドの概要 + IPsec VPN サーバー機能の有効化 / 無効化
説明 + PacketiX VPN Server の IPsec VPN サーバー機能を有効化 / 無効化します。
IPsec VPN サーバー機能を有効にすると、VPN Server 上の仮想 HUB は、IPsec / L2TP / EtherIP / L2TPv3 に対応した PC や Mac OS X、スマートフォン、ルータ等からの VPN 接続を受付けることができるようになります。

このコマンドを実行するには、VPN Server の管理者権限が必要です。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + IPsecEnable [/L2TP:yes|no] [/L2TPRAW:yes|no] [/ETHERIP:yes|no] [/PSK:pre-shared-key] [/DEFAULTHUB:default_hub]
"IPsecEnable" コマンドで指定することができるパラメータ引数の一覧:
/L2TP + L2TP over IPsec サーバー機能を有効または無効に設定します。iPhone、iPad、Android、Windows、Mac OS X からの VPN 接続を受付けるにはこの機能を有効にしてください。
/L2TPRAW + IPsec を用いない L2TP サーバー機能を有効または無効に設定します。特殊なクライアントからの接続を受付ける場合のみ有効にしてください。
/ETHERIP + EtherIP / L2TPv3 over IPsec サーバー機能 (拠点間接続 VPN サーバー機能) を有効または無効に設定します。EtherIP / L2TPv3 over IPsec に対応した市販のルータ製品は、この VPN Server の仮想 HUB にレイヤ 2 (Ethernet) でブリッジ接続できるようになります。
/PSK + IPsec 事前共有鍵を設定します。IPsec 事前共有鍵は、「PSK (Pre-Shared Key)」または「シークレット」と呼ばれることがあります。8 文字程度で設定し、VPN を利用するすべてのユーザーに配布してください。Google Android 4.0 にはバグがあり、PSK の文字数が 10 文字を超えた場合は VPN 通信に失敗することがあります。そのため、PSK の文字数は 9 文字以下にすることを推奨します。
/DEFAULTHUB + 接続時のユーザー名において仮想 HUB 名が省略された場合に接続するデフォルトの仮想 HUB の名前を指定します。通常、L2TP, OpenVPN および MS-SSTP VPN 接続時のユーザー名は "仮想HUB名\ユーザー名" または "ユーザー名@仮想HUB名" のように指定される必要があります。もしユーザーが仮想 HUB 名の指定を省略した場合は、DEFAULTHUB パラメータとして指定されている仮想 HUB がデフォルトの仮想 HUB として選択されることになります。
+

 

+

6.3.70 "IPsecGet": IPsec VPN サーバー機能の現在の設定の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + IPsecGet
コマンドの概要 + IPsec VPN サーバー機能の現在の設定の取得
説明 + PacketiX VPN Server の IPsec VPN サーバー機能の現在の設定を取得して表示します。

このコマンドを実行するには、VPN Server の管理者権限が必要です。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + IPsecGet
"IPsecGet" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.71 "EtherIpClientAdd": EtherIP / L2TPv3 over IPsec サーバー機能のクライアントデバイスからの接続を受付けるための接続設定の追加

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + EtherIpClientAdd
コマンドの概要 + EtherIP / L2TPv3 over IPsec サーバー機能のクライアントデバイスからの接続を受付けるための接続設定の追加
説明 + EtherIP / L2TPv3 over IPsec サーバー機能のクライアントデバイスからの接続を受付けるための接続設定を追加します。
EtherIP / L2TPv3 over IPsec サーバー機能が有効になっている場合にルータ等からの接続を受付けるには、予めクライアント側となる EtherIP / L2TPv3 over IPsec 対応ルータが VPN Server に接続する際の IPsec Phase 1 文字列と、接続先の仮想 HUB の情報の対応表を定義しておく必要があります。
EtherIpClientAdd コマンドを用いて定義を追加することにより、EtherIP / L2TPv3 over IPsec クライアントがこの VPN Server に接続しようとした際の ISAKMP (IKE) Phase 1 のイニシエータ ID 文字列が定義に一致する場合に、定義されている仮想 HUB への接続設定が適用されます。
ユーザー名とパスワードは、仮想 HUB に登録されている必要があります。EtherIP / L2TPv3 クライアントは、このコマンドで入力された情報で識別されるユーザーの権限で仮想 HUB に接続したものとみなされます。

このコマンドを実行するには、VPN Server の管理者権限が必要です。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + EtherIpClientAdd [ID] [/HUB:hubname] [/USERNAME:username] [/PASSWORD:password]
"EtherIpClientAdd" コマンドで指定することができるパラメータ引数の一覧:
ID + ISAKMP Phase 1 ID を指定します。ID はクライアント側のルータの接続設定で設定するものと同一の文字列を指定してください。文字列のほか、ID の種類が IP アドレスの場合は IP アドレスも指定できます。なお、'*' (アスタリスク) を指定するとワイルドカード指定となり、他の明示的なルールに一致しないすべての接続元クライアントが対象となります。
/HUB + 接続先の仮想 HUB の名前を指定します。
/USERNAME + 接続先の仮想 HUB にログインするためのユーザー名を指定します。
/PASSWORD + 接続先の仮想 HUB にログインするためのパスワードを指定します。
+

 

+

6.3.72 "EtherIpClientDelete": EtherIP / L2TPv3 over IPsec サーバー機能のクライアントデバイスからの接続を受付けるための接続設定の削除

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + EtherIpClientDelete
コマンドの概要 + EtherIP / L2TPv3 over IPsec サーバー機能のクライアントデバイスからの接続を受付けるための接続設定の削除
説明 + EtherIP / L2TPv3 over IPsec サーバー機能のクライアントデバイスからの接続を受付けるための接続設定の定義済み項目を削除します。

このコマンドを実行するには、VPN Server の管理者権限が必要です。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + EtherIpClientDelete [ID]
"EtherIpClientDelete" コマンドで指定することができるパラメータ引数の一覧:
ID + ISAKMP Phase 1 ID を指定します。
+

 

+

6.3.73 "EtherIpClientList": EtherIP / L2TPv3 over IPsec サーバー機能のクライアントデバイスからの接続を受付けるための接続設定の一覧表示

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + EtherIpClientList
コマンドの概要 + EtherIP / L2TPv3 over IPsec サーバー機能のクライアントデバイスからの接続を受付けるための接続設定の一覧表示
説明 + EtherIP / L2TPv3 over IPsec サーバー機能のクライアントデバイスからの接続を受付けるための接続設定の定義済み一覧を表示します。

このコマンドを実行するには、VPN Server の管理者権限が必要です。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + EtherIpClientList
"EtherIpClientList" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.74 "OpenVpnEnable": OpenVPN 互換サーバー機能を有効化 / 無効化

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + OpenVpnEnable
コマンドの概要 + OpenVPN 互換サーバー機能を有効化 / 無効化
説明 + PacketiX VPN Server には OpenVPN 社の OpenVPN ソフトウェア製品と同等の VPN サーバー機能が搭載されています。OpenVPN サーバー機能を有効にすると、OpenVPN クライアントから OpenVPN サーバーに接続できるようになります。

OpenVPN 互換サーバー機能で仮想 HUB に接続する場合のユーザー名の指定方法、およびデフォルト仮想 HUB の選択規則は、IPsec サーバー機能と同様です。詳しくは IPsecEnable コマンドのヘルプを参照してください。

このコマンドを実行するには、VPN Server の管理者権限が必要です。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + OpenVpnEnable [yes|no] [/PORTS:udp_port_list]
"OpenVpnEnable" コマンドで指定することができるパラメータ引数の一覧:
yes|no + OpenVPN 互換サーバー機能を有効にする場合は yes、無効にする場合は no を指定します。
/PORTS + OpenVPN サービスを提供する UDP ポートの一覧を指定してください。UDP ポートは複数指定できます。複数指定する場合は 1194, 2001, 2010, 2012 のようにカンマ (,) で区切ってください。OpenVPN は標準では UDP 1194 ポートを使用しますが、その他の任意の UDP ポートを指定できます。
+

 

+

6.3.75 "OpenVpnGet": OpenVPN 互換サーバー機能の現在の設定を取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + OpenVpnGet
コマンドの概要 + OpenVPN 互換サーバー機能の現在の設定を取得
説明 + 現在の OpenVPN 互換サーバー機能の設定を取得して表示します。

このコマンドを実行するには、VPN Server の管理者権限が必要です。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + OpenVpnGet
"OpenVpnGet" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.76 "OpenVpnMakeConfig": OpenVPN 互換サーバー機能に接続可能なサンプルの OpenVPN 設定ファイルの生成

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + OpenVpnMakeConfig
コマンドの概要 + OpenVPN 互換サーバー機能に接続可能なサンプルの OpenVPN 設定ファイルの生成
説明 + 本来、OpenVPN クライアントを使うためには設定ファイルを手動で記述する必要がありますが、これは難易度が高い作業です。しかし、このコマンドを使用すればこの VPN Server に接続することができる基本的な OpenVPN クライアント用の設定ファイルを自動的に生成することができます。

このコマンドを実行するには、VPN Server の管理者権限が必要です。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + OpenVpnMakeConfig [ZIP_FileName]
"OpenVpnMakeConfig" コマンドで指定することができるパラメータ引数の一覧:
ZIP_FileName + このコマンドによって出力される設定ファイル (ZIP 圧縮形式) の保存先ファイル名を指定します。拡張子が指定されていない場合は自動的に ".zip" が付加されます。
+

 

+

6.3.77 "SstpEnable": Microsoft SSTP VPN 互換サーバー機能を有効化 / 無効化

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + SstpEnable
コマンドの概要 + Microsoft SSTP VPN 互換サーバー機能を有効化 / 無効化
説明 + PacketiX VPN Server には Microsoft 社の Windows Server 2008 / 2012 製品に搭載されている MS-SSTP VPN サーバー機能と互換性がある機能が搭載されています。Microsoft SSTP VPN 互換サーバー機能を有効にすると、Windows Vista / 7 / 8 / RT に標準搭載の MS-SSTP クライアントからこの VPN Server に接続できるようになります。

[ご注意]
VPN Server の SSL 証明書の CN の値がクライアント側で指定するホスト名と一致し、かつその証明書が信頼されている必要があります。詳しくは Microsoft 社のドキュメントを参照してください。
指定された CN の値を持つ新しい SSL 証明書 (自己署名証明書) を生成して VPN Server の現在の証明書と置換するためには、ServerCertRegenerate コマンドを使用してください。この場合は、当該証明書を SSTP VPN クライアントのコンピュータの信頼されるルート証明書として登録する必要があります。このような手間をかけたくない場合は、代わりに VeriSign や GlobalSign 社などの市販の証明書業者の SSL 証明書の取得を検討してください。

Microsoft SSTP VPN 互換サーバー機能で仮想 HUB に接続する場合のユーザー名の指定方法、およびデフォルト仮想 HUB の選択規則は、IPsec サーバー機能と同様です。詳しくは IPsecEnable コマンドのヘルプを参照してください。

このコマンドを実行するには、VPN Server の管理者権限が必要です。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + SstpEnable [yes|no]
"SstpEnable" コマンドで指定することができるパラメータ引数の一覧:
yes|no + Microsoft SSTP VPN 互換サーバー機能を有効にする場合は yes、無効にする場合は no を指定します。
+

 

+

6.3.78 "SstpGet": Microsoft SSTP VPN 互換サーバー機能の現在の設定を取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + SstpGet
コマンドの概要 + Microsoft SSTP VPN 互換サーバー機能の現在の設定を取得
説明 + 現在の Microsoft SSTP VPN 互換サーバー機能の設定を取得して表示します。

このコマンドを実行するには、VPN Server の管理者権限が必要です。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + SstpGet
"SstpGet" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.79 "ServerCertRegenerate": 指定された CN (Common Name) を持つ自己署名証明書を新たに作成し VPN Server に登録

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ServerCertRegenerate
コマンドの概要 + 指定された CN (Common Name) を持つ自己署名証明書を新たに作成し VPN Server に登録
説明 + PacketiX VPN Server の SSL-VPN 機能で提示されるサーバー証明書を、新たに作成する証明書に置き換えます。新たな証明書は自己署名証明書として生成され、CN (Common Name) の値を任意の文字列に設定することができます。

このコマンドは、Microsoft SSTP VPN 互換サーバー機能を使用しようとする場合に便利です。なぜならば、SSTP VPN クライアント (Windows Vista / 7 / 8 / RT に標準搭載) は接続先の VPN Server の提示する SSL 証明書の CN (Common Name) の値が接続先として指定されているホスト名文字列と完全に一致するかどうかを検証し、もし一致しない場合は接続をキャンセルするためです。
詳しくは SstpEnable コマンドのヘルプを参照してください。

このコマンドは、既存の VPN Server の SSL 証明書を削除します。ServerCertGet コマンドおよび ServerKeyGet コマンドを用いて、現在の証明書と秘密鍵をバックアップしておくことを推奨します。

このコマンドを実行するには、VPN Server の管理者権限が必要です。
このコマンドは、VPN Bridge では実行できません。
コマンドライン書式 + ServerCertRegenerate [CN]
"ServerCertRegenerate" コマンドで指定することができるパラメータ引数の一覧:
CN + 新たに生成する自己署名証明書の Common Name (CN) の値を指定します。
+

 

+

6.3.80 "VpnOverIcmpDnsEnable": VPN over ICMP / VPN over DNS サーバー機能を有効化 / 無効化

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + VpnOverIcmpDnsEnable
コマンドの概要 + VPN over ICMP / VPN over DNS サーバー機能を有効化 / 無効化
説明 + ファイアウォールやルータ等の故障や過負荷、設定ミス等により TCP/IP 通信ができない環境のネットワークからでも、ICMP (Ping) または DNS パケットの通信が可能であれば、VPN Server と VPN Client との間で VPN 通信を行うことができます。そのためには、予め VPN over ICMP / VPN over DNS サーバー機能を有効にしておく必要があります。

警告: この機能はファイアウォールやルータ等が一時的に不調となっており ICMP または DNS のみ安定した通信が可能な環境で VPN 通信を確立するための機能であ。緊急時などには有益ですが、長期間の利用には適しない場合があります。

接続元の VPN Client または VPN Bridge は内部バージョン 4.0 以降が必要です。

このコマンドを実行するには、VPN Server の管理者権限が必要です。
このコマンドは、VPN Bridge では実行できません。
コマンドライン書式 + VpnOverIcmpDnsEnable [/ICMP:yes|no] [/DNS:yes|no]
"VpnOverIcmpDnsEnable" コマンドで指定することができるパラメータ引数の一覧:
/ICMP + VPN over ICMP サーバーを有効にするには yes、無効にするには no を指定します。
/DNS + VPN over DNS サーバーを有効にするには yes、無効にするには no を指定します。
+

 

+

6.3.81 "VpnOverIcmpDnsGet": 現在の VPN over ICMP / VPN over DNS サーバー機能の設定を取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + VpnOverIcmpDnsGet
コマンドの概要 + 現在の VPN over ICMP / VPN over DNS サーバー機能の設定を取得
説明 + 現在の VPN over ICMP / VPN over DNS サーバー機能の設定を取得して表示します。

このコマンドを実行するには、VPN Server の管理者権限が必要です。
このコマンドは、VPN Bridge では実行できません。
コマンドライン書式 + VpnOverIcmpDnsGet
"VpnOverIcmpDnsGet" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.82 "DynamicDnsGetStatus": ダイナミック DNS 機能の現在の状態の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + DynamicDnsGetStatus
コマンドの概要 + ダイナミック DNS 機能の現在の状態の取得
説明 + ダイナミック DNS 機能の現在の状態を取得して表示します。

ダイナミック DNS による、VPN Server コンピュータに永続的な固有の DNS ホスト名が割当てられます。これにより独自でドメインを所有していなくても、VPN Client や VPN Bridge などの設定画面上が VPN Server の IP アドレスの代わりに DNS ホスト名によって VPN Server を指定することができます。
また、IP アドレスが変化する可能性がある一般的な ISP を用いて VPN Server をインターネットに接続する場合でも、IP アドレスが変化すれば自動的に DNS ホスト名対応する IP アドレスが更新されますので、可変 IP アドレスでも VPN Server を運用することができるようになります。
これにより、高価な月額料金が必要な固定グローバル IP アドレスのサービスを契約する必要がなくなります。

[注意]
ダイナミック DNS 機能を無効にするには、VPN Server の設定ファイルを編集します。
"declare root" ディレクティブ内に "declare DDnsClient" ディレクティブがあります。この中にある "bool Disable" の値を true に設定して VPN Server を再起動することにより、ダイナミック DNS 機能が無効になります。

このコマンドを実行するには、VPN Server の管理者権限が必要です。
このコマンドは、VPN Bridge では実行できません。
コマンドライン書式 + DynamicDnsGetStatus
"DynamicDnsGetStatus" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.83 "DynamicDnsSetHostname": ダイナミック DNS ホスト名の設定

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + DynamicDnsSetHostname
コマンドの概要 + ダイナミック DNS ホスト名の設定
説明 + ダイナミック DNS 機能で VPN Server が使用するホスト名を設定します。現在割当てられているホスト名は DynamicDnsGetStatus コマンドで確認できます。

ダイナミック DNS による、VPN Server コンピュータに永続的な固有の DNS ホスト名が割当てられます。これにより独自でドメインを所有していなくても、VPN Client や VPN Bridge などの設定画面上が VPN Server の IP アドレスの代わりに DNS ホスト名によって VPN Server を指定することができます。
また、IP アドレスが変化する可能性がある一般的な ISP を用いて VPN Server をインターネットに接続する場合でも、IP アドレスが変化すれば自動的に DNS ホスト名対応する IP アドレスが更新されますので、可変 IP アドレスでも VPN Server を運用することができるようになります。
これにより、高価な月額料金が必要な固定グローバル IP アドレスのサービスを契約する必要がなくなります。

[注意]
ダイナミック DNS 機能を無効にするには、VPN Server の設定ファイルを編集します。
"declare root" ディレクティブ内に "declare DDnsClient" ディレクティブがあります。この中にある "bool Disable" の値を true に設定して VPN Server を再起動することにより、ダイナミック DNS 機能が無効になります。

このコマンドを実行するには、VPN Server の管理者権限が必要です。
このコマンドは、VPN Bridge では実行できません。
コマンドライン書式 + DynamicDnsSetHostname [hostname]
"DynamicDnsSetHostname" コマンドで指定することができるパラメータ引数の一覧:
hostname + 新しいホスト名を 3 文字以上 31 文字以下の半角英数字およびハイフン '-' で指定します。変更は何度でも可能です。
+

 

+

6.3.84 "VpnAzureGetStatus": VPN Azure 機能の現在の状態の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + VpnAzureGetStatus
コマンドの概要 + VPN Azure 機能の現在の状態の取得
説明 + VPN Azure 機能の現在の状態を取得します。

VPN Azure により、会社のパソコンに自宅や外出先のパソコンから非常に簡単に VPN 接続できるようになります。VPN 接続中は会社のパソコンを経由して、社内 LAN の他のサーバーにもアクセスできます。
会社のパソコン (VPN Server) にはグローバル IP アドレスは不要です。ファイアウォールや NAT の内側であっても動作し、ネットワーク管理者による設定は一切必要ありません。VPN クライアントとなる自宅のパソコンでは、Windows に標準付属の SSTP VPN クライアントを使用できます。
VPN Azure は、PacketiX VPN Server をお使いの方はどなたでも無料で利用できるクラウド VPN サービスです。ソフトイーサ株式会社によって運営されています。使い方は http://www.vpnazure.net/ に掲載されています。

VPN Azure ホスト名はダイナミック DNS サービスのホスト名のドメイン部分を "vpnazure.net" に変更したものが使用されます。ホスト名を変更するには DynamicDnsSetHostname コマンドを使用してください。

このコマンドを実行するには、VPN Server の管理者権限が必要です。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + VpnAzureGetStatus
"VpnAzureGetStatus" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.3.85 "VpnAzureSetEnable": VPN Azure 機能の有効化 / 無効化

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + VpnAzureSetEnable
コマンドの概要 + VPN Azure 機能の有効化 / 無効化
説明 + VPN Azure 機能を有効または無効にします。

VPN Azure により、会社のパソコンに自宅や外出先のパソコンから非常に簡単に VPN 接続できるようになります。VPN 接続中は会社のパソコンを経由して、社内 LAN の他のサーバーにもアクセスできます。
会社のパソコン (VPN Server) にはグローバル IP アドレスは不要です。ファイアウォールや NAT の内側であっても動作し、ネットワーク管理者による設定は一切必要ありません。VPN クライアントとなる自宅のパソコンでは、Windows に標準付属の SSTP VPN クライアントを使用できます。
VPN Azure は、PacketiX VPN Server をお使いの方はどなたでも無料で利用できるクラウド VPN サービスです。ソフトイーサ株式会社によって運営されています。使い方は http://www.vpnazure.net/ に掲載されています。

VPN Azure ホスト名はダイナミック DNS サービスのホスト名のドメイン部分を "vpnazure.net" に変更したものが使用されます。ホスト名を変更するには DynamicDnsSetHostname コマンドを使用してください。

このコマンドを実行するには、VPN Server の管理者権限が必要です。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + VpnAzureSetEnable [yes|no]
"VpnAzureSetEnable" コマンドで指定することができるパラメータ引数の一覧:
yes|no + VPN Azure 機能を有効にするには yes、無効にするには no を指定します。
+

 

+ + + + + + + + + + +------ 2 ------ + + + + + + + + + +

6.4.1 "Online": 仮想 HUB をオンラインにする

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + Online
コマンドの概要 + 仮想 HUB をオンラインにする
説明 + 現在管理している仮想 HUB がオフラインになっている場合は、オンラインにします。オフライン状態の仮想 HUB は、クライアントからの VPN 接続を受け付けません。仮想 HUB をオンライン化することによって、その仮想 HUB はユーザーからの接続を受け付けたり、サービスを提供したりするようになります。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + Online
"Online" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.2 "Offline": 仮想 HUB をオフラインにする

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + Offline
コマンドの概要 + 仮想 HUB をオフラインにする
説明 + 現在管理している仮想 HUB がオンラインになっている場合は、オフラインにします。仮想 HUB に接続中のセッションがある場合は、すべて切断されます。オフライン状態の仮想 HUB は、クライアントからの VPN 接続を受け付けません。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + Offline
"Offline" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.3 "SetMaxSession": 仮想 HUB の最大同時接続セッション数を設定する

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + SetMaxSession
コマンドの概要 + 仮想 HUB の最大同時接続セッション数を設定する
説明 + 現在管理している仮想 HUB の、最大同時接続セッション数を設定します。最大同時接続セッション数を越えたセッションが、VPN Client や VPN Bridge から接続された場合、最大同時接続セッション数を上回った時点で、それ以上クライアントは接続できなくなります。この最大同時接続セッション数の制限には、ローカルブリッジ、仮想 NAT、カスケード接続などによって仮想 HUB 内に生成されるセッションは含まれません。
現在の最大同時接続セッション数の設定は、OptionsGet コマンドによって取得することができます。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + SetMaxSession [max_session]
"SetMaxSession" コマンドで指定することができるパラメータ引数の一覧:
max_session + 設定する最大同時接続セッション数を、整数で指定します。0 を指定すると、無制限になります。
+

 

+

6.4.4 "SetHubPassword": 仮想 HUB の管理パスワードを設定する

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + SetHubPassword
コマンドの概要 + 仮想 HUB の管理パスワードを設定する
説明 + 現在管理している仮想 HUB の、管理パスワードを設定します。仮想 HUB の管理パスワードが設定されている場合、その仮想 HUB に対して、VPN Server の接続ユーティリティから、仮想 HUB 管理モードでパスワードを指定して接続することができます。また、VPN Client や VPN Bridge などから、ユーザー名を "Administrator"、パスワードを仮想 HUB の管理者パスワードに指定して VPN 接続することも可能になります。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + SetHubPassword [password]
"SetHubPassword" コマンドで指定することができるパラメータ引数の一覧:
password + 設定するパスワードを指定します。パラメータでパスワードを指定しない場合は、パスワードを入力するプロンプトが表示されます。
+

 

+

6.4.5 "SetEnumAllow": 仮想 HUB の匿名ユーザーへの列挙の許可設定

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + SetEnumAllow
コマンドの概要 + 仮想 HUB の匿名ユーザーへの列挙の許可設定
説明 + 現在管理している仮想 HUB のオプション設定を変更し、匿名ユーザーに対して、この仮想 HUB を列挙するように設定します。このオプションを設定すると、VPN Client のユーザーは、この VPN Server のアドレスを入力するだけでこの仮想 HUB を列挙することが可能です。また、SetEnumDeny コマンドを使用すると、匿名ユーザーへの列挙を禁止することができます。仮想 HUB は、作成された時点では列挙が許可されています。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + SetEnumAllow
"SetEnumAllow" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.6 "SetEnumDeny": 仮想 HUB の匿名ユーザーへの列挙の禁止設定

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + SetEnumDeny
コマンドの概要 + 仮想 HUB の匿名ユーザーへの列挙の禁止設定
説明 + 現在管理している仮想 HUB のオプション設定を変更し、匿名ユーザーに対して、この仮想 HUB を列挙しないように設定します。このオプションを設定すると、VPN Client のユーザーが、VPN Server に対して仮想 HUB の列挙を要求した場合でも、この仮想 HUB は列挙されないようになります。また、SetEnumAllow コマンドを使用すると、匿名ユーザーへの列挙を許可することができます。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + SetEnumDeny
"SetEnumDeny" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.7 "OptionsGet": 仮想 HUB のオプション設定の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + OptionsGet
コマンドの概要 + 仮想 HUB のオプション設定の取得
説明 + 現在管理している仮想 HUB のオプション設定の一覧を取得します。仮想 HUB の列挙の許可 / 禁止の設定、最大同時接続数、オンライン / オフライン状態、およびクラスタリング環境における仮想 HUB の種類を取得することができます。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + OptionsGet
"OptionsGet" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.8 "RadiusServerSet": ユーザー認証に使用する RADIUS サーバーの設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + RadiusServerSet
コマンドの概要 + ユーザー認証に使用する RADIUS サーバーの設定
説明 + 現在管理している仮想 HUB に、ユーザーが RADIUS サーバー認証モードで接続した場合に、ユーザー名とパスワードを確認するための外部の RADIUS サーバーを指定します。
Radius サーバーは、この VPN Server の IP アドレスからの要求を受け付けるように設定しておく必要があります。また、Password Authentication Protocol (PAP) による認証が有効になっている必要があります。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + RadiusServerSet [server_name:port] [/SECRET:secret] [/RETRY_INTERVAL:interval]
"RadiusServerSet" コマンドで指定することができるパラメータ引数の一覧:
server_name:port + [ホスト名:ポート番号] の形式で、使用する RADIUS サーバーのホスト名、または IP アドレスと UDP ポート番号を指定します。ポート番号を省略した場合は、1812 が使用されます。
/SECRET + RADIUS サーバーとの間での通信に使用する共有シークレット (パスワード) を指定します。
+

 

+

6.4.9 "RadiusServerDelete": ユーザー認証に使用する RADIUS サーバー設定の削除

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + RadiusServerDelete
コマンドの概要 + ユーザー認証に使用する RADIUS サーバー設定の削除
説明 + 現在管理している仮想 HUB にユーザーが RADIUS サーバー認証モードで接続した場合に使用する RADIUS サーバーに関する設定を削除し、RADIUS 認証を使用できないようにします。現在の RADIUS サーバーに関する設定は、RadiusServerGet コマンドで取得することができます。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + RadiusServerDelete
"RadiusServerDelete" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.10 "RadiusServerGet": ユーザー認証に使用する RADIUS サーバー設定の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + RadiusServerGet
コマンドの概要 + ユーザー認証に使用する RADIUS サーバー設定の取得
説明 + 現在管理している仮想 HUB に、ユーザーが RADIUS サーバー認証モードで接続した場合に使用する RADIUS サーバーについての現在の設定を取得します。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + RadiusServerGet
"RadiusServerGet" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.11 "StatusGet": 仮想 HUB の現在の状況の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + StatusGet
コマンドの概要 + 仮想 HUB の現在の状況の取得
説明 + 現在管理している仮想 HUB の、現在の状況を取得します。仮想 HUB の種類やセッション数、各種オブジェクト数、ログイン回数、最終ログイン日時と最終通信日時、通信の統計データを取得することができます。
コマンドライン書式 + StatusGet
"StatusGet" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.12 "LogGet": 仮想 HUB のログ保存設定の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + LogGet
コマンドの概要 + 仮想 HUB のログ保存設定の取得
説明 + 現在管理している仮想 HUB の、ログ保存設定を取得します。セキュリティログとパケットログに関する保存設定や、保存対象などの設定情報が取得できます。
コマンドライン書式 + LogGet
"LogGet" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.13 "LogEnable": セキュリティログまたはパケットログの有効化

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + LogEnable
コマンドの概要 + セキュリティログまたはパケットログの有効化
説明 + 現在管理している仮想 HUB の、セキュリティログまたはパケットログを有効化します。
現在の設定は、LogGet コマンドで取得することができます。
コマンドライン書式 + LogEnable [security|packet]
"LogEnable" コマンドで指定することができるパラメータ引数の一覧:
security|packet + 有効化するログの種類を選択します。"security" または "packet" のいずれかを指定します。
+

 

+

6.4.14 "LogDisable": セキュリティログまたはパケットログの無効化

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + LogDisable
コマンドの概要 + セキュリティログまたはパケットログの無効化
説明 + 現在管理している仮想 HUB の、セキュリティログまたはパケットログを無効化します。
現在の設定は、LogGet コマンドで取得することができます。
コマンドライン書式 + LogDisable [security|packet]
"LogDisable" コマンドで指定することができるパラメータ引数の一覧:
security|packet + 無効化するログの種類を選択します。"security" または "packet" のいずれかを指定します。
+

 

+

6.4.15 "LogSwitchSet": ログファイルの切り替え周期の設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + LogSwitchSet
コマンドの概要 + ログファイルの切り替え周期の設定
説明 + 現在管理している仮想 HUB が保存する、セキュリティログまたはパケットログのログファイルの切り替え周期を設定します。ログファイルの切り替え周期は、1 秒単位、1 分単位、1 時間単位、1 日単位、1 ヶ月単位、または切り替えを行わないように変更することができます。
現在の設定は、LogGet コマンドで取得することができます。
コマンドライン書式 + LogSwitchSet [security|packet] [/SWITCH:sec|min|hour|day|month|none]
"LogSwitchSet" コマンドで指定することができるパラメータ引数の一覧:
security|packet + 設定を変更するログの種類を選択します。"security" または "packet" のいずれかを指定します。
/SWITCH + 設定する切り替え周期を選択します。sec、min、hour、day、month、none から指定します。
+

 

+

6.4.16 "LogPacketSaveType": パケットログに保存するパケットの種類と保存内容の設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + LogPacketSaveType
コマンドの概要 + パケットログに保存するパケットの種類と保存内容の設定
説明 + 現在管理している仮想 HUB で保存する、パケットログの保存内容を、パケットの種類ごとに設定します。パケットの種類には、[TCP コネクションログ]、[TCP パケットログ]、[DHCP パケットログ]、[UDP パケットログ]、[ICMP パケットログ]、[IP パケットログ]、[ARP パケットログ]、[Ethernet パケットログ] があります。
現在の設定は、LogGet コマンドで取得することができます。
コマンドライン書式 + LogPacketSaveType [/TYPE:tcpconn|tcpdata|dhcp|udp|icmp|ip|arp|ether] [/SAVE:none|header|full]
"LogPacketSaveType" コマンドで指定することができるパラメータ引数の一覧:
/TYPE + 保存内容の変更対称のパケットの種類を、tcpconn、tcpdata、dhcp、udp、icmp、ip、arp、ether の中から指定します。
/SAVE + パケットログの保存内容を指定します。 +none : 保存無し +header: ヘッダ情報のみ +full : パケット内容すべて +のいずれかを指定します。
+

 

+

6.4.17 "CAList": 信頼する証明機関の証明書一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CAList
コマンドの概要 + 信頼する証明機関の証明書一覧の取得
説明 + 現在管理している仮想 HUB が信頼する証明機関の証明書を管理します。登録されている証明機関の証明書一覧は、VPN Client が署名済み証明書認証モードで接続してきた際の証明書の検証に使用されます。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CAList
"CAList" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.18 "CAAdd": 信頼する証明機関の証明書の追加

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CAAdd
コマンドの概要 + 信頼する証明機関の証明書の追加
説明 + 現在管理している仮想 HUB が信頼する証明機関の証明書一覧に、新しい証明書を追加します。登録されている証明機関の証明書一覧は、VPN Client が、署名済み証明書認証モードで接続してきた際の証明書の検証に使用されます。
現在の証明書一覧を取得するには、CAList コマンドを使用します。
証明書を追加するには、その証明書が X.509 形式のファイルとして保存されている必要があります。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CAAdd [path]
"CAAdd" コマンドで指定することができるパラメータ引数の一覧:
path + 登録する X.509 証明書ファイル名を指定します。
+

 

+

6.4.19 "CADelete": 信頼する証明機関の証明書の削除

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CADelete
コマンドの概要 + 信頼する証明機関の証明書の削除
説明 + 現在管理している仮想 HUB が信頼する証明機関の証明書一覧から、既存の証明書を削除します。
現在の証明書一覧を取得するには、CAList コマンドを使用します。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CADelete [id]
"CADelete" コマンドで指定することができるパラメータ引数の一覧:
id + 削除する証明書の ID を指定します。
+

 

+

6.4.20 "CAGet": 信頼する証明機関の証明書の取得

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CAGet
コマンドの概要 + 信頼する証明機関の証明書の取得
説明 + 現在管理している仮想 HUB が信頼する証明機関の証明書一覧内の既存の証明書を取得し、X.509 形式のファイルとして保存します。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CAGet [id] [/SAVECERT:path]
"CAGet" コマンドで指定することができるパラメータ引数の一覧:
id + 取得する証明書の ID を指定します。
/SAVECERT + 取得した証明書を保存するファイル名を指定します。
+

 

+

6.4.21 "CascadeList": カスケード接続一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeList
コマンドの概要 + カスケード接続一覧の取得
説明 + 現在管理している仮想 HUB に登録されているカスケード接続の一覧を取得します。
カスケード接続を使用すると、この仮想 HUB を同一または別のコンピュータ上で動作している他の仮想 HUB に、レイヤ 2 カスケード接続することができます。

[カスケード接続における警告]
カスケード接続を使用すると、複数の仮想 HUB 間でのレイヤ 2 ブリッジが可能ですが、接続方法を間違えると、ループ状のカスケード接続を作成してしまう場合があります。カスケード接続機能を使用する際には、慎重にネットワークトポロジを設計してください。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeList
"CascadeList" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.22 "CascadeCreate": 新しいカスケード接続の作成

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeCreate
コマンドの概要 + 新しいカスケード接続の作成
説明 + 現在管理している仮想 HUB に、新しいカスケード接続を作成します。
カスケード接続を使用すると、この仮想 HUB を同一または別のコンピュータ上で動作している他の仮想 HUB にカスケード接続することができます。
カスケード接続を作成するには、初期パラメータとして、カスケード接続の名前と接続先のサーバーおよび接続先の仮想 HUB、ユーザー名を指定する必要があります。新しいカスケード接続を作成した場合、ユーザー認証の種類は [匿名認証] に初期設定され、プロキシサーバーの設定とサーバー証明書の検証オプションは設定されません。これらの設定やその他の詳細設定を変更するには、カスケード接続を作成した後に "Cascade" という名前で始まる他のコマンドを使用します。

[カスケード接続における警告]
カスケード接続を使用すると、複数の仮想 HUB 間でのレイヤ 2 ブリッジが可能ですが、接続方法を間違えると、ループ状のカスケード接続を作成してしまう場合があります。カスケード接続機能を使用する際には、慎重にネットワークトポロジを設計してください。

このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeCreate [name] [/SERVER:hostname:port] [/HUB:hubname] [/USERNAME:username]
"CascadeCreate" コマンドで指定することができるパラメータ引数の一覧:
name + 作成するカスケード接続の名前を指定します。
/SERVER + [ホスト名:ポート番号] の形式で、接続先の VPN Server のホスト名とポート番号を指定します。IP アドレスで指定することもできます。
/HUB + 接続先の VPN Server 内の仮想 HUB を指定します。
/USERNAME + 接続先の VPN Server に接続する際のユーザー認証で使用するユーザー名を指定します。
+

 

+

6.4.23 "CascadeSet": カスケード接続の接続先の設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeSet
コマンドの概要 + カスケード接続の接続先の設定
説明 + 現在管理している仮想 HUB に登録されているカスケード接続の、接続先の VPN Server のホスト名とポート番号、仮想 HUB 名、および接続に使用するユーザー名を設定します。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeSet [name] [/SERVER:hostname:port] [/HUB:hubname]
"CascadeSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するカスケード接続の名前を指定します。
/SERVER + [ホスト名:ポート番号] の形式で、接続先の VPN Server のホスト名とポート番号を指定します。IP アドレスで指定することもできます。
/HUB + 接続先の VPN Server 内の仮想 HUB を指定します。
+

 

+

6.4.24 "CascadeGet": カスケード接続の設定の取得

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeGet
コマンドの概要 + カスケード接続の設定の取得
説明 + 現在管理している仮想 HUB に登録されているカスケード接続の接続設定内容を取得します。
なお、カスケード接続の接続設定内容を変更するには、カスケード接続を作成した後に "Cascade" という名前で始まる、他のコマンドを使用します。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeGet [name]
"CascadeGet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を取得するカスケード接続の名前を指定します。
+

 

+

6.4.25 "CascadeDelete": カスケード接続の削除

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeDelete
コマンドの概要 + カスケード接続の削除
説明 + 現在管理している仮想 HUB に登録されているカスケード接続を削除します。指定されたカスケード接続がオンライン状態である場合は、自動的に接続を切断してから削除します。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeDelete [name]
"CascadeDelete" コマンドで指定することができるパラメータ引数の一覧:
name + 削除するカスケード接続の名前を指定します。
+

 

+

6.4.26 "CascadeUsernameSet": カスケード接続の接続に使用するユーザー名の設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeUsernameSet
コマンドの概要 + カスケード接続の接続に使用するユーザー名の設定
説明 + 現在管理している仮想 HUB に登録されているカスケード接続を指定し、そのカスケード接続が VPN Server に接続する際の、ユーザー認証に必要なユーザー名を指定します。
なお、ユーザー認証の種類を指定したり、必要なパラメータを指定したりする必要がある場合があります。これらの情報を変更するには、CascadeAnonymousSet、CascadePasswordSet、CascadeCertSet などのコマンドを使用します。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeUsernameSet [name] [/USERNAME:username]
"CascadeUsernameSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するカスケード接続の名前を指定します。
/USERNAME + カスケード接続が VPN Server に接続する際の、ユーザー認証に必要なユーザー名を指定します。
+

 

+

6.4.27 "CascadeAnonymousSet": カスケード接続のユーザー認証の種類を匿名認証に設定

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeAnonymousSet
コマンドの概要 + カスケード接続のユーザー認証の種類を匿名認証に設定
説明 + 現在管理している仮想 HUB に登録されているカスケード接続を指定し、そのカスケード接続が VPN Server に接続する際の、ユーザー認証の方法を [匿名認証] に設定します。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeAnonymousSet [name]
"CascadeAnonymousSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するカスケード接続の名前を指定します。
+

 

+

6.4.28 "CascadePasswordSet": カスケード接続のユーザー認証の種類をパスワード認証に設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadePasswordSet
コマンドの概要 + カスケード接続のユーザー認証の種類をパスワード認証に設定
説明 + 現在管理している仮想 HUB に登録されているカスケード接続を指定し、そのカスケード接続が VPN Server に接続する際のユーザー認証の方法を [パスワード認証] に設定します。パスワード認証の種類には、[標準パスワード認証] と [RADIUS または NT ドメイン認証] を指定します。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadePasswordSet [name] [/PASSWORD:password] [/TYPE:standard|radius]
"CascadePasswordSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するカスケード接続の名前を指定します。
/PASSWORD + パスワード認証で使用するパスワードを指定します。指定しない場合は、パスワードを入力するためのプロンプトが表示されます。
/TYPE + パスワード認証の種類として、"standard" (標準パスワード認証)、または "radius" (RADIUS または NT ドメイン認証) のどちらかを指定します。
+

 

+

6.4.29 "CascadeCertSet": カスケード接続のユーザー認証の種類をクライアント証明書認証に設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeCertSet
コマンドの概要 + カスケード接続のユーザー認証の種類をクライアント証明書認証に設定
説明 + 現在管理している仮想 HUB に登録されているカスケード接続を指定し、そのカスケード接続が VPN Server に接続する際のユーザー認証の方法を [クライアント証明書認証] に設定します。証明書としては、X.509 形式の証明書ファイルと、Base 64 でエンコードされた対応した秘密鍵ファイルを指定する必要があります。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeCertSet [name] [/LOADCERT:cert] [/LOADKEY:key]
"CascadeCertSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するカスケード接続の名前を指定します。
/LOADCERT + 証明書認証で提示する X.509 形式の証明書ファイル名を指定します。
/LOADKEY + 証明書に対応した Base 64 形式でエンコードされた秘密鍵ファイル名を指定します。
+

 

+

6.4.30 "CascadeCertGet": カスケード接続に用いるクライアント証明書の取得

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeCertGet
コマンドの概要 + カスケード接続に用いるクライアント証明書の取得
説明 + 現在管理している仮想 HUB に登録されているカスケード接続を指定し、そのカスケード接続がクライアント証明書認証を使用する場合は、クライアント証明書として提示する証明書を取得して、証明書ファイルを X.509 形式で保存します。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeCertGet [name] [/SAVECERT:cert]
"CascadeCertGet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を取得するカスケード接続の名前を指定します。
/SAVECERT + 取得した証明書を X.509 形式で保存するファイル名を指定します。
+

 

+

6.4.31 "CascadeEncryptEnable": カスケード接続の通信時の暗号化の有効化

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeEncryptEnable
コマンドの概要 + カスケード接続の通信時の暗号化の有効化
説明 + 現在管理している仮想 HUB に登録されているカスケード接続を指定し、そのカスケード接続が VPN Server との間で VPN 接続を行なって通信をする際に、VPN Server との間の通信内容を SSL で暗号化するように設定します。
通常は、VPN Server との間の通信を SSL で暗号化して、情報の盗聴や改ざんを防止します。暗号化を無効にすることもできます。暗号化を無効にすると、通信のスループットが向上しますが、通信データは平文でネットワーク上を流れます。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeEncryptEnable [name]
"CascadeEncryptEnable" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するカスケード接続の名前を指定します。
+

 

+

6.4.32 "CascadeEncryptDisable": カスケード接続の通信時の暗号化の無効化

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeEncryptDisable
コマンドの概要 + カスケード接続の通信時の暗号化の無効化
説明 + 現在管理している仮想 HUB に登録されているカスケード接続を指定し、そのカスケード接続が VPN Server との間で VPN 接続を行なって通信をする際に VPN Server との間の通信内容を暗号化しないように設定します。
通常は、VPN Server との間の通信を SSL で暗号化して、情報の盗聴や改ざんを防止します。暗号化を無効にすることもできます。暗号化を無効にすると、通信のスループットが向上しますが、通信データは平文でネットワーク上を流れます。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeEncryptDisable [name]
"CascadeEncryptDisable" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するカスケード接続の名前を指定します。
+

 

+

6.4.33 "CascadeCompressEnable": カスケード接続の通信時のデータ圧縮の有効化

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeCompressEnable
コマンドの概要 + カスケード接続の通信時のデータ圧縮の有効化
説明 + 現在管理している仮想 HUB に登録されているカスケード接続を指定し、そのカスケード接続が VPN Server との間で VPN 接続を行なって通信をする際に、VPN Server との間の通信内容を圧縮するように設定します。
最大で約 80 % 程度の圧縮を行うことができます。ただし、圧縮を行うと、クライアントおよびサーバーの両方で CPU 負荷が高くなります。回線速度が約 10 Mbps 以上の場合は、圧縮を行うとスループットが低下し、逆効果となる場合があります。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeCompressEnable [name]
"CascadeCompressEnable" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するカスケード接続の名前を指定します。
+

 

+

6.4.34 "CascadeCompressDisable": カスケード接続の通信時のデータ圧縮の無効化

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeCompressDisable
コマンドの概要 + カスケード接続の通信時のデータ圧縮の無効化
説明 + 現在管理している仮想 HUB に登録されているカスケード接続を指定し、そのカスケード接続が VPN Server との間で VPN 接続を行なって通信をする際に、VPN Server との間の通信内容を圧縮しないように設定します。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeCompressDisable [name]
"CascadeCompressDisable" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するカスケード接続の名前を指定します。
+

 

+

6.4.35 "CascadeProxyNone": カスケード接続の接続方法を直接 TCP/IP 接続に設定

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeProxyNone
コマンドの概要 + カスケード接続の接続方法を直接 TCP/IP 接続に設定
説明 + 現在管理している仮想 HUB に登録されているカスケード接続を指定し、そのカスケード接続が VPN Server に対して接続する際に、使用する接続方法を [直接 TCP/IP 接続] に設定し、プロキシサーバーを経由しないようにします。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeProxyNone [name]
"CascadeProxyNone" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するカスケード接続の名前を指定します。
+

 

+

6.4.36 "CascadeProxyHttp": カスケード接続の接続方法を HTTP プロキシサーバー経由接続に設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeProxyHttp
コマンドの概要 + カスケード接続の接続方法を HTTP プロキシサーバー経由接続に設定
説明 + 現在管理している仮想 HUB に登録されているカスケード接続を指定し、そのカスケード接続が VPN Server に対して接続する際に、使用する接続方法を [HTTP プロキシサーバー経由接続] に設定し、経由する HTTP プロキシサーバーのホスト名とポート番号、ユーザー名とパスワード (必要な場合) を指定します。
経由する HTTP サーバーは、HTTPS 通信をするための CONNECT メソッドに対応している必要があります。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeProxyHttp [name] [/SERVER:hostname:port] [/USERNAME:username] [/PASSWORD:password]
"CascadeProxyHttp" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するカスケード接続の名前を指定します。
/SERVER + [ホスト名:ポート番号] の形式で、経由する HTTP プロキシサーバーのホスト名、または IP アドレスとポート番号を指定します。
/USERNAME + 経由する HTTP プロキシサーバーに接続するためにユーザー認証が必要な場合、ユーザー名を指定します。また、同時に /PASSWORD パラメータも指定します。/USERNAME と /PASSWORD パラメータが指定されない場合は、ユーザー認証データを設定しません。
/PASSWORD + 経由する HTTP プロキシサーバーに接続するためにユーザー認証が必要な場合、パスワードを指定します。/USERNAME パラメータと共に指定します。
+

 

+

6.4.37 "CascadeProxySocks": カスケード接続の接続方法を SOCKS プロキシサーバー経由接続に設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeProxySocks
コマンドの概要 + カスケード接続の接続方法を SOCKS プロキシサーバー経由接続に設定
説明 + 現在管理している仮想 HUB に登録されているカスケード接続を指定し、そのカスケード接続が VPN Server に対して接続する際に、使用する接続方法を [SOCKS プロキシサーバー経由接続] に設定し、経由する SOCKS プロキシサーバーのホスト名とポート番号、ユーザー名とパスワード (必要な場合) を指定します。
経由する SOCKS サーバーは、SOCKS バージョン 4 に対応している必要があります。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeProxySocks [name] [/SERVER:hostname:port] [/USERNAME:username] [/PASSWORD:password]
"CascadeProxySocks" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するカスケード接続の名前を指定します。
/SERVER + [ホスト名:ポート番号] の形式で、経由する SOCKS プロキシサーバーのホスト名、または IP アドレスとポート番号を指定します。
/USERNAME + 経由する SOCKS プロキシサーバーに接続するためにユーザー認証が必要な場合、ユーザー名を指定します。また、同時に /PASSWORD パラメータも指定します。/USERNAME と /PASSWORD パラメータが指定されない場合は、ユーザー認証データを設定しません。
/PASSWORD + 経由する SOCKS プロキシサーバーに接続するためにユーザー認証が必要な場合、パスワードを指定します。/USERNAME パラメータと共に指定します。
+

 

+

6.4.38 "CascadeServerCertEnable": カスケード接続のサーバー証明書の検証オプションの有効化

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeServerCertEnable
コマンドの概要 + カスケード接続のサーバー証明書の検証オプションの有効化
説明 + 現在管理している仮想 HUB に登録されているカスケード接続を指定し、そのカスケード接続が VPN Server に対して接続する際に、接続先の VPN Server の提示する SSL 証明書が信頼できるかどうか検査するオプションを有効にします。
このオプションが有効になっている場合、接続先サーバーの SSL 証明書をあらかじめ CascadeServerCertSet コマンドでカスケード接続設定内に保存しておくか、または仮想 HUB の信頼する証明機関の証明書一覧に、サーバーの SSL 証明書を署名したルート証明書を CAAdd コマンドなどで登録しておく必要があります。
カスケード接続の、サーバー証明書の検証オプションが有効になっている状態で接続した VPN Server の証明書が信頼できない場合、直ちに接続を解除して再試行を繰り返します。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeServerCertEnable [name]
"CascadeServerCertEnable" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するカスケード接続の名前を指定します。
+

 

+

6.4.39 "CascadeServerCertDisable": カスケード接続のサーバー証明書の検証オプションの無効化

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeServerCertDisable
コマンドの概要 + カスケード接続のサーバー証明書の検証オプションの無効化
説明 + 現在管理している仮想 HUB に登録されているカスケード接続を指定し、そのカスケード接続が VPN Server に対して接続する際に、接続先の VPN Server の提示する SSL 証明書が、信頼できるかどうか検査するオプションを無効にします。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeServerCertDisable [name]
"CascadeServerCertDisable" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するカスケード接続の名前を指定します。
+

 

+

6.4.40 "CascadeServerCertSet": カスケード接続のサーバー固有証明書の設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeServerCertSet
コマンドの概要 + カスケード接続のサーバー固有証明書の設定
説明 + 現在管理している仮想 HUB に登録されているカスケード接続を指定し、そのカスケード接続が VPN Server に対して接続する際に、接続先の VPN Server の提示する SSL 証明書と同じ証明書をあらかじめ登録します。
カスケード接続の、サーバー証明書の検証オプションが有効になっている場合、接続先サーバーの SSL 証明書を、あらかじめこのコマンドでカスケード接続設定内に保存しておくか、または仮想 HUB の信頼する証明機関の証明書一覧に、サーバーの SSL 証明書を署名したルート証明書を CAAdd コマンドなどで登録しておく必要があります。
カスケード接続の、サーバー証明書の検証オプションが有効になっている状態で接続した VPN Server の証明書が信頼できない場合、直ちに接続を解除して再試行を繰り返します。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeServerCertSet [name] [/LOADCERT:cert]
"CascadeServerCertSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するカスケード接続の名前を指定します。
/LOADCERT + 設定するサーバー固有証明書が保存されている X.509 形式の証明書ファイル名を指定します。
+

 

+

6.4.41 "CascadeServerCertDelete": カスケード接続のサーバー固有証明書の削除

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeServerCertDelete
コマンドの概要 + カスケード接続のサーバー固有証明書の削除
説明 + 現在管理している仮想 HUB に登録されているカスケード接続を指定し、そのカスケード接続にサーバー固有証明書が登録されている場合は、それを削除します。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeServerCertDelete [name]
"CascadeServerCertDelete" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するカスケード接続の名前を指定します。
+

 

+

6.4.42 "CascadeServerCertGet": カスケード接続のサーバー固有証明書の取得

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeServerCertGet
コマンドの概要 + カスケード接続のサーバー固有証明書の取得
説明 + 現在管理している仮想 HUB に登録されているカスケード接続を指定し、そのカスケード接続にサーバー固有証明書が登録されている場合は、その証明書を取得して、X.509 形式の証明書ファイルとして保存します。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeServerCertGet [name] [/SAVECERT:path]
"CascadeServerCertGet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するカスケード接続の名前を指定します。
/SAVECERT + サーバー固有証明書を X.509 形式で保存する証明書ファイル名を指定します。
+

 

+

6.4.43 "CascadeDetailSet": カスケード接続の高度な通信設定の設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeDetailSet
コマンドの概要 + カスケード接続の高度な通信設定の設定
説明 + 現在管理している仮想 HUB に登録されているカスケード接続を指定し、そのカスケード接続が VPN Server と通信する際に使用される、VPN プロトコルの通信設定をカスタマイズします。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeDetailSet [name] [/MAXTCP:max_connection] [/INTERVAL:interval] [/TTL:disconnect_span] [/HALF:yes|no] [/NOQOS:yes|no]
"CascadeDetailSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するカスケード接続の名前を指定します。
/MAXTCP + VPN 通信に使用する TCP コネクション数を、1 以上 32 以下の整数で指定します。VPN Server との間の VPN 通信セッションにおけるデータ伝送に、複数本の TCP コネクションを束ねて使用することにより、通信速度を向上できる場合があります。 +注意: サーバーへの接続回線が高速な場合は 8 本程度を、ダイヤルアップ等の低速な場合は 1 本をお勧めします。
/INTERVAL + 複数の TCP コネクションを確立して VPN 通信を行うとき、各 TCP コネクションの確立間隔を秒単位で指定します。規定値は 1 秒です。
/TTL + 各 TCP コネクションの寿命を設定する場合は、TCP コネクションが確立されてから切断されるまでの寿命を、秒数で指定します。0 を指定すると、寿命は設定されません。
/HALF + 半二重モードを有効にする場合は "yes" を指定します。2 本以上の TCP コネクションを束ねて VPN 通信を行う際、「半二重モード」を使用することができます。半二重モードを有効にすると、自動的に各 TCP コネクションのデータ伝送方向を半数ずつ固定することができます。たとえば、8 本の TCP コネクションを使用して VPN セッションを確立した場合、半二重モードを有効にすると、4 本の TCP コネクションはアップロード方向専用、残りの 4 本のコネクションはダウンロード方向専用に固定され通信が行われます。
/NOQOS + VoIP / QoS 対応機能を無効にする場合は "yes" を指定します。通常は "no" を指定します。
+

 

+

6.4.44 "CascadePolicySet": カスケード接続セッションのセキュリティポリシーの設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadePolicySet
コマンドの概要 + カスケード接続セッションのセキュリティポリシーの設定
説明 + 現在管理している仮想 HUB に登録されているカスケード接続を指定し、そのカスケード接続が確立した際に、仮想 HUB で生成されるセッションに適用するセキュリティポリシーの内容を変更します。
仮想 HUB が別の VPN Server にカスケード接続すると、カスケード接続元の仮想 HUB には「カスケードセッション」が新しく生成されます。そのカスケードセッションに設定するセキュリティポリシーの内容を、このコマンドで設定することができます。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + [name] [/NAME:policy_name] [/VALUE:num|yes|no]
"CascadePolicySet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するカスケード接続の名前を指定します。
/NAME + 値を変更するポリシーの名前を指定します。ポリシーの名前と、設定できる値の一覧は PolicyList コマンドで表示することができます。
/VALUE + ポリシーの新しい値を指定します。そのポリシーが数値型の場合は整数を指定します。ブール型の場合は yes または no を指定します。設定できる型と値は PolicyList コマンドで表示することができます。
+

 

+

6.4.45 "PolicyList": セキュリティポリシーの種類と設定可能値の一覧を表示

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + PolicyList
コマンドの概要 + セキュリティポリシーの種類と設定可能値の一覧を表示
説明 + VPN Server のユーザーやグループ、カスケード接続に対して設定することができるセキュリティポリシー内の項目の名前、説明、および設定できる値の一覧を表示します。
PolicyList コマンドに何も引数を指定せずに起動すると、サポートされているすべてのセキュリティポリシーの名前と説明の一覧が表示されます。
PolicyList コマンドの引数で名前を指定すると、その値に関する詳細な説明と、設定できる値の型および範囲が表示されます。
コマンドライン書式 + PolicyList [name]
"PolicyList" コマンドで指定することができるパラメータ引数の一覧:
name + 説明を表示するポリシー名を指定します。指定しない場合は、サポートされているすべてのセキュリティポリシーの名前と、説明の一覧が表示されます。
+

 

+

6.4.46 "CascadeStatusGet": カスケード接続の現在の状態の取得

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeStatusGet
コマンドの概要 + カスケード接続の現在の状態の取得
説明 + 現在管理している仮想 HUB に登録されているカスケード接続を指定し、そのカスケード接続が現在オンラインである場合は、その接続状態やその他の情報を取得します。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeStatusGet [name]
"CascadeStatusGet" コマンドで指定することができるパラメータ引数の一覧:
name + 情報を取得するカスケード接続の名前を指定します。
+

 

+

6.4.47 "CascadeRename": カスケード接続の名前の変更

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeRename
コマンドの概要 + カスケード接続の名前の変更
説明 + 現在管理している仮想 HUB に登録されているカスケード接続を指定し、そのカスケード接続の名前を変更します。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeRename [name] [/NEW:new_name]
"CascadeRename" コマンドで指定することができるパラメータ引数の一覧:
name + 名前を変更するカスケード接続の現在の名前を指定します。
/NEW + 変更後の新しい名前を指定します。
+

 

+

6.4.48 "CascadeOnline": カスケード接続のオンライン状態への設定

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeOnline
コマンドの概要 + カスケード接続のオンライン状態への設定
説明 + 現在管理している仮想 HUB に登録されているカスケード接続を指定し、そのカスケード接続をオンライン化します。オンライン状態になったカスケード接続は、接続設定に従って、接続先の VPN Server への接続処理を開始します。オンライン状態になったカスケード接続は、CascadeOffline コマンドでオフライン状態に設定するまで、VPN Server に常時接続または接続を試行し続けます。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeOnline [name]
"CascadeOnline" コマンドで指定することができるパラメータ引数の一覧:
name + オンライン状態にするカスケード接続の名前を指定します。
+

 

+

6.4.49 "CascadeOffline": カスケード接続のオフライン状態への設定

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CascadeOffline
コマンドの概要 + カスケード接続のオフライン状態への設定
説明 + 現在管理している仮想 HUB に登録されているカスケード接続を指定し、そのカスケード接続をオフライン化します。オフライン化されたカスケード接続は、次に CascadeOnline コマンドでオンライン状態に設定するまで VPN Server に対して接続しません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CascadeOffline [name]
"CascadeOffline" コマンドで指定することができるパラメータ引数の一覧:
name + オフライン状態にするカスケード接続の名前を指定します。
+

 

+

6.4.50 "AccessAdd": アクセスリストへのルールの追加 (IPv4)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccessAdd
コマンドの概要 + アクセスリストへのルールの追加 (IPv4)
説明 + 現在管理している仮想 HUB のアクセスリストに、新しいルールを追加します。
アクセスリストとは、仮想 HUB 内を流れるパケットに対して適用されるパケットフィルタルールの集合です。アクセスリストには複数のルールを登録することができ、各ルールごとに優先順位を定義することができます。すべてのパケットは、アクセスリストに登録されているルールで指定された条件に、最初に一致したルールで規定されている動作で、通過または破棄が決定されます。どのルールの条件にも一致しなかったパケットは、暗黙で通過を許可されます。なお、AccessAddEx コマンドを使用することで、通過時に遅延・ジッタ・パケットロスを発生させることもできます。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + AccessAdd [pass|discard] [/MEMO:memo] [/PRIORITY:priority] [/SRCUSERNAME:username] [/DESTUSERNAME:username] [/SRCMAC:mac/mask] [/DESTMAC:mac/mask] [/SRCIP:ip/mask] [/DESTIP:ip/mask] [/PROTOCOL:tcp|udp|icmpv4|icmpv6|ip|num] [/SRCPORT:start-end] [/DESTPORT:start-end] [/TCPSTATE:established|unestablished]
"AccessAdd" コマンドで指定することができるパラメータ引数の一覧:
pass|discard + パケットが、このルールの条件に一致した場合の動作を決定します。pass を指定すると [通過] を、discard を指定すると [破棄] を意味します。
/MEMO + ルールの説明 (メモ) を指定します。
/PRIORITY + ルールの優先順位を 1 以上の整数で指定します。優先順位は小さいものほど優先度が高くなります。
/SRCUSERNAME + ルールの条件として、指定された名前のユーザーまたはグループのセッションによって送信されたパケットのみに、このルールを適用することができます。その場合は、ユーザー名またはグループ名を指定します。
/DESTUSERNAME + ルールの条件として、指定された名前のユーザーまたはグループのユーザーのセッションが受信するパケットのみに、このルールを適用することができます。その場合は、ユーザー名またはグループ名を指定します。
/SRCMAC + ルールの条件として、送信元 MAC アドレスを指定します。MAC アドレスは 00-AC-84-EA-33-BC/FF-FF-FF-FF-FF-00 のように 16 進数と "-" か ":" の区切り文字を使用して指定します。区切り文字は省略できます。
/DESTMAC + ルールの条件として、宛先 MAC アドレスを指定します。指定方法は、/SRCMAC パラメータと同様です。
/SRCIP + ルールの条件として、送信元 IPv4 アドレスを "IPアドレス/マスク" の形式で指定します。IP アドレスは 192.168.0.1 のように 10 進数をドットで区切って指定します。マスクは 255.255.255.0 のように 10 進数をドットで区切って指定するか、24 のように先頭からのビット長を 10 進数で指定できます。0.0.0.0/0.0.0.0 を指定すると、すべてのホストを示します。
/DESTIP + ルールの条件として、宛先 IPv4 アドレスを "IPアドレス/マスク" の形式で指定します。指定方法は /SRCIP パラメータと同様です。
/PROTOCOL + ルールの条件として、プロトコルの種類を指定します。IP プロトコル番号を 10 進数で入力するか、"tcp" (TCP/IP プロトコル、6 番)、"udp" (UDP/IP プロトコル、17番)、"icmpv4" (ICMPv4 プロトコル、1 番)、"icmpv6" (ICMPv6 プロトコル、58 番)、"ip" (すべての IP プロトコル、0 番) のキーワードを指定します。すべての IP プロトコルを対象とするには 0 を指定します。
/SRCPORT + プロトコルが TCP/IP または UDP/IP の場合は、ルールの条件として、送信元ポート番号を指定します。それ以外のプロトコルの場合は無視されます。このパラメータを指定しない場合は、すべてのポート番号が対象となります。指定方法は、"1-1024" (1 番以上 1024 番以下)、"23" (23 番のみ) などのように指定します。
/DESTPORT + プロトコルが TCP/IP または UDP/IP の場合は、ルールの条件として、宛先ポート番号を指定します。それ以外のプロトコルの場合は無視されます。指定方法は /SRCPORT パラメータと同様です。
/TCPSTATE + ルールの条件として、TCP コネクションの状態を指定します。 Established または Unestablished を指定します。
+

 

+

6.4.51 "AccessAddEx": アクセスリストへのルールの追加 (IPv4, 遅延・ジッタ・パケットロス設定可能)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccessAddEx
コマンドの概要 + アクセスリストへのルールの追加 (IPv4, 遅延・ジッタ・パケットロス設定可能)
説明 + 現在管理している仮想 HUB のアクセスリストに、新しいルールを追加します。通過時に遅延・ジッタ・パケットロスを発生させることができます。
アクセスリストとは、仮想 HUB 内を流れるパケットに対して適用されるパケットフィルタルールの集合です。アクセスリストには複数のルールを登録することができ、各ルールごとに優先順位を定義することができます。すべてのパケットは、アクセスリストに登録されているルールで指定された条件に、最初に一致したルールで規定されている動作で、通過または破棄が決定されます。どのルールの条件にも一致しなかったパケットは、暗黙で通過を許可されます。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + AccessAddEx [pass|discard] [/MEMO:memo] [/PRIORITY:priority] [/SRCUSERNAME:username] [/DESTUSERNAME:username] [/SRCMAC:mac/mask] [/DESTMAC:mac/mask] [/SRCIP:ip/mask] [/DESTIP:ip/mask] [/PROTOCOL:tcp|udp|icmpv4|icmpv6|ip|num] [/SRCPORT:start-end] [/DESTPORT:start-end] [/SRCUSERNAME:username] [/DESTUSERNAME:username] [/TCPSTATE:established|unestablished] [/DELAY:delay_millisec] [/JITTER:jitter_percent] [/LOSS:loss_percent]
"AccessAddEx" コマンドで指定することができるパラメータ引数の一覧:
pass|discard + パケットが、このルールの条件に一致した場合の動作を決定します。pass を指定すると [通過] を、discard を指定すると [破棄] を意味します。遅延・ジッタ・パケットロス設定は、pass の場合のみ適用されます。
/MEMO + ルールの説明 (メモ) を指定します。
/PRIORITY + ルールの優先順位を 1 以上の整数で指定します。優先順位は小さいものほど優先度が高くなります。
/SRCUSERNAME + ルールの条件として、指定された名前のユーザーまたはグループのセッションによって送信されたパケットのみに、このルールを適用することができます。その場合は、ユーザー名またはグループ名を指定します。
/DESTUSERNAME + ルールの条件として、指定された名前のユーザーまたはグループのセッションが受信するパケットのみに、このルールを適用することができます。その場合は、ユーザー名またはグループ名を指定します。
/SRCMAC + ルールの条件として、送信元 MAC アドレスを指定します。MAC アドレスは 00-AC-84-EA-33-BC/FF-FF-FF-FF-FF-00 のように 16 進数と "-" か ":" の区切り文字を使用して指定します。区切り文字は省略できます。
/DESTMAC + ルールの条件として、宛先 MAC アドレスを指定します。指定方法は、/SRCMAC パラメータと同様です。
/SRCIP + ルールの条件として、送信元 IPv4 アドレスを "IPアドレス/マスク" の形式で指定します。IP アドレスは 192.168.0.1 のように 10 進数をドットで区切って指定します。マスクは 255.255.255.0 のように 10 進数をドットで区切って指定するか、24 のように先頭からのビット長を 10 進数で指定できます。0.0.0.0/0.0.0.0 を指定すると、すべてのホストを示します。
/DESTIP + ルールの条件として、宛先 IPv4 アドレスを "IPアドレス/マスク" の形式で指定します。指定方法は /SRCIP パラメータと同様です。
/PROTOCOL + ルールの条件として、プロトコルの種類を指定します。IP プロトコル番号を 10 進数で入力するか、"tcp" (TCP/IP プロトコル、6 番)、"udp" (UDP/IP プロトコル、17番)、"icmpv4" (ICMPv4 プロトコル、1 番)、"icmpv6" (ICMPv6 プロトコル、58 番)、"ip" (すべての IP プロトコル、0 番) のキーワードを指定します。すべての IP プロトコルを対象とするには 0 を指定します。
/SRCPORT + プロトコルが TCP/IP または UDP/IP の場合は、ルールの条件として、送信元ポート番号を指定します。それ以外のプロトコルの場合は無視されます。このパラメータを指定しない場合は、すべてのポート番号が対象となります。指定方法は、"1-1024" (1 番以上 1024 番以下)、"23" (23 番のみ) などのように指定します。
/DESTPORT + プロトコルが TCP/IP または UDP/IP の場合は、ルールの条件として、宛先ポート番号を指定します。それ以外のプロトコルの場合は無視されます。指定方法は /SRCPORT パラメータと同様です。
/TCPSTATE + ルールの条件として、TCP コネクションの状態を指定します。Established または Unestablished を指定します。
/DELAY + このルールによってパケットが通過する場合に遅延を発生させることができます。発生させたい遅延時間をミリ秒単位で指定します。無指定または 0 を指定すると、遅延は発生しません。遅延は 10000 ミリ秒以下である必要があります。
/JITTER + このルールによってパケットが通過する場合にジッタを発生させることができます。遅延の値に対してジッタの揺らぎを 0% ~ 100% のパーセント数値で指定します。無指定または 0 を指定すると、ジッタは発生しません。
/LOSS + このルールによってパケットが通過する場合にパケットロスを発生させることができます。パケットが破棄される可能性を 0% ~ 100% のパーセント数値で指定します。無指定または 0 を指定すると、パケットロスは発生しません。
+

 

+

6.4.52 "AccessAdd6": アクセスリストへのルールの追加 (IPv6)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccessAdd6
コマンドの概要 + アクセスリストへのルールの追加 (IPv6)
説明 + 現在管理している仮想 HUB のアクセスリストに、新しいルールを追加します。
アクセスリストとは、仮想 HUB 内を流れるパケットに対して適用されるパケットフィルタルールの集合です。アクセスリストには複数のルールを登録することができ、各ルールごとに優先順位を定義することができます。すべてのパケットは、アクセスリストに登録されているルールで指定された条件に、最初に一致したルールで規定されている動作で、通過または破棄が決定されます。どのルールの条件にも一致しなかったパケットは、暗黙で通過を許可されます。なお、AccessAddEx6 コマンドを使用することで、通過時に遅延・ジッタ・パケットロスを発生させることもできます。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + AccessAdd6 [pass|discard] [/MEMO:memo] [/PRIORITY:priority] [/SRCUSERNAME:username] [/DESTUSERNAME:username] [/SRCMAC:mac/mask] [/DESTMAC:mac/mask] [/SRCIP:ip/mask] [/DESTIP:ip/mask] [/PROTOCOL:tcp|udp|icmpv4|icmpv6|ip|num] [/SRCPORT:start-end] [/DESTPORT:start-end] [/SRCUSERNAME:username] [/DESTUSERNAME:username] [/TCPSTATE:established|unestablished]
"AccessAdd6" コマンドで指定することができるパラメータ引数の一覧:
pass|discard + パケットが、このルールの条件に一致した場合の動作を決定します。pass を指定すると [通過] を、discard を指定すると [破棄] を意味します。
/MEMO + ルールの説明 (メモ) を指定します。
/PRIORITY + ルールの優先順位を 1 以上の整数で指定します。優先順位は小さいものほど優先度が高くなります。
/SRCUSERNAME + ルールの条件として、指定された名前のユーザーまたはグループのセッションによって送信されたパケットのみに、このルールを適用することができます。その場合は、ユーザー名またはグループ名を指定します。
/DESTUSERNAME + ルールの条件として、指定された名前のユーザーまたはグループのセッションが受信するパケットのみに、このルールを適用することができます。その場合は、ユーザー名またはグループ名を指定します。
/SRCMAC + ルールの条件として、送信元 MAC アドレスを指定します。MAC アドレスは 00-AC-84-EA-33-BC/FF-FF-FF-FF-FF-00 のように 16 進数と "-" か ":" の区切り文字を使用して指定します。区切り文字は省略できます。
/DESTMAC + ルールの条件として、宛先 MAC アドレスを指定します。指定方法は、/SRCMAC パラメータと同様です。
/SRCIP + ルールの条件として、送信元 IPv6 アドレスを "IPアドレス/マスク" の形式で指定します。IPv6 アドレスは 2001:200:0:1:: のように 16 進数をコロンで区切って指定します。マスクは ffff:ffff:ffff:ffff:: のように IPv6 形式で区切って指定するか、64 のように先頭からのビット長を 10 進数で指定します。単一の IPv6 ホストを指定するには、マスクを ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff または 128 として指定します。すべての IPv6 ホストを指定するには、"::/0" と指定します。
/DESTIP + ルールの条件として、宛先 IPv6 アドレスを "IPアドレス/マスク" の形式で指定します。指定方法は /SRCIP パラメータと同様です。
/PROTOCOL + ルールの条件として、プロトコルの種類を指定します。IP プロトコル番号を 10 進数で入力するか、"tcp" (TCP/IP プロトコル、6 番)、"udp" (UDP/IP プロトコル、17番)、"icmpv4" (ICMPv4 プロトコル、1 番)、"icmpv6" (ICMPv6 プロトコル、58 番)、"ip" (すべての IP プロトコル、0 番) のキーワードを指定します。すべての IP プロトコルを対象とするには 0 を指定します。
/SRCPORT + プロトコルが TCP/IP または UDP/IP の場合は、ルールの条件として、送信元ポート番号を指定します。それ以外のプロトコルの場合は無視されます。このパラメータを指定しない場合は、すべてのポート番号が対象となります。指定方法は、"1-1024" (1 番以上 1024 番以下)、"23" (23 番のみ) などのように指定します。
/DESTPORT + プロトコルが TCP/IP または UDP/IP の場合は、ルールの条件として、宛先ポート番号を指定します。それ以外のプロトコルの場合は無視されます。指定方法は /SRCPORT パラメータと同様です。
/TCPSTATE + ルールの条件として、TCP コネクションの状態を指定します。 Established または Unestablished を指定します。
+

 

+

6.4.53 "AccessAddEx6": アクセスリストへのルールの追加 (IPv6, 遅延・ジッタ・パケットロス設定可能)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccessAddEx6
コマンドの概要 + アクセスリストへのルールの追加 (IPv6, 遅延・ジッタ・パケットロス設定可能)
説明 + 現在管理している仮想 HUB のアクセスリストに、新しいルールを追加します。通過時に遅延・ジッタ・パケットロスを発生させることができます。
アクセスリストとは、仮想 HUB 内を流れるパケットに対して適用されるパケットフィルタルールの集合です。アクセスリストには複数のルールを登録することができ、各ルールごとに優先順位を定義することができます。すべてのパケットは、アクセスリストに登録されているルールで指定された条件に、最初に一致したルールで規定されている動作で、通過または破棄が決定されます。どのルールの条件にも一致しなかったパケットは、暗黙で通過を許可されます。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + AccessAddEx6 [pass|discard] [/MEMO:memo] [/PRIORITY:priority] [/SRCUSERNAME:username] [/DESTUSERNAME:username] [/SRCMAC:mac/mask] [/DESTMAC:mac/mask] [/SRCIP:ip/mask] [/DESTIP:ip/mask] [/PROTOCOL:tcp|udp|icmpv4|icmpv6|ip|num] [/SRCPORT:start-end] [/DESTPORT:start-end] [/SRCUSERNAME:username] [/DESTUSERNAME:username] [/TCPSTATE:established|unestablished] [/DELAY:delay_millisec] [/JITTER:jitter_percent] [/LOSS:loss_percent]
"AccessAddEx6" コマンドで指定することができるパラメータ引数の一覧:
pass|discard + パケットが、このルールの条件に一致した場合の動作を決定します。pass を指定すると [通過] を、discard を指定すると [破棄] を意味します。遅延・ジッタ・パケットロス設定は、pass の場合のみ適用されます。
/MEMO + ルールの説明 (メモ) を指定します。
/PRIORITY + ルールの優先順位を 1 以上の整数で指定します。優先順位は小さいものほど優先度が高くなります。
/SRCUSERNAME + ルールの条件として、指定された名前のユーザーまたはグループのセッションによって送信されたパケットのみに、このルールを適用することができます。その場合は、ユーザー名またはグループ名を指定します。
/DESTUSERNAME + ルールの条件として、指定された名前のユーザーまたはグループのセッションが受信するパケットのみに、このルールを適用することができます。その場合は、ユーザー名またはグループ名を指定します。
/SRCMAC + ルールの条件として、送信元 MAC アドレスを指定します。MAC アドレスは 00-AC-84-EA-33-BC/FF-FF-FF-FF-FF-00 のように 16 進数と "-" か ":" の区切り文字を使用して指定します。区切り文字は省略できます。
/DESTMAC + ルールの条件として、宛先 MAC アドレスを指定します。指定方法は、/SRCMAC パラメータと同様です。
/SRCIP + ルールの条件として、送信元 IPv6 アドレスを "IPアドレス/マスク" の形式で指定します。IPv6 アドレスは 2001:200:0:1:: のように 16 進数をコロンで区切って指定します。マスクは ffff:ffff:ffff:ffff:: のように IPv6 形式で区切って指定するか、64 のように先頭からのビット長を 10 進数で指定します。単一の IPv6 ホストを指定するには、マスクを ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff または 128 として指定します。すべての IPv6 ホストを指定するには、"::/0" と指定します。
/DESTIP + ルールの条件として、宛先 IPv6 アドレスを "IPアドレス/マスク" の形式で指定します。指定方法は /SRCIP パラメータと同様です。
/PROTOCOL + ルールの条件として、プロトコルの種類を指定します。IP プロトコル番号を 10 進数で入力するか、"tcp" (TCP/IP プロトコル、6 番)、"udp" (UDP/IP プロトコル、17番)、"icmpv4" (ICMPv4 プロトコル、1 番)、"icmpv6" (ICMPv6 プロトコル、58 番)、"ip" (すべての IP プロトコル、0 番) のキーワードを指定します。すべての IP プロトコルを対象とするには 0 を指定します。
/SRCPORT + プロトコルが TCP/IP または UDP/IP の場合は、ルールの条件として、送信元ポート番号を指定します。それ以外のプロトコルの場合は無視されます。このパラメータを指定しない場合は、すべてのポート番号が対象となります。指定方法は、"1-1024" (1 番以上 1024 番以下)、"23" (23 番のみ) などのように指定します。
/DESTPORT + プロトコルが TCP/IP または UDP/IP の場合は、ルールの条件として、宛先ポート番号を指定します。それ以外のプロトコルの場合は無視されます。指定方法は /SRCPORT パラメータと同様です。
/TCPSTATE + ルールの条件として、TCP コネクションの状態を指定します。 Established または Unestablished を指定します。
/DELAY + このルールによってパケットが通過する場合に遅延を発生させることができます。発生させたい遅延時間をミリ秒単位で指定します。無指定または 0 を指定すると、遅延は発生しません。ジッタは 10000 ミリ秒以下である必要があります。
/JITTER + このルールによってパケットが通過する場合にジッタを発生させることができます。遅延の値に対してジッタの揺らぎを 0% ~ 100% のパーセント数値で指定します。無指定または 0 を指定すると、ジッタは発生しません。
/LOSS + このルールによってパケットが通過する場合にパケットロスを発生させることができます。パケットが破棄される可能性を 0% ~ 100% のパーセント数値で指定します。無指定または 0 を指定すると、パケットロスは発生しません。
+

 

+

6.4.54 "AccessList": アクセスリストのルール一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccessList
コマンドの概要 + アクセスリストのルール一覧の取得
説明 + 現在管理している仮想 HUB のアクセスリストに登録されている、パケットフィルタルールの一覧を取得します。
アクセスリストとは、仮想 HUB 内を流れるパケットに対して適用されるパケットフィルタルールの集合です。アクセスリストには複数のルールを登録することができ、ルール毎に優先順位を定義することができます。すべてのパケットは、アクセスリストに登録されているルールで指定された条件に、最初に一致したルールで規定されている動作で、通過または破棄が決定されます。どのルールの条件にも一致しなかったパケットは、暗黙で通過を許可されます。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + AccessList
"AccessList" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.55 "AccessDelete": アクセスリストからルールを削除

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccessDelete
コマンドの概要 + アクセスリストからルールを削除
説明 + 現在管理している仮想 HUB のアクセスリストに登録されている、パケットフィルタルールを指定して削除します。
ルールを削除するには、そのルールの ID を指定する必要があります。ID は AccessList コマンドで表示できます。
なお、ルールを削除しなくても一時的に無効化するには AccessDisable コマンドを使用します。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + AccessDelete [id]
"AccessDelete" コマンドで指定することができるパラメータ引数の一覧:
id + 削除するルールの ID またはユニーク ID を指定します。
+

 

+

6.4.56 "AccessEnable": アクセスリストのルールの有効化

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccessEnable
コマンドの概要 + アクセスリストのルールの有効化
説明 + 現在管理している仮想 HUB のアクセスリストに登録されているパケットフィルタルールを指定して有効化します。有効化したルールは、パケットフィルタリングに使用されます。
ルールを有効化するには、そのルールの ID を指定する必要があります。ID は AccessList コマンドで表示できます。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + AccessEnable [id]
"AccessEnable" コマンドで指定することができるパラメータ引数の一覧:
id + 有効化するルールの ID を指定します。
+

 

+

6.4.57 "AccessDisable": アクセスリストのルールの無効化

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccessDisable
コマンドの概要 + アクセスリストのルールの無効化
説明 + 現在管理している仮想 HUB のアクセスリストに登録されているパケットフィルタルールを指定して無効化します。無効化したルールは、パケットフィルタリングに使用されなくなります。
ルールを無効化するには、そのルールの ID を指定する必要があります。ID は AccessList コマンドで表示できます。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + AccessDisable [id]
"AccessDisable" コマンドで指定することができるパラメータ引数の一覧:
id + 無効化するルールの ID を指定します。
+

 

+

6.4.58 "UserList": ユーザー一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + UserList
コマンドの概要 + ユーザー一覧の取得
説明 + 現在管理している仮想 HUB の、セキュリティアカウントデータベースに登録されているユーザー一覧を取得します。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + UserList
"UserList" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.59 "UserCreate": ユーザーの作成

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + UserCreate
コマンドの概要 + ユーザーの作成
説明 + 現在管理している仮想 HUB の、セキュリティアカウントデータベースに新しいユーザーを作成します。
ユーザーを作成すると、そのユーザーの認証情報に従って、VPN Client がこの仮想 HUB に接続することができるようになります。
UserCreate コマンドを使用してユーザーを作成した場合、そのユーザーの認証方法は [パスワード認証] として登録され、パスワードとしてランダムな文字列が割り当てられます。したがって、そのユーザーはそのままでは仮想 HUB に接続することはできません。ユーザーを作成した後、必ず UserPasswordSet コマンドでユーザーのパスワードを指定するか、UserAnonymousSet コマンド、UserCertSet コマンド、UserSignedSet コマンド、UserRadiusSet コマンドまたは UserNTLMSet コマンドでユーザーの認証方法を変更してください。
ただし、ユーザー名を "*" (アスタリスク 1 文字) として作成したユーザーは、自動的に RADIUS 認証のユーザーとして登録されます。"*" という名前のユーザーが存在する場合に限り、クライアントが VPN Server に接続した際に提示したユーザー名が既存のユーザー名と一致しないユーザーは、そのユーザーが入力したユーザー名とパスワードによって、RADIUS サーバーまたは NT ドメインコントローラによって認証されることができ、その場合の認証設定やセキュリティポリシーの設定は "*" ユーザーに設定に準拠します。
一度作成したユーザーのユーザー情報を変更するには、UserSet コマンドを使用します。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + UserCreate [name] [/GROUP:group] [/REALNAME:realname] [/NOTE:note]
"UserCreate" コマンドで指定することができるパラメータ引数の一覧:
name + 新しく作成するユーザーのユーザー名を指定します。
/GROUP + ユーザーをグループに参加させる場合、グループ名を指定します。ユーザーをどのグループにも所属させない場合は /GROUP:none と指定します。
/REALNAME + ユーザーの本名を指定します。指定しない場合は、/REALNAME:none と指定します。
/NOTE + ユーザーの説明を指定します。指定しない場合は、/NOTE:none と指定します。
+

 

+

6.4.60 "UserSet": ユーザー情報の変更

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + UserSet
コマンドの概要 + ユーザー情報の変更
説明 + 現在管理している仮想 HUB の、セキュリティアカウントデータベースに登録されているユーザーの情報を変更します。
このコマンドで変更できるユーザーの情報は、UserCreate コマンドで、新しくユーザーを作成するときに指定する「グループ名」、「本名」および「説明」の 3 項目です。
現在登録されているユーザーの一覧を取得するには、UserList コマンドを使用してください。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + UserSet [name] [/GROUP:group] [/REALNAME:realname] [/NOTE:note]
"UserSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するユーザー名を指定します。
/GROUP + ユーザーをグループに参加させる場合、グループ名を指定します。ユーザーをどのグループにも所属させない場合は /GROUP:none と指定します。
/REALNAME + ユーザーの本名を指定します。指定しない場合は、/REALNAME:none と指定します。
/NOTE + ユーザーの説明を指定します。指定しない場合は、/NOTE:none と指定します。
+

 

+

6.4.61 "UserDelete": ユーザーの削除

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + UserDelete
コマンドの概要 + ユーザーの削除
説明 + 現在管理している仮想 HUB の、セキュリティアカウントデータベースに登録されているユーザーを削除します。ユーザーを削除すると、そのユーザーは仮想 HUB に接続できなくなります。
UserPolicySet コマンドを使用すると、ユーザーを削除しなくても、一時的にログインを禁止するように設定することができます。
現在登録されているユーザーの一覧を取得するには、UserList コマンドを使用してください。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + UserDelete [name]
"UserDelete" コマンドで指定することができるパラメータ引数の一覧:
name + 削除するユーザー名を指定します。
+

 

+

6.4.62 "UserGet": ユーザー情報の取得

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + UserGet
コマンドの概要 + ユーザー情報の取得
説明 + 現在管理している仮想 HUB の、セキュリティアカウントデータベースに登録されているユーザーの登録情報を所得します。
このコマンドで取得できる情報は、「ユーザー名」、「本名」、「説明」、「所属グループ」、「有効期限」、「セキュリティポリシー」、「認証方法」、および設定されている認証方法の属性として指定されているパラメータに加えて、そのユーザーの統計データです。
現在登録されているユーザーの一覧を取得するには、UserList コマンドを使用してください。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + UserGet [name]
"UserGet" コマンドで指定することができるパラメータ引数の一覧:
name + 情報を取得するユーザー名を指定します。
+

 

+

6.4.63 "UserAnonymousSet": ユーザーの認証方法を匿名認証に設定

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + UserAnonymousSet
コマンドの概要 + ユーザーの認証方法を匿名認証に設定
説明 + 現在管理している仮想 HUB の、セキュリティアカウントデータベースに登録されているユーザーの認証方法を「匿名認証」に設定します。匿名認証に設定されたユーザーのユーザー名で仮想 HUB に接続した VPN Client は、いかなるユーザー認証も受けずに無条件で仮想 HUB に接続することができます。匿名認証機能は、インターネットなどで広く誰でも接続できるような設定で公開する VPN Server に最適です。
現在登録されているユーザーの一覧を取得するには、UserList コマンドを使用してください。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + UserAnonymousSet [name]
"UserAnonymousSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するユーザー名を指定します。
+

 

+

6.4.64 "UserPasswordSet": ユーザーの認証方法をパスワード認証に設定しパスワードを設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + UserPasswordSet
コマンドの概要 + ユーザーの認証方法をパスワード認証に設定しパスワードを設定
説明 + 現在管理している仮想 HUB の、セキュリティアカウントデータベースに登録されているユーザーの認証方法を「パスワード認証」に設定します。パスワード認証とは、仮想 HUB のセキュリティアカウントデータベース内のユーザー オブジェクトに対して任意のパスワードを設定しておき、そのユーザー名でユーザーが仮想 HUB に接続しようとした際にパスワードの入力を求め、そのパスワードが一致した場合に接続を許可する認証方法です。
実際には、ユーザーのパスワードはハッシュ化され保存されるので、VPN Server の設定ファイルを解析しても元のパスワードはわかりません。
現在登録されているユーザーの一覧を取得するには、UserList コマンドを使用してください。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + UserPasswordSet [name] [/PASSWORD:password]
"UserPasswordSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するユーザー名を指定します。
/PASSWORD + ユーザーに対して設定するパスワードを指定します。このパラメータを指定しない場合は、パスワードを入力するプロンプトが表示されます。
+

 

+

6.4.65 "UserCertSet": ユーザーの認証方法を固有証明書認証に設定し証明書を設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + UserCertSet
コマンドの概要 + ユーザーの認証方法を固有証明書認証に設定し証明書を設定
説明 + 現在管理している仮想 HUB の、セキュリティアカウントデータベースに登録されているユーザーの認証方法を「固有証明書認証」に設定します。固有証明書認証とは、仮想 HUB のセキュリティアカウントデータベース内のユーザー オブジェクトに対して 1 つの X.509 証明書を設定しておき、そのユーザー名でユーザーが仮想 HUB に接続しようとした際に、提示した証明書が登録されている証明書と一致し、かつクライアントがその証明書に対応する秘密鍵を保持しているかを RSA アルゴリズムで検証することによって接続を許可する認証方法です。
現在登録されているユーザーの一覧を取得するには、UserList コマンドを使用してください。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + UserCertSet [name] [/LOADCERT:cert]
"UserCertSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するユーザー名を指定します。
/LOADCERT + ユーザーに対して設定する証明書を X.509 証明書ファイル名で指定します。
+

 

+

6.4.66 "UserCertGet": 固有証明書認証のユーザーの登録されている証明書の取得

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + UserCertGet
コマンドの概要 + 固有証明書認証のユーザーの登録されている証明書の取得
説明 + 現在管理している仮想 HUB の、セキュリティアカウントデータベースに登録されている「固有証明書認証」のユーザーに対して設定されている X.509 形式の証明書を取得し、ファイルに保存します。
指定したユーザーが「固有証明書認証」として設定されていない場合は、エラーが発生します。
現在登録されているユーザーの一覧を取得するには、UserList コマンドを使用してください。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + UserCertGet [name] [/SAVECERT:cert]
"UserCertGet" コマンドで指定することができるパラメータ引数の一覧:
name + 情報を取得するユーザー名を指定します。
/SAVECERT + 取得したユーザーの証明書を X.509 形式で保存するファイル名を指定します。
+

 

+

6.4.67 "UserSignedSet": ユーザーの認証方法を署名済み証明書認証に設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + UserSignedSet
コマンドの概要 + ユーザーの認証方法を署名済み証明書認証に設定
説明 + 現在管理している仮想 HUB の、セキュリティアカウントデータベースに登録されているユーザーの認証方法を「署名済み証明書認証」に設定します。署名済み証明書認証に設定されているユーザー名で、ユーザーが仮想 HUB に接続した際に、ユーザーが提示した証明書がその仮想 HUB の信頼する証明機関の証明書の一覧内の証明書のいずれかによって署名されているかどうかが検査され、かつクライアントがその証明書に対応する秘密鍵を保持しているかを RSA アルゴリズムで検証することによって接続を許可する認証方法です。
また、ユーザーごとに期待する証明書の Common Name (CN)、およびシリアル番号を登録しておき、前記の検証を通過した後証明書の内容が設定された値に一致した場合にのみ接続を許可するようにする設定も可能です。
現在登録されているユーザーの一覧を取得するには、UserList コマンドを使用してください。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + UserSignedSet [name] [/CN:cn] [/SERIAL:serial]
"UserSignedSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するユーザー名を指定します。
/CN + このパラメータを指定した場合は、ユーザーが提示した証明書が信頼できる証明機関によって署名されているかどうかを検証した後に、その証明書の Common Name (CN) の値を、このパラメータによって設定された値と比較して一致している場合のみ接続を許可します。"none" を指定した場合は、このチェックは行われません。
/SERIAL + このパラメータを指定した場合は、ユーザーが提示した証明書が信頼できる証明機関によって署名されているかどうかを検証した後に、その証明書のシリアル番号の値を、このパラメータによって設定された値と比較して一致している場合のみ接続を許可します。"none" を指定した場合は、このチェックは行われません。
+

 

+

6.4.68 "UserRadiusSet": ユーザーの認証方法を RADIUS 認証に設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + UserRadiusSet
コマンドの概要 + ユーザーの認証方法を RADIUS 認証に設定
説明 + 現在管理している仮想 HUB の、セキュリティアカウントデータベースに登録されているユーザーの認証方法を「RADIUS 認証」に設定します。RADIUS 認証に設定されているユーザー名でユーザーが仮想 HUB に接続した際に、ユーザー名とユーザーが入力したパスワードが RADIUS サーバーに送信され、RADIUS サーバーがユーザー名とパスワードのチェックを行った後に認証が成功すると、そのユーザーの VPN 接続が許可されます。
Radius 認証を使用するには、あらかじめ RadiusServerSet コマンドを使用して使用する RADIUS サーバーを仮想 HUB に設定しておく必要があります。
現在登録されているユーザーの一覧を取得するには、UserList コマンドを使用してください。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + UserRadiusSet [name] [/ALIAS:alias_name]
"UserRadiusSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するユーザー名を指定します。
/ALIAS + このパラメータが設定されている場合、RADIUS サーバーに対して送信されるユーザー名を、仮想 HUB 上のユーザー名とは別のユーザー名にすることが可能です。設定しない場合は、/ALIAS:none と指定してください (仮想 HUB 上のユーザー名が使用されます)。ユーザー名が "*" の場合は /ALIAS パラメータは無視されます。"*" ユーザーについての説明は、UserCreate /HELP と入力すると表示されます。
+

 

+

6.4.69 "UserNTLMSet": ユーザーの認証方法を NT ドメイン認証に設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + UserNTLMSet
コマンドの概要 + ユーザーの認証方法を NT ドメイン認証に設定
説明 + 現在管理している仮想 HUB の、セキュリティアカウントデータベースに登録されているユーザーの認証方法を「NT ドメイン認証」に設定します。NT ドメイン認証に設定されているユーザー名でユーザーが仮想 HUB に接続した際に、ユーザー名とユーザーが入力したパスワードが Windows NT / 2000 / Server 2003 / Server 2008 / Server 2008 R2 / Server 2012 のドメインコントローラ、または Active Directory サーバーに送信され、認証サーバーがユーザー名とパスワードのチェックを行った後に認証が成功すると、そのユーザーの VPN 接続が許可されます。
NT ドメイン認証を使用するには、VPN Server がそのドメインに接続されている Windows NT 4.0, Windows 2000, Windows XP, Windows Server 2003, Windows Vista, Windows Server 2008, Windows 7, Windows Server 2008 R2, Windows 8, Windows Server 2012 のいずれかのオペレーティングシステム上で動作している必要があります。詳しくは VPN Server の管理者にお問い合わせください。
現在登録されているユーザーの一覧を取得するには、UserList コマンドを使用してください。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + UserNTLMSet [name] [/ALIAS:alias_name]
"UserNTLMSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するユーザー名を指定します。
/ALIAS + このパラメータが設定されている場合、NT ドメインまたは Active Directory に対して送信されるユーザー名を、仮想 HUB 上のユーザー名とは別のユーザー名にすることが可能です。設定しない場合は、/ALIAS:none と指定してください (仮想 HUB 上のユーザー名が使用されます)。ユーザー名が "*" の場合は /ALIAS パラメータは無視されます。"*" ユーザーについての説明は、UserCreate /HELP と入力すると表示されます。
+

 

+

6.4.70 "UserPolicyRemove": ユーザーのセキュリティポリシーの削除

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + UserPolicyRemove
コマンドの概要 + ユーザーのセキュリティポリシーの削除
説明 + 現在管理している仮想 HUB の、セキュリティアカウントデータベースに登録されているユーザーに対して設定されている、セキュリティポリシーの設定を削除します。セキュリティポリシーの設定が削除されているユーザーは、そのユーザーが所属しているグループのセキュリティポリシーの設定が適用されます。グループに所属していないか、グループにセキュリティポリシーが設定されていない場合は、デフォルトの値 (アクセスを許可: 有効、TCP 接続数の最大値: 32 個、タイムアウト時間: 20 秒) に従います。
現在登録されているユーザーの一覧を取得するには、UserList コマンドを使用してください。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + UserPolicyRemove [name]
"UserPolicyRemove" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するユーザー名を指定します。
+

 

+

6.4.71 "UserPolicySet": ユーザーのセキュリティポリシーの設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + UserPolicySet
コマンドの概要 + ユーザーのセキュリティポリシーの設定
説明 + 現在管理している仮想 HUB の、セキュリティアカウントデータベースに登録されているユーザーに対して設定されているセキュリティポリシーの内容を変更します。
ユーザーにセキュリティポリシーが設定されていない場合は、新しいデフォルトのセキュリティポリシーを設定してから、指定された値を変更します。
現在登録されているユーザーの一覧を取得するには、UserList コマンドを使用してください。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + UserPolicySet [name] [/NAME:policy_name] [/VALUE:num|yes|no]
"UserPolicySet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するユーザー名を指定します。
/NAME + 値を変更するポリシーの名前を指定します。ポリシーの名前と設定できる値の一覧は PolicyList コマンドで表示することができます。
/VALUE + ポリシーの新しい値を指定します。そのポリシーが数値型の場合は整数を指定します。ブール型の場合は yes または no を指定します。設定できる型と値は、PolicyList コマンドで表示することができます。
+

 

+

6.4.72 "UserExpiresSet": ユーザーの有効期限の設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + UserExpiresSet
コマンドの概要 + ユーザーの有効期限の設定
説明 + 現在管理している仮想 HUB の、セキュリティアカウントデータベースに登録されているユーザーの有効期限を設定します。有効期限が終了したユーザーは、仮想 HUB に接続できなくなります。
現在登録されているユーザーの一覧を取得するには、UserList コマンドを使用してください。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + UserExpiresSet [name] [/EXPIRES:expires]
"UserExpiresSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するユーザー名を指定します。
/EXPIRES + ユーザーの有効期限の日時を指定します。"2005/10/08 19:30:00" のように、年・月・日・時・分・秒 の 6 個の整数をスペース、スラッシュまたはコロンで区切って指定してください。年は 4 桁で指定してください。値にスペースを入れる場合は、値全体を "" で囲む必要があります。指定はローカル時刻 (コマンドライン管理ユーティリティを実行しているコンピュータの基準時刻) で指定できます。/EXPIRES:none と指定すると、有効期限は解除されます。
+

 

+

6.4.73 "GroupList": グループ一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + GroupList
コマンドの概要 + グループ一覧の取得
説明 + 現在管理している仮想 HUB の、セキュリティアカウントデータベースに登録されているグループ一覧を取得します。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + GroupList
"GroupList" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.74 "GroupCreate": グループの作成

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + GroupCreate
コマンドの概要 + グループの作成
説明 + 現在管理している仮想 HUB の、セキュリティアカウントデータベースに新しいグループを作成します。
グループには複数のユーザーを登録することができます。グループにユーザーを登録するには、GroupJoin コマンドを使用します。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + GroupCreate [name] [/REALNAME:realname] [/NOTE:note]
"GroupCreate" コマンドで指定することができるパラメータ引数の一覧:
name + 作成するグループ名を指定します。
/REALNAME + グループの本名を指定します。たとえば、グループが実際の部課名に対応する場合は、その名前を指定します。指定しない場合は、/REALNAME:none と指定します。
/NOTE + グループの説明を指定します。指定しない場合は、/NOTE:none と指定します。
+

 

+

6.4.75 "GroupSet": グループ情報の設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + GroupSet
コマンドの概要 + グループ情報の設定
説明 + 現在管理している仮想 HUB の、セキュリティアカウントデータベースに登録されているグループの情報を設定します。
現在登録されているグループの一覧を取得するには、GroupList コマンドを使用してください。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + GroupSet [name] [/REALNAME:realname] [/NOTE:note]
"GroupSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するグループ名を指定します。
/REALNAME + グループの本名を指定します。たとえば、グループが実際の部課名に対応する場合は、その名前を指定します。指定しない場合は、/REALNAME:none と指定します。
/NOTE + グループの説明を指定します。指定しない場合は、/NOTE:none と指定します。
+

 

+

6.4.76 "GroupDelete": グループの削除

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + GroupDelete
コマンドの概要 + グループの削除
説明 + 現在管理している仮想 HUB の、セキュリティアカウントデータベースに登録されているグループを削除します。
グループを削除すると、そのグループに所属していたユーザーはすべて無所属になります。
現在登録されているグループの一覧を取得するには、GroupList コマンドを使用してください。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + GroupDelete [name]
"GroupDelete" コマンドで指定することができるパラメータ引数の一覧:
name + 削除するグループ名を指定します
+

 

+

6.4.77 "GroupGet": グループ情報と所属しているユーザー一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + GroupGet
コマンドの概要 + グループ情報と所属しているユーザー一覧の取得
説明 + 現在管理している仮想 HUB の、セキュリティアカウントデータベースに登録されているグループの情報と、そのグループに所属しているユーザーの一覧を取得します。
現在登録されているグループの一覧を取得するには、GroupList コマンドを使用してください。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + GroupGet [name]
"GroupGet" コマンドで指定することができるパラメータ引数の一覧:
name + 情報を取得するグループ名を指定します。
+

 

+

6.4.78 "GroupJoin": グループにユーザーを追加

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + GroupJoin
コマンドの概要 + グループにユーザーを追加
説明 + 現在管理している仮想 HUB の、セキュリティアカウントデータベースに登録されているグループに、セキュリティアカウントデータベース内のユーザーを追加します。
現在登録されているユーザーとグループの一覧は、UserList コマンドと GroupList コマンドで取得できます。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + GroupJoin [name] [/USERNAME:username]
"GroupJoin" コマンドで指定することができるパラメータ引数の一覧:
name + ユーザーを追加するグループ名を指定します。
/USERNAME + name で指定したグループに追加するユーザー名を指定します。
+

 

+

6.4.79 "GroupUnjoin": グループからユーザーを削除

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + GroupUnjoin
コマンドの概要 + グループからユーザーを削除
説明 + 現在管理している仮想 HUB の、セキュリティアカウントデータベースに登録されているグループから、指定したユーザーを削除します。グループからユーザーが削除されると、そのユーザーは無所属となります。
グループに現在所属しているユーザーの一覧を取得するには、GroupGet コマンドを使用します。
現在登録されているグループの一覧を取得するには、GroupList コマンドを使用してください。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + GroupUnjoin [name]
"GroupUnjoin" コマンドで指定することができるパラメータ引数の一覧:
name + グループから削除するユーザー名を指定します。
+

 

+

6.4.80 "GroupPolicyRemove": グループのセキュリティポリシーの削除

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + GroupPolicyRemove
コマンドの概要 + グループのセキュリティポリシーの削除
説明 + 現在管理している仮想 HUB の、セキュリティアカウントデータベースに登録されているグループに対して設定されているセキュリティポリシーの設定を削除します。所属しているグループにもユーザー本体にもセキュリティポリシーが設定されていないユーザーは、デフォルトの値 (アクセスを許可: 有効、TCP 接続数の最大値: 32 個、タイムアウト時間: 20 秒) に従います。
現在登録されているグループの一覧を取得するには、GroupList コマンドを使用してください。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + GroupPolicyRemove [name]
"GroupPolicyRemove" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するグループ名を指定します。
+

 

+

6.4.81 "GroupPolicySet": グループのセキュリティポリシーの設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + GroupPolicySet
コマンドの概要 + グループのセキュリティポリシーの設定
説明 + 現在管理している仮想 HUB の、セキュリティアカウントデータベースに登録されているグループに対して設定されているセキュリティポリシーの内容を変更します。
グループにセキュリティポリシーが設定されていない場合は、新しいデフォルトのセキュリティポリシーを設定してから、指定された値を変更します。
現在登録されているグループの一覧を取得するには、GroupList コマンドを使用してください。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + GroupPolicySet [name] [/NAME:policy_name] [/VALUE:num|yes|no]
"GroupPolicySet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更するグループ名を指定します。
/NAME + 値を変更するポリシーの名前を指定します。ポリシーの名前と設定できる値の一覧は、PolicyList コマンドで表示することができます。
/VALUE + ポリシーの新しい値を指定します。そのポリシーが数値型の場合は整数を指定します。ブール型の場合は yes または no を指定します。設定できる型と値は、PolicyList コマンドで表示することができます。
+

 

+

6.4.82 "SessionList": 接続中のセッション一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + SessionList
コマンドの概要 + 接続中のセッション一覧の取得
説明 + 現在管理している仮想 HUB に接続中のセッション一覧を取得します。セッション一覧には、各コネクションごとの [セッション名]、[セッションの場所]、[ユーザー名]、[接続元ホスト名]、[TCP コネクション]、[転送バイト数]、[転送パケット数] が表示されます。
現在接続中の VPN Server がクラスタコントローラで、管理している仮想 HUB がスタティック仮想 HUB の場合は、すべてのクラスタメンバの当該仮想 HUB に接続しているセッション一覧がすべて結合されて取得されます。
それ以外の場合は、現在管理している VPN Server に実際に接続しているセッション一覧のみが取得されます。
コマンドライン書式 + SessionList
"SessionList" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.83 "SessionGet": セッション情報の取得

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + SessionGet
コマンドの概要 + セッション情報の取得
説明 + 現在管理している仮想 HUB に接続中のセッションを指定して、そのセッションの情報を取得します。セッション情報には、接続元ホスト名やユーザー名、バージョン情報、時刻情報、TCP コネクション数、通信パラメータ、セッションキー、送受信したデータの統計情報、その他のクライアントやサーバーの情報などが含まれます。
現在接続中のセッション一覧を取得するには、SessionList コマンドを使用してください。
コマンドライン書式 + SessionGet [name]
"SessionGet" コマンドで指定することができるパラメータ引数の一覧:
name + 情報を取得するセッション名を指定します。
+

 

+

6.4.84 "SessionDisconnect": セッションの切断

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + SessionDisconnect
コマンドの概要 + セッションの切断
説明 + 現在管理している仮想 HUB に接続中のセッションを指定して、そのセッションを管理者権限で強制切断します。
ただし、接続元のクライアント側の設定で通信が切断された場合は自動的に再接続するオプションが有効になっている場合、クライアントはもう一度接続してくる可能性があります。
現在接続中のセッション一覧を取得するには、SessionList コマンドを使用してください。
コマンドライン書式 + SessionDisconnect [name]
"SessionDisconnect" コマンドで指定することができるパラメータ引数の一覧:
name + 切断するセッション名を指定します。
+

 

+

6.4.85 "MacTable": MAC アドレステーブルデータベースの取得

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + MacTable
コマンドの概要 + MAC アドレステーブルデータベースの取得
説明 + 現在管理している仮想 HUB が保持している MAC アドレステーブルデータベースを取得します。
MAC アドレステーブルデータベースは、仮想 HUB が Ethernet フレームのスイッチング動作を行うために必要なテーブルで、仮想 HUB は MAC アドレステーブルデータベースに基づいて、各 Ethernet フレームの振り分け先セッションを決定します。MAC アドレスデータベースは、仮想 HUB が流れる通信の内容を自動的に分析して構築します。
セッション名を指定して、そのセッションに関連付けられている MAC アドレステーブルエントリを取得することもできます。
コマンドライン書式 + MacTable [session_name]
"MacTable" コマンドで指定することができるパラメータ引数の一覧:
session_name + 引数としてセッション名を指定すると、そのセッションに関連付けられている MAC アドレステーブルエントリのみを表示します。指定しない場合は、すべてのエントリが表示されます。
+

 

+

6.4.86 "MacDelete": MAC アドレステーブルエントリの削除

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + MacDelete
コマンドの概要 + MAC アドレステーブルエントリの削除
説明 + 現在管理している仮想 HUB が保持している MAC アドレステーブルデータベースを操作し、指定された MAC アドレステーブルエントリをデータベースから削除します。
現在の MAC アドレステーブルデータベースの内容を取得するには、MacTable コマンドを使用してください。
コマンドライン書式 + MacDelete [id]
"MacDelete" コマンドで指定することができるパラメータ引数の一覧:
id + 削除する MAC アドレステーブルエントリの ID を指定します。
+

 

+

6.4.87 "IpTable": IP アドレステーブルデータベースの取得

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + IpTable
コマンドの概要 + IP アドレステーブルデータベースの取得
説明 + 現在管理している仮想 HUB が保持している IP アドレステーブルデータベースを取得します。
IP アドレステーブルデータベースは、どのセッションがどの IP アドレスを使用しているかを常に仮想 HUB が把握するために、自動的に通信内容を分析して生成されるテーブルで、仮想 HUB のセキュリティポリシー適用エンジンによって頻繁に使用されています。
セッション名を指定して、そのセッションに関連付けられている IP アドレステーブルエントリを取得することもできます。
コマンドライン書式 + IpTable [session_name]
"IpTable" コマンドで指定することができるパラメータ引数の一覧:
session_name + 引数としてセッション名を指定すると、そのセッションに関連付けられている IP アドレステーブルエントリのみを表示します。指定しない場合は、すべてのエントリが表示されます。
+

 

+

6.4.88 "IpDelete": IP アドレステーブルエントリの削除

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + IpDelete
コマンドの概要 + IP アドレステーブルエントリの削除
説明 + 現在管理している仮想 HUB が保持している IP アドレステーブルデータベースを操作し、指定された IP アドレステーブルエントリをデータベースから削除します。
現在の IP アドレステーブルデータベースの内容を取得するには、IpTable コマンドを使用してください。
コマンドライン書式 + IpDelete [id]
"IpDelete" コマンドで指定することができるパラメータ引数の一覧:
id + 削除する IP アドレステーブルエントリの ID を指定します。
+

 

+

6.4.89 "SecureNatEnable": 仮想 NAT および DHCP サーバー機能 (SecureNAT 機能) の有効化

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + SecureNatEnable
コマンドの概要 + 仮想 NAT および DHCP サーバー機能 (SecureNAT 機能) の有効化
説明 + 現在管理している仮想 HUB 内で、仮想 NAT および DHCP サーバー機能 (SecureNAT 機能) を有効化し、動作を開始します。このコマンドを実行する前に、必ず SecureNatHostGet コマンド、NatGet コマンドおよび DhcpGet コマンドで、現在の仮想 NAT 機能および DHCP サーバー機能の設定内容を確認してください。
SecureNAT 機能を有効にすると、仮想 HUB 内の仮想ネットワークにおいて NAT ルータ (IP マスカレード) や DHCP サーバー機能を仮想的に動作させることができるようになります。

[SecureNAT 機能に関する警告]
SecureNAT 機能はシステム管理者やネットワークに関して詳しい知識のある方向けの機能です。
SecureNAT 機能を正しく使用すると、VPN を経由した安全なリモートアクセスが実現できます。しかし、誤った方法で使用すると、ネットワーク全体を危険な状態にする可能性もあります。ネットワークに関する十分な知識をお持ちでない場合や、ネットワーク管理者の許可を得ていない場合は、SecureNAT 機能を有効にしないでください。SecureNAT 機能に関する詳しい説明は、VPN Server のマニュアルやオンラインドキュメントを参照してください。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + SecureNatEnable
"SecureNatEnable" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.90 "SecureNatDisable": 仮想 NAT および DHCP サーバー機能 (SecureNAT 機能) の無効化

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + SecureNatDisable
コマンドの概要 + 仮想 NAT および DHCP サーバー機能 (SecureNAT 機能) の無効化
説明 + 現在管理している仮想 HUB 内で、仮想 NAT および DHCP サーバー機能 (SecureNAT 機能) を無効化します。このコマンドを実行すると、仮想 NAT 機能は直ちに動作を停止し、仮想 DHCP サーバー機能は保持している DHCP リースデータベースを削除しサービスを停止します。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + SecureNatDisable
"SecureNatDisable" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.91 "SecureNatStatusGet": 仮想 NAT および DHCP サーバー機能 (SecureNAT 機能) の動作状況の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + SecureNatStatusGet
コマンドの概要 + 仮想 NAT および DHCP サーバー機能 (SecureNAT 機能) の動作状況の取得
説明 + 現在管理している仮想 HUB 内で、仮想 NAT および DHCP サーバー機能 (SecureNAT 機能) が動作している場合は、その動作状況を取得します。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + SecureNatStatusGet
"SecureNatStatusGet" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.92 "SecureNatHostGet": SecureNAT 機能の仮想ホストのネットワークインターフェイス設定の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + SecureNatHostGet
コマンドの概要 + SecureNAT 機能の仮想ホストのネットワークインターフェイス設定の取得
説明 + 現在管理している仮想 HUB 内で、仮想 NAT および DHCP サーバー機能 (SecureNAT 機能) の設定項目の内、仮想ホストのネットワークインターフェイスの設定を取得します。
SecureNAT 機能は、仮想 HUB の内部で、L2 セグメント内で 1 枚の仮想的な LAN カードを持ち、MAC アドレスと IP アドレスを割り当てられます。これによって、同一 L2 セグメントに接続している他のホストは、まるで実際の IP ホストがネットワーク上に存在しているかのように SecureNAT の仮想ホストと通信することが可能になります。

[SecureNAT 機能に関する警告]
SecureNAT 機能はシステム管理者やネットワークに関して詳しい知識のある方向けの機能です。
SecureNAT 機能を正しく使用すると、VPN を経由した安全なリモートアクセスが実現できます。しかし、誤った方法で使用すると、ネットワーク全体を危険な状態にする可能性もあります。ネットワークに関する十分な知識をお持ちでない場合や、ネットワーク管理者の許可を得ていない場合は、SecureNAT 機能を有効にしないでください。SecureNAT 機能に関する詳しい説明は、VPN Server のマニュアルやオンラインドキュメントを参照してください。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + SecureNatHostGet
"SecureNatHostGet" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.93 "SecureNatHostSet": SecureNAT 機能の仮想ホストのネットワークインターフェイス設定の変更

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + SecureNatHostSet
コマンドの概要 + SecureNAT 機能の仮想ホストのネットワークインターフェイス設定の変更
説明 + 現在管理している仮想 HUB 内で、仮想 NAT および DHCP サーバー機能 (SecureNAT 機能) の設定項目の内、仮想ホストのネットワークインターフェイスの設定を変更して保存します。
SecureNAT 機能は、仮想 HUB の内部で、L2 セグメント内で 1 枚の仮想的な LAN カードを持ち、MAC アドレスと IP アドレスを割り当てられます。これによって、同一 L2 セグメントに接続している他のホストは、まるで実際の IP ホストがネットワーク上に存在しているかのように SecureNAT の仮想ホストと通信することが可能になります。

[SecureNAT 機能に関する警告]
SecureNAT 機能はシステム管理者やネットワークに関して詳しい知識のある方向けの機能です。
SecureNAT 機能を正しく使用すると、VPN を経由した安全なリモートアクセスが実現できます。しかし、誤った方法で使用すると、ネットワーク全体を危険な状態にする可能性もあります。ネットワークに関する十分な知識をお持ちでない場合や、ネットワーク管理者の許可を得ていない場合は、SecureNAT 機能を有効にしないでください。SecureNAT 機能に関する詳しい説明は、VPN Server のマニュアルやオンラインドキュメントを参照してください。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + SecureNatHostSet [/MAC:mac] [/IP:ip] [/MASK:mask]
"SecureNatHostSet" コマンドで指定することができるパラメータ引数の一覧:
/MAC + 仮想インターフェイスに割り当てる MAC アドレスを指定します。MAC アドレスは "00-AC-01-23-45-67" のように文字列で指定します。/MAC:none を指定すると、現在の設定を変更しません。
/IP + 仮想インターフェイスに割り当てる IP アドレスを指定します。/IP:none を指定すると、現在の設定を変更しません。
/MASK + 仮想インターフェイスに割り当てるサブネットマスクを指定します。/MASK:none を指定すると、現在の設定を変更しません。
+

 

+

6.4.94 "NatGet": SecureNAT 機能の仮想 NAT 機能の設定の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + NatGet
コマンドの概要 + SecureNAT 機能の仮想 NAT 機能の設定の取得
説明 + 現在管理している仮想 HUB 内で、仮想 NAT および DHCP サーバー機能 (SecureNAT 機能) の設定項目の内、仮想 NAT の設定を取得します。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + NatGet
"NatGet" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.95 "NatEnable": SecureNAT 機能の仮想 NAT 機能の有効化

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + NatEnable
コマンドの概要 + SecureNAT 機能の仮想 NAT 機能の有効化
説明 + 現在管理している仮想 HUB 内で、仮想 NAT 機能を有効にします。
このコマンドを用いて仮想 NAT 機能を有効にしても、SecureNAT 機能が動作していない場合は、仮想 NAT は動作しません。SecureNAT 機能の動作を開始するには、SecureNatEnable コマンドを使用します。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + NatEnable
"NatEnable" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.96 "NatDisable": SecureNAT 機能の仮想 NAT 機能の無効化

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + NatDisable
コマンドの概要 + SecureNAT 機能の仮想 NAT 機能の無効化
説明 + 現在管理している仮想 HUB 内で、仮想 NAT 機能を無効にします。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + NatDisable
"NatDisable" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.97 "NatSet": SecureNAT 機能の仮想 NAT 機能の設定の変更

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + NatSet
コマンドの概要 + SecureNAT 機能の仮想 NAT 機能の設定の変更
説明 + 現在管理している仮想 HUB 内の仮想 NAT の設定を変更します。仮想 NAT の設定には、MTU 値、TCP セッションのタイムアウト時間、UDP セッションのタイムアウト時間が含まれます。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + NatSet [/MTU:mtu] [/TCPTIMEOUT:tcp_timeout] [/UDPTIMEOUT:udp_timeout] [/LOG:yes|no]
"NatSet" コマンドで指定することができるパラメータ引数の一覧:
/MTU + MTU (最大転送可能ユニットサイズ) を、バイト数単位の整数で設定します。この値は、仮想 NAT が送出する Ethernet フレームの MAC ヘッダを除いたペイロードの最大長で、デフォルトでは 1500 バイトです。
/TCPTIMEOUT + 仮想 NAT が中継する TCP セッションで、何秒間無通信状態が続けばタイムアウトしセッションを破棄するかを設定します。
/UDPTIMEOUT + 仮想 NAT が中継する UDP セッションで、何秒間無通信状態が続けばタイムアウトしセッションを破棄するかを設定します。
/LOG + 仮想 NAT の動作を、仮想 HUB のセキュリティログに保存するかどうかを指定します。"yes" を指定すると保存され、"no" を指定すると保存しません。
+

 

+

6.4.98 "NatTable": SecureNAT 機能の仮想 NAT 機能のセッションテーブルの取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + NatTable
コマンドの概要 + SecureNAT 機能の仮想 NAT 機能のセッションテーブルの取得
説明 + 現在管理している仮想 HUB 内で仮想 NAT 機能が動作している場合、仮想 NAT を経由して現在通信中の TCP、および UDP のセッションテーブル (NAT テーブル) を取得します。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + NatTable
"NatTable" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.99 "DhcpGet": SecureNAT 機能の仮想 DHCP サーバー機能の設定の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + DhcpGet
コマンドの概要 + SecureNAT 機能の仮想 DHCP サーバー機能の設定の取得
説明 + 現在管理している仮想 HUB 内で、仮想 NAT および DHCP サーバー機能 (SecureNAT 機能) の設定項目の内、仮想 DHCP サーバーの設定を取得します。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + DhcpGet
"DhcpGet" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.100 "DhcpEnable": SecureNAT 機能の仮想 DHCP サーバー機能の有効化

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + DhcpEnable
コマンドの概要 + SecureNAT 機能の仮想 DHCP サーバー機能の有効化
説明 + 現在管理している仮想 HUB 内で、仮想 DHCP サーバー機能を有効にします。
このコマンドを用いて仮想 DHCP 機能を有効にしても、SecureNAT 機能が動作していない場合は、仮想 DHCP サーバーは動作しません。SecureNAT 機能の動作を開始するには、SecureNatEnable コマンドを使用します。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + DhcpEnable
"DhcpEnable" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.101 "DhcpDisable": SecureNAT 機能の仮想 DHCP サーバー機能の無効化

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + DhcpDisable
コマンドの概要 + SecureNAT 機能の仮想 DHCP サーバー機能の無効化
説明 + 現在管理している仮想 HUB 内で、仮想 DHCP サーバー機能を無効にします。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + DhcpDisable
"DhcpDisable" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.102 "DhcpSet": SecureNAT 機能の仮想 DHCP サーバー機能の設定の変更

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + DhcpSet
コマンドの概要 + SecureNAT 機能の仮想 DHCP サーバー機能の設定の変更
説明 + 現在管理している仮想 HUB 内の、仮想 DHCP サーバーの設定を変更します。仮想 DHCP サーバーの設定には、配布 IP アドレス帯、サブネットマスク、リース期限、およびクライアントに割り当てるオプション値が含まれます。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + DhcpSet [/START:start_ip] [/END:end_ip] [/MASK:subnetmask] [/EXPIRE:sec] [/GW:gwip] [/DNS:dns] [/DNS2:dns2] [/DOMAIN:domain] [/LOG:yes|no]
"DhcpSet" コマンドで指定することができるパラメータ引数の一覧:
/START + クライアントに対して配布するアドレス帯の開始点を指定します。(例: 192.168.30.10)
/END + クライアントに対して配布するアドレス帯の終了点を指定します。(例: 192.168.30.200)
/MASK + クライアントに対して指定するサブネットマスクを指定します。(例: 255.255.255.0)
/EXPIRE + クライアントに対して IP アドレスをリースする際の有効期限を秒単位で指定します。
/GW + クライアントに対して通知するデフォルトゲートウェイの IP アドレスを指定します。SecureNAT 機能の仮想 NAT 機能と共に有効にして使用する場合は、SecureNAT の仮想ホストの IP アドレスを指定することもできます。0 または none を指定すると、デフォルトゲートウェイをクライアントに対して通知しません。
/DNS + クライアントに対して通知する DNS サーバー (プライマリ) の IP アドレスを指定します。SecureNAT 機能の仮想 NAT 機能と共に有効にして使用する場合は、SecureNAT の仮想ホストの IP アドレスを指定することもできます。0 または none を指定すると、DNS サーバー アドレスをクライアントに対して通知しません。
/DOMAIN + クライアントに対して通知するドメイン名を指定します。none を指定すると、ドメイン名をクライアントに対して通知しません。
/LOG + 仮想 DHCP サーバーの動作を仮想 HUB のセキュリティログに保存するかどうかを指定します。"yes" を指定すると保存します。この値は、仮想 NAT 機能のログ保存設定と連動しています。
+

 

+

6.4.103 "DhcpTable": SecureNAT 機能の仮想 DHCP サーバー機能のリーステーブルの取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + DhcpTable
コマンドの概要 + SecureNAT 機能の仮想 DHCP サーバー機能のリーステーブルの取得
説明 + 現在管理している仮想 HUB 内で仮想 DHCP サーバー機能が動作している場合、仮想 DHCP サーバーが保持しているクライアントに対して割り当てた IP アドレスのリーステーブルを取得します。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + DhcpTable
"DhcpTable" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.104 "AdminOptionList": 仮想 HUB 管理オプションの一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AdminOptionList
コマンドの概要 + 仮想 HUB 管理オプションの一覧の取得
説明 + 現在管理している仮想 HUB に設定されている仮想 HUB 管理オプションの一覧を取得します。
仮想 HUB 管理オプションは、VPN Server の管理者が各仮想 HUB の管理者に仮想 HUB の管理を委任している場合に、設定範囲を制限するために使用します。
仮想 HUB の管理オプションを追加・編集および削除することができるのは、この VPN Server 全体の管理権限を持った管理者のみです。仮想 HUB の管理者は、管理オプションを表示できますが、変更することはできません。
ただし、allow_hub_admin_change_option が 1 に設定されている場合は、仮想 HUB の管理者でも管理オプションを編集することができます。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + AdminOptionList
"AdminOptionList" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.105 "AdminOptionSet": 仮想 HUB 管理オプションの値の設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AdminOptionSet
コマンドの概要 + 仮想 HUB 管理オプションの値の設定
説明 + 現在管理している仮想 HUB に設定されている仮想 HUB 管理オプションの値を変更します。
仮想 HUB 管理オプションは、VPN Server の管理者が各仮想 HUB の管理者に仮想 HUB の管理を委任している場合に、設定範囲を制限するために使用します。
仮想 HUB の管理オプションを追加・編集および削除することができるのは、この VPN Server 全体の管理権限を持った管理者のみです。仮想 HUB の管理者は、管理オプションを表示できますが、変更することはできません。
ただし、allow_hub_admin_change_option が 1 に設定されている場合は、仮想 HUB の管理者でも管理オプションを編集することができます。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + AdminOptionSet [name] [/VALUE:value]
"AdminOptionSet" コマンドで指定することができるパラメータ引数の一覧:
name + 値を変更する管理オプション名を指定します。AdminOptionList コマンドで名前の一覧を取得できます。
/VALUE + 設定する値を整数で指定します。
+

 

+

6.4.106 "ExtOptionList": 仮想 HUB 拡張オプションの一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ExtOptionList
コマンドの概要 + 仮想 HUB 拡張オプションの一覧の取得
説明 + 現在管理している仮想 HUB に設定されている仮想 HUB 拡張オプションの一覧を取得します。
仮想 HUB 拡張オプションは、仮想 HUB に関するより詳細な設定を行うことができる機能です。
仮想 HUB の管理オプションを追加・編集および削除することができるのは、この VPN Server 全体の管理権限を持った管理者および仮想 HUB の管理者です。
ただし、仮想 HUB 管理オプションの deny_hub_admin_change_ext_option が 1 に設定されている場合は、仮想 HUB の管理者は、拡張オプションを編集することができません。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + ExtOptionList
"ExtOptionList" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.107 "ExtOptionSet": 仮想 HUB 管理オプションの値の設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + ExtOptionSet
コマンドの概要 + 仮想 HUB 管理オプションの値の設定
説明 + 現在管理している仮想 HUB に設定されている仮想 HUB 拡張オプションの値を設定します。
仮想 HUB 拡張オプションは、仮想 HUB に関するより詳細な設定を行うことができる機能です。
仮想 HUB の管理オプションを追加・編集および削除することができるのは、この VPN Server 全体の管理権限を持った管理者および仮想 HUB の管理者です。
ただし、仮想 HUB 管理オプションの deny_hub_admin_change_ext_option が 1 に設定されている場合は、仮想 HUB の管理者は、拡張オプションを編集することができません。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタ内でクラスタメンバサーバーとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + ExtOptionSet [name] [/VALUE:value]
"ExtOptionSet" コマンドで指定することができるパラメータ引数の一覧:
name + 値を変更する拡張オプション名を指定します。ExtOptionList コマンドで名前の一覧を取得できます。
/VALUE + 設定する値を整数で指定します。
+

 

+

6.4.108 "CrlList": 無効な証明書リストの一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CrlList
コマンドの概要 + 無効な証明書リストの一覧の取得
説明 + 現在管理している仮想 HUB に設定されている、無効な証明書リストの一覧を取得します。
無効な証明書の一覧に証明書を登録すると、その証明書を提示したクライアントは、この仮想 HUB に証明書認証モードで接続できなくなります。
通常、この機能は秘密鍵が漏洩したり、証明書を保有する者の権限が失効した場合に、当該証明書を無効として仮想 HUB に登録することにより、その証明書を用いて VPN Client が仮想 HUB に接続しようとした際に、ユーザー認証を拒否するために使用されます。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CrlList
"CrlList" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.109 "CrlAdd": 無効な証明書の追加

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CrlAdd
コマンドの概要 + 無効な証明書の追加
説明 + 現在管理している仮想 HUB に設定されている無効な証明書リストに、新しい無効な証明書の定義を追加します。
無効な証明書の一覧に登録する内容を、このコマンドのパラメータで指定します。仮想 HUB にユーザーが証明書認証モードで接続してきたとき、その証明書が無効な証明書の一覧に登録されている 1 つ以上の内容に一致する場合に、そのユーザーの接続を拒否します。
このコマンドで指定したパラメータで定義されるすべての条件に一致した証明書が、無効として判定されます。
設定できる項目は、[名前 (CN)]、[所属機関 (O)]、[組織単位 (OU)]、[国 (C)]、[都道府県 (ST)]、[ローカル (L)]、[シリアル番号 (16進数)]、[MD5 ダイジェスト値 (16進数, 128 bit)]、[SHA-1 ダイジェスト値 (16進数, 160 bit)] です。ダイジェスト値 (ハッシュ値) の指定は、証明書を事実上一意に指定することになります。通常、MD5 または SHA-1 のダイジェスト値を入力する場合は、その他の項目を入力する必要はありません。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CrlAdd [/SERIAL:serial] [/MD5:md5] [/SHA1:sha1] [/CN:cn] [/O:o] [/OU:ou] [/C:c] [/ST:st] [/L:l]
"CrlAdd" コマンドで指定することができるパラメータ引数の一覧:
/SERIAL + 条件として証明書のシリアル番号 (16進数) を設定する場合はこのパラメータで値を指定します。
/MD5 + 条件として証明書の MD5 ダイジェスト値 (16進数, 128 bit) を設定する場合は、このパラメータで値を指定します。16 進数で 32 文字 (16 Bytes) のパラメータを指定しない場合は無視されます。
/SHA1 + 条件として証明書の SHA1 ダイジェスト値 (16進数, 160 bit) を設定する場合は、このパラメータで値を指定します。16 進数で 40 文字 (20 Bytes) のパラメータを指定しない場合は無視されます。
/CN + 条件として証明書の名前 (CN) を指定する場合は、このパラメータで値を設定します。
/O + 条件として証明書の所属機関 (O) を指定する場合は、このパラメータで値を設定します。
/OU + 条件として証明書の組織単位 (OU) を指定する場合は、このパラメータで値を設定します。
/C + 条件として証明書の国 (C) を指定する場合は、このパラメータで値を設定します。
/ST + 条件として証明書の都道府県 (ST) を指定する場合は、このパラメータで値を設定します。
/L + 条件として証明書のローカル (L) を指定する場合は、このパラメータで値を設定します。
+

 

+

6.4.110 "CrlDel": 無効な証明書の削除

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CrlDel
コマンドの概要 + 無効な証明書の削除
説明 + 現在管理している仮想 HUB に設定されている無効な証明書のリストから、無効な証明書の定義を指定して削除します。
現在登録されている無効な証明書の定義一覧は、CrlList コマンドで取得できます
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CrlDel [id]
"CrlDel" コマンドで指定することができるパラメータ引数の一覧:
id + 削除する無効な証明書の定義の ID を指定します。
+

 

+

6.4.111 "CrlGet": 無効な証明書の取得

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CrlGet
コマンドの概要 + 無効な証明書の取得
説明 + 現在管理している仮想 HUB に設定されている無効な証明書のリストから、無効な証明書の定義を指定して、その定義内容を取得します。
現在登録されている無効な証明書の定義一覧は、CrlList コマンドで取得できます。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + CrlGet [id]
"CrlGet" コマンドで指定することができるパラメータ引数の一覧:
id + 取得する無効な証明書の定義の ID を指定します。
+

 

+

6.4.112 "AcList": 接続元 IP 制限リストのルール一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AcList
コマンドの概要 + 接続元 IP 制限リストのルール一覧の取得
説明 + 現在管理している仮想 HUB に設定されている 接続元 IP 制限リストのルール一覧を取得します。
クライアントコンピュータの接続元 IP アドレスによって、この仮想 HUB への VPN 接続を、許可または拒否することができます。複数のルールを定義することができ、各ルールには優先順位を設定することができます。優先順位が高いルールから検索を行い、最初に IP アドレスが一致したルールの動作に基づいて、そのクライアントからの接続を、許可または拒否します。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + AcList
"AcList" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.4.113 "AcAdd": 接続元 IP 制限リストにルールを追加 (IPv4)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AcAdd
コマンドの概要 + 接続元 IP 制限リストにルールを追加 (IPv4)
説明 + 現在管理している仮想 HUB に設定されている 接続元 IP 制限リストに新しいルールを追加します。
ここで設定した項目は、VPN Client が仮想 HUB に接続しようとした際に、そのクライアントからの接続を許可するか拒否するかを決定するために使用されます。
ルール項目の内容として、ルールに一致するクライアントの IP アドレス、または IP アドレスとマスクを指定することができます。IP アドレスのみを指定すると、単一の指定したコンピュータのみがルールに一致することになりますが、IP ネットワークアドレスとマスクを指定すると、そのサブネットの範囲内のすべてのコンピュータがルールに一致することになります。
ルールには優先順位を設定することができます。優先順位は 1 以上の整数で指定し、値が小さいほど優先順位は高く評価されます。
現在登録されている 接続元 IP 制限リストのルール一覧を取得するには、AcList コマンドを使用します。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + AcAdd [allow|deny] [/PRIORITY:priority] [/IP:ip/mask]
"AcAdd" コマンドで指定することができるパラメータ引数の一覧:
allow|deny + ルールに一致したクライアントからの接続を許可する ("allow") か拒否する ("deny") かを設定します。
/PRIORITY + ルールの優先順位を 1 以上の整数で指定します。値が小さいほど優先順位は高く評価されます。
/IP + [IP アドレス/マスク] の形式で、クライアント IPv4 アドレスの範囲を指定します。IPv4 アドレスは 192.168.0.1 のように、10 進数をドットで区切って指定します。マスクは 255.255.255.0 のように 10 進数をドットで区切って指定するか、24 のように先頭からのビット長を 10 進数で指定します。単一の IPv4 ホストを指定するには、マスクを 255.255.255.255 または 32 として指定します。
+

 

+

6.4.114 "AcDel": 接続元 IP 制限リスト内のルールの削除

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AcDel
コマンドの概要 + 接続元 IP 制限リスト内のルールの削除
説明 + 現在管理している仮想 HUB に設定されている 接続元 IP 制限リストのルールを削除します。
現在登録されている 接続元 IP 制限リストのルール一覧を取得するには、AcList コマンドを使用します。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + AcDel [id]
"AcDel" コマンドで指定することができるパラメータ引数の一覧:
id + 削除する接続元 IP 制限リスト内のルールの ID を指定します。
+

 

+

6.4.115 "AcAdd6": 接続元 IP 制限リストにルールを追加 (IPv6)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AcAdd6
コマンドの概要 + 接続元 IP 制限リストにルールを追加 (IPv6)
説明 + 現在管理している仮想 HUB に設定されている 接続元 IP 制限リストに新しいルールを追加します。
ここで設定した項目は、VPN Client が仮想 HUB に接続しようとした際に、そのクライアントからの接続を許可するか拒否するかを決定するために使用されます。
ルール項目の内容として、ルールに一致するクライアントの IP アドレス、または IP アドレスとマスクを指定することができます。IP アドレスのみを指定すると、単一の指定したコンピュータのみがルールに一致することになりますが、IP ネットワークアドレスとマスクを指定すると、そのサブネットの範囲内のすべてのコンピュータがルールに一致することになります。
ルールには優先順位を設定することができます。優先順位は 1 以上の整数で指定し、値が小さいほど優先順位は高く評価されます。
現在登録されている 接続元 IP 制限リストのルール一覧を取得するには、AcList コマンドを使用します。
このコマンドは、VPN Bridge では実行できません。
このコマンドは、クラスタとして動作している VPN Server の仮想 HUB では実行できません。
コマンドライン書式 + AcAdd6 [allow|deny] [/PRIORITY:priority] [/IP:ip/mask]
"AcAdd6" コマンドで指定することができるパラメータ引数の一覧:
allow|deny + ルールに一致したクライアントからの接続を許可する ("allow") か拒否する ("deny") かを設定します。
/PRIORITY + ルールの優先順位を 1 以上の整数で指定します。値が小さいほど優先順位は高く評価されます。
/IP + [IP アドレス/マスク] の形式で、クライアント IPv6 アドレスの範囲を指定します。IPv6 アドレスは 2001:200:0:1:: のように 16 進数をコロンで区切って指定します。マスクは ffff:ffff:ffff:ffff:: のように IPv6 形式で区切って指定するか、64 のように先頭からのビット長を 10 進数で指定します。単一の IPv6 ホストを指定するには、マスクを ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff または 128 として指定します。
+

 

+ + + + + + + + + + +------ 3 ------ + + + + + + + + + +

6.5.1 "About": バージョン情報の表示

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + About
コマンドの概要 + バージョン情報の表示
説明 + このコマンドライン管理ユーティリティのバージョン情報を表示します。バージョン情報には、vpncmd のバージョン番号、ビルド番号、ビルド情報などが含まれます。
コマンドライン書式 + About
"About" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.5.2 "VersionGet": VPN Client サービスのバージョン情報の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + VersionGet
コマンドの概要 + VPN Client サービスのバージョン情報の取得
説明 + 現在管理している VPN Client サービスプログラムのバージョン情報を取得します。
コマンドライン書式 + VersionGet
"VersionGet" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.5.3 "PasswordSet": VPN Client サービスに接続するためのパスワードの設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + PasswordSet
コマンドの概要 + VPN Client サービスに接続するためのパスワードの設定
説明 + VPN Client サービスに、コマンドライン管理ユーティリティや VPN クライアント接続マネージャなどから接続して制御を行う際に、パスワードの入力を求めることができます。このコマンドを用いて、入力を求めるパスワードを設定することができます。
パスワードは、リモート (localhost 以外のコンピュータ) から操作を行う場合のみ入力させることを要求することもできます。
コマンドライン書式 + PasswordSet [password] [/REMOTEONLY:yes|no]
"PasswordSet" コマンドで指定することができるパラメータ引数の一覧:
password + 設定するパスワードを指定します。"none" と指定すると、パスワードの設定を削除することができます。
/REMOTEONLY + yes を指定すると、パスワードはリモート (localhost 以外のコンピュータ) から操作を行う場合のみ要求され、localhost からの接続時には要求されなくなります。このパラメータを省略した場合は、"no" と見なします。
+

 

+

6.5.4 "PasswordGet": VPN Client サービスに接続するためのパスワードの設定の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + PasswordGet
コマンドの概要 + VPN Client サービスに接続するためのパスワードの設定の取得
説明 + VPN Client サービスに、コマンドライン管理ユーティリティや VPN クライアント接続マネージャなどから接続して制御を行う際に、パスワードの入力を求めるようになっているかどうかの設定を取得します。
また、パスワードを要求する場合についは、リモート (localhost 以外のコンピュータ) から操作を行う場合のみ入力させる設定になっているかどうかも取得します。
コマンドライン書式 + PasswordGet
"PasswordGet" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.5.5 "CertList": 信頼する証明機関の証明書一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CertList
コマンドの概要 + 信頼する証明機関の証明書一覧の取得
説明 + VPN Client が信頼する証明機関の証明書一覧を管理します。登録されている証明機関の証明書一覧は、VPN Server への接続時の、サーバー証明書の検証などに利用されます。
コマンドライン書式 + CertList
"CertList" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.5.6 "CertAdd": 信頼する証明機関の証明書の追加

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CertAdd
コマンドの概要 + 信頼する証明機関の証明書の追加
説明 + VPN Client が信頼する証明機関の証明書一覧に、新しい証明書を追加します。登録された証明機関の証明書一覧は、VPN Server への接続時の、サーバー証明書の検証などに利用されます。
現在の証明書一覧を取得するには、CertList コマンドを使用します。
証明書を追加するには、その証明書が X.509 形式のファイルとして保存されている必要があります。
コマンドライン書式 + CertAdd [path]
"CertAdd" コマンドで指定することができるパラメータ引数の一覧:
path + 登録する X.509 証明書ファイル名を指定します。
+

 

+

6.5.7 "CertDelete": 信頼する証明機関の証明書の削除

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CertDelete
コマンドの概要 + 信頼する証明機関の証明書の削除
説明 + VPN Client が信頼する証明機関の証明書一覧から、既存の証明書を削除します。
現在の証明書一覧を取得するには、CertList コマンドを使用します。
コマンドライン書式 + CertDelete [id]
"CertDelete" コマンドで指定することができるパラメータ引数の一覧:
id + 削除する証明書の ID を指定します。
+

 

+

6.5.8 "CertGet": 信頼する証明機関の証明書の取得

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + CertGet
コマンドの概要 + 信頼する証明機関の証明書の取得
説明 + VPN Client が信頼する証明機関の証明書一覧内の、既存の証明書を取得し、X.509 形式のファイルとして保存します。
コマンドライン書式 + CertGet [id] [/SAVECERT:path]
"CertGet" コマンドで指定することができるパラメータ引数の一覧:
id + 取得する証明書の ID を指定します。
/SAVECERT + 取得した証明書を保存するファイル名を指定します。
+

 

+

6.5.9 "SecureList": 使用できるスマートカードの種類の一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + SecureList
コマンドの概要 + 使用できるスマートカードの種類の一覧の取得
説明 + VPN Client でサポートされているスマートカードの種類の一覧を表示します。
スマートカードの種類の一覧には、現在コンピュータにドライバがインストールされていて、かつ VPN ソフトウェアでサポートされているデバイスの一覧が表示されます。
現在使用しているスマートカードの種類が表示されない場合は、VPN ソフトウェアをより新しいバージョンにアップデートすることにより使用できるようになる場合もあります。
コマンドライン書式 + SecureList
"SecureList" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.5.10 "SecureSelect": 使用するスマートカードの種類の選択

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + SecureSelect
コマンドの概要 + 使用するスマートカードの種類の選択
説明 + VPN Client で使用するスマートカードの種類を選択します。
使用できるスマートカードの種類の一覧は、SecureList コマンドで取得することができます。
コマンドライン書式 + SecureSelect [id]
"SecureSelect" コマンドで指定することができるパラメータ引数の一覧:
id + スマートカードの種類の ID を指定します。
+

 

+

6.5.11 "SecureGet": 使用するスマートカードの種類の ID の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + SecureGet
コマンドの概要 + 使用するスマートカードの種類の ID の取得
説明 + 現在 VPN Client で使用するように設定されているスマートカードの種類の ID を取得します。この ID を元に SecureList コマンドの結果を見ることによって、現在選択されているスマートカードの種類が取得できます。
現在スマートカードが選択されていない場合は、ID が 0 と表示されます。
コマンドライン書式 + SecureGet
"SecureGet" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.5.12 "NicCreate": 新規仮想 LAN カードの作成

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + NicCreate
コマンドの概要 + 新規仮想 LAN カードの作成
説明 + 新しい仮想 LAN カードをシステムに追加します。仮想 LAN カードには任意の名前を付けることができます。
ただし、仮想 LAN カード名に使用することができる文字は英数字のみで、Windows 2000 以降のシステムでは 31 文字まで、Windows 98, 98 SE および ME では 4 文字まで設定することができます。
NicCreate コマンドを呼び出した場合、VPN Client が動作しているオペレーティングシステムに、新しい仮想 LAN カードデバイスドライバがインストールされます。
この場合、オペレーティングシステムによっては、デバイスドライバをインストールしても良いかどうか確認するダイアログボックスが表示される場合があります。
コマンドライン書式 + NicCreate [name]
"NicCreate" コマンドで指定することができるパラメータ引数の一覧:
name + 仮想 LAN カードの名前を指定します。
+

 

+

6.5.13 "NicDelete": 仮想 LAN カードの削除

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + NicDelete
コマンドの概要 + 仮想 LAN カードの削除
説明 + 既存の仮想 LAN カードをシステムから削除します。
システムから仮想 LAN カードを削除すると、その仮想 LAN カードを使用していた接続は切断されます。
また、削除された仮想 LAN カードを使用するように設定されていた接続設定は、別の仮想 LAN カードを使用するように自動的に設定変更されます。
このコマンドは、VPN Client が Windows 2000 以降のオペレーティングシステムで動作している場合に使用できます。
コマンドライン書式 + NicDelete [name]
"NicDelete" コマンドで指定することができるパラメータ引数の一覧:
name + 仮想 LAN カードの名前を指定します。
+

 

+

6.5.14 "NicUpgrade": 仮想 LAN カードのデバイスドライバのアップグレード

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + NicUpgrade
コマンドの概要 + 仮想 LAN カードのデバイスドライバのアップグレード
説明 + 既存の仮想 LAN カードのデバイスドライバのバージョンが古い場合、現在動作している VPN Client に同梱されている最新のデバイスドライバにアップグレードします。アップグレードが行われない場合でも、デバイスドライバを再インストールします。
オペレーティングシステムによっては、デバイスドライバをインストールしても良いかどうか確認するダイアログボックスが表示される場合があります。
このコマンドは、VPN Client が Windows 2000 以降のオペレーティングシステムで動作している場合に使用できます。
コマンドライン書式 + NicUpgrade [name]
"NicUpgrade" コマンドで指定することができるパラメータ引数の一覧:
name + 仮想 LAN カードの名前を指定します。
+

 

+

6.5.15 "NicGetSetting": 仮想 LAN カードの設定の取得

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + NicGetSetting
コマンドの概要 + 仮想 LAN カードの設定の取得
説明 + 既存の仮想 LAN カードの MAC アドレス設定を取得します。
このコマンドは、VPN Client が Windows 2000 以降のオペレーティングシステムで動作している場合に使用できます。
コマンドライン書式 + NicGetSetting [name]
"NicGetSetting" コマンドで指定することができるパラメータ引数の一覧:
name + 仮想 LAN カードの名前を指定します。
+

 

+

6.5.16 "NicSetSetting": 仮想 LAN カードの設定の変更

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + NicSetSetting
コマンドの概要 + 仮想 LAN カードの設定の変更
説明 + 既存の仮想 LAN カードの MAC アドレス設定を変更します。このコマンドを実行すると、現在動作中の仮想 LAN カードデバイスドライバは再起動します。
このコマンドは、VPN Client が Windows 2000 以降のオペレーティングシステムで動作している場合に使用できます。
コマンドライン書式 + NicSetSetting [name] [/MAC:mac]
"NicSetSetting" コマンドで指定することができるパラメータ引数の一覧:
name + 仮想 LAN カードの名前を指定します。
/MAC + 設定する MAC アドレスを指定します。 +MAC アドレスは、6 バイト分の 16 進数を文字列で指定してください。 +例: 00:AC:01:23:45:67 または 00-AC-01-23-45-67
+

 

+

6.5.17 "NicEnable": 仮想 LAN カードの有効化

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + NicEnable
コマンドの概要 + 仮想 LAN カードの有効化
説明 + 既存の仮想 LAN カードが無効化されている場合は、有効化します。
このコマンドは、VPN Client が Windows 2000 以降のオペレーティングシステムで動作している場合に使用できます。
コマンドライン書式 + NicEnable [name]
"NicEnable" コマンドで指定することができるパラメータ引数の一覧:
name + 仮想 LAN カードの名前を指定します。
+

 

+

6.5.18 "NicDisable": 仮想 LAN カードの無効化

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + NicDisable
コマンドの概要 + 仮想 LAN カードの無効化
説明 + 既存の仮想 LAN カードが有効化されている場合は、無効化します。
このコマンドは、VPN Client が Windows 2000 以降のオペレーティングシステムで動作している場合に使用できます。
コマンドライン書式 + NicDisable [name]
"NicDisable" コマンドで指定することができるパラメータ引数の一覧:
name + 仮想 LAN カードの名前を指定します。
+

 

+

6.5.19 "NicList": 仮想 LAN カード一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + NicList
コマンドの概要 + 仮想 LAN カード一覧の取得
説明 + 現在システムに登録されている仮想 LAN カードの一覧を取得します。
コマンドライン書式 + NicList
"NicList" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.5.20 "AccountList": 接続設定一覧の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountList
コマンドの概要 + 接続設定一覧の取得
説明 + VPN Client に登録されている接続設定の一覧を取得します。
コマンドライン書式 + AccountList
"AccountList" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.5.21 "AccountCreate": 新しい接続設定の作成

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountCreate
コマンドの概要 + 新しい接続設定の作成
説明 + VPN Client に新しい接続設定を作成します。
接続設定を作成するには、初期パラメータとして接続設定の名前と接続先のサーバー、および接続先の仮想 HUB、ユーザー名に加えて使用する仮想 LAN カード名を指定する必要があります。新しい接続設定を作成した場合、ユーザー認証の種類は [匿名認証] に初期設定され、プロキシサーバーの設定とサーバー証明書の検証オプションは設定されません。これらの設定やその他の詳細設定を変更するには、接続設定を作成した後に、"Account" という名前で始まる他のコマンドを使用します。
コマンドライン書式 + AccountCreate [name] [/SERVER:hostname:port] [/HUB:hubname] [/USERNAME:username] [/NICNAME:nicname]
"AccountCreate" コマンドで指定することができるパラメータ引数の一覧:
name + 作成する接続設定の名前を指定します。
/SERVER + [ホスト名:ポート番号] の形式で、接続先の VPN Server のホスト名と、ポート番号を指定します。IP アドレスで指定することもできます。
/HUB + 接続先の VPN Server 内の仮想 HUB を指定します。
/USERNAME + 接続先の VPN Server に接続する際の、ユーザー認証で使用するユーザー名を指定します。
/NICNAME + 接続に使用する仮想 LAN カード名を指定します。
+

 

+

6.5.22 "AccountSet": 接続設定の接続先の設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountSet
コマンドの概要 + 接続設定の接続先の設定
説明 + VPN Client に登録されている接続設定の、接続先の VPN Server のホスト名とポート番号、仮想 HUB 名、および接続に使用するユーザー名に加えて使用する仮想 LAN カード名を設定します。
コマンドライン書式 + AccountSet [name] [/SERVER:hostname:port] [/HUB:hubname]
"AccountSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更する接続設定の名前を指定します。
/SERVER + [ホスト名:ポート番号] の形式で、接続先の VPN Server のホスト名と、ポート番号を指定します。IP アドレスで指定することもできます。
/HUB + 接続先の VPN Server 内の仮想 HUB を指定します。
+

 

+

6.5.23 "AccountGet": 接続設定の設定の取得

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountGet
コマンドの概要 + 接続設定の設定の取得
説明 + VPN Client に登録されている接続設定の接続設定内容を取得します。
なお、接続設定の接続設定内容を変更するには、接続設定を作成した後に、"Account" という名前で始まる他のコマンドを使用します。
コマンドライン書式 + AccountGet [name]
"AccountGet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を取得する接続設定の名前を指定します。
+

 

+

6.5.24 "AccountDelete": 接続設定の削除

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountDelete
コマンドの概要 + 接続設定の削除
説明 + VPN Client に登録されている接続設定を削除します。指定された接続設定がオンライン状態である場合は、自動的に接続を切断してから削除します。
コマンドライン書式 + AccountDelete [name]
"AccountDelete" コマンドで指定することができるパラメータ引数の一覧:
name + 削除する接続設定の名前を指定します。
+

 

+

6.5.25 "AccountUsernameSet": 接続設定の接続に使用するユーザー名の設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountUsernameSet
コマンドの概要 + 接続設定の接続に使用するユーザー名の設定
説明 + VPN Client に登録されている接続設定を指定し、その接続設定が VPN Server に接続する際の、ユーザー認証に必要なユーザー名を指定します。
なお、ユーザー認証の種類を指定したり、必要なパラメータを指定したりする必要がある場合があります。これらの情報を変更するには、AccountAnonymousSet、AccountPasswordSet、AccountCertSet、AccountSecureCertSet などのコマンドを使用します。
コマンドライン書式 + AccountUsernameSet [name] [/USERNAME:username]
"AccountUsernameSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更する接続設定の名前を指定します。
/USERNAME + 接続設定が VPN Server に接続する際の、ユーザー認証に必要なユーザー名を指定します。
+

 

+

6.5.26 "AccountAnonymousSet": 接続設定のユーザー認証の種類を匿名認証に設定

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountAnonymousSet
コマンドの概要 + 接続設定のユーザー認証の種類を匿名認証に設定
説明 + VPN Client に登録されている接続設定を指定し、その接続設定が VPN Server に接続する際のユーザー認証の方法を、[匿名認証] に設定します。
コマンドライン書式 + AccountAnonymousSet [name]
"AccountAnonymousSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更する接続設定の名前を指定します。
+

 

+

6.5.27 "AccountPasswordSet": 接続設定のユーザー認証の種類をパスワード認証に設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountPasswordSet
コマンドの概要 + 接続設定のユーザー認証の種類をパスワード認証に設定
説明 + VPN Client に登録されている接続設定を指定し、その接続設定が VPN Server に接続する際のユーザー認証の方法を、[パスワード認証] に設定します。パスワード認証の種類には、[標準パスワード認証] と [RADIUS または NT ドメイン認証] を指定します。
コマンドライン書式 + AccountPasswordSet [name] [/PASSWORD:password] [/TYPE:standard|radius]
"AccountPasswordSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更する接続設定の名前を指定します。
/PASSWORD + パスワード認証で使用するパスワードを指定します。指定しない場合は、パスワードを入力するためのプロンプトが表示されます。
/TYPE + パスワード認証の種類として、"standard" (標準パスワード認証) または "radius" (RADIUS または NT ドメイン認証) の、どちらかを指定します。
+

 

+

6.5.28 "AccountCertSet": 接続設定のユーザー認証の種類をクライアント証明書認証に設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountCertSet
コマンドの概要 + 接続設定のユーザー認証の種類をクライアント証明書認証に設定
説明 + VPN Client に登録されている接続設定を指定し、その接続設定が VPN Server に接続する際のユーザー認証の方法を、[クライアント証明書認証] に設定します。証明書としては、X.509 形式の証明書ファイルと、Base 64 でエンコードされた対応した秘密鍵ファイルを指定する必要があります。
コマンドライン書式 + AccountCertSet [name] [/LOADCERT:cert] [/LOADKEY:key]
"AccountCertSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更する接続設定の名前を指定します。
/LOADCERT + 証明書認証で提示する X.509 形式の証明書ファイル名を指定します。
/LOADKEY + 証明書に対応した Base 64 形式でエンコードされた秘密鍵ファイル名を指定します。
+

 

+

6.5.29 "AccountCertGet": 接続設定に用いるクライアント証明書の取得

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountCertGet
コマンドの概要 + 接続設定に用いるクライアント証明書の取得
説明 + VPN Client に登録されている接続設定を指定し、その接続設定がクライアント証明書認証を使用する場合は、クライアント証明書として提示する証明書を取得して、証明書ファイルを X.509 形式で保存します。
コマンドライン書式 + AccountCertGet [name] [/SAVECERT:cert]
"AccountCertGet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を取得する接続設定の名前を指定します。
/SAVECERT + 取得した証明書を X.509 形式で保存するファイル名を指定します。
+

 

+

6.5.30 "AccountEncryptDisable": 接続設定の通信時の暗号化の無効化

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountEncryptDisable
コマンドの概要 + 接続設定の通信時の暗号化の無効化
説明 + VPN Client に登録されている接続設定を指定し、その接続設定が VPN Server との間で VPN 接続を行なって通信をする際に、VPN Server との間の通信内容を暗号化しないように設定します。
通常は、VPN Server との間の通信を SSL で暗号化して、情報の盗聴や改ざんを防止します。暗号化を無効にすることもできます。暗号化を無効にすると、通信のスループットが向上しますが、通信データは平文でネットワーク上を流れます。
コマンドライン書式 + AccountEncryptDisable [name]
"AccountEncryptDisable" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更する接続設定の名前を指定します。
+

 

+

6.5.31 "AccountEncryptEnable": 接続設定の通信時の暗号化の有効化

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountEncryptEnable
コマンドの概要 + 接続設定の通信時の暗号化の有効化
説明 + VPN Client に登録されている接続設定を指定し、その接続設定が VPN Server との間で VPN 接続を行なって通信をする際に、VPN Server との間の通信内容を SSL で暗号化するように設定します。
通常は、VPN Server との間の通信を SSL で暗号化して、情報の盗聴や改ざんを防止します。暗号化を無効にすることもできます。暗号化を無効にすると、通信のスループットが向上しますが、通信データは平文でネットワーク上を流れます。
コマンドライン書式 + AccountEncryptEnable [name]
"AccountEncryptEnable" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更する接続設定の名前を指定します。
+

 

+

6.5.32 "AccountCompressEnable": 接続設定の通信時のデータ圧縮の有効化

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountCompressEnable
コマンドの概要 + 接続設定の通信時のデータ圧縮の有効化
説明 + VPN Client に登録されている接続設定を指定し、その接続設定が VPN Server との間で VPN 接続を行なって通信をする際に、VPN Server との間の通信内容を圧縮するように設定します。
最大で約 80 % 程度の圧縮を行うことができます。ただし、圧縮を行うと、クライアントおよびサーバーの両方で CPU 負荷が高くなります。回線速度が約 10 Mbps 以上の場合は、圧縮を行うとスループットが低下し、逆効果となる場合があります。
コマンドライン書式 + AccountCompressEnable [name]
"AccountCompressEnable" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更する接続設定の名前を指定します。
+

 

+

6.5.33 "AccountCompressDisable": 接続設定の通信時のデータ圧縮の無効化

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountCompressDisable
コマンドの概要 + 接続設定の通信時のデータ圧縮の無効化
説明 + VPN Client に登録されている接続設定を指定し、その接続設定が VPN Server との間で VPN 接続を行なって通信をする際に、VPN Server との間の通信内容を圧縮しないように設定します。
コマンドライン書式 + AccountCompressDisable [name]
"AccountCompressDisable" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更する接続設定の名前を指定します。
+

 

+

6.5.34 "AccountProxyNone": 接続設定の接続方法を直接 TCP/IP 接続に設定

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountProxyNone
コマンドの概要 + 接続設定の接続方法を直接 TCP/IP 接続に設定
説明 + VPN Client に登録されている接続設定を指定し、その接続設定が VPN Server に対して接続する際に使用する接続方法を [直接 TCP/IP 接続] に設定し、プロキシサーバーを経由しないようにします。
コマンドライン書式 + AccountProxyNone [name]
"AccountProxyNone" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更する接続設定の名前を指定します。
+

 

+

6.5.35 "AccountProxyHttp": 接続設定の接続方法を HTTP プロキシサーバー経由接続に設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountProxyHttp
コマンドの概要 + 接続設定の接続方法を HTTP プロキシサーバー経由接続に設定
説明 + VPN Client に登録されている接続設定を指定し、その接続設定が VPN Server に対して接続する際に使用する接続方法を [HTTP プロキシサーバー経由接続] に設定し、経由する HTTP プロキシサーバーのホスト名とポート番号、ユーザー名とパスワード (必要な場合) を指定します。
経由する HTTP プロキシサーバーは、HTTPS 通信をするための CONNECT メソッドに対応している必要があります。
コマンドライン書式 + AccountProxyHttp [name] [/SERVER:hostname:port] [/USERNAME:username] [/PASSWORD:password]
"AccountProxyHttp" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更する接続設定の名前を指定します。
/SERVER + [ホスト名:ポート番号] の形式で、経由する HTTP プロキシサーバーのホスト名、または IP アドレスとポート番号を指定します。
/PASSWORD + 経由する HTTP プロキシサーバーに接続するためにユーザー認証が必要な場合、パスワードを指定します。/USERNAME パラメータと共に指定します。
+

 

+

6.5.36 "AccountProxySocks": 接続設定の接続方法を SOCKS プロキシサーバー経由接続に設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountProxySocks
コマンドの概要 + 接続設定の接続方法を SOCKS プロキシサーバー経由接続に設定
説明 + VPN Client に登録されている接続設定を指定し、その接続設定が VPN Server に対して接続する際に使用する接続方法を [SOCKS プロキシサーバー経由接続] に設定し、経由する SOCKS プロキシサーバーのホスト名とポート番号、ユーザー名とパスワード (必要な場合) を指定します。
経由する SOCKS サーバーは、SOCKS バージョン 4 に対応している必要があります。
コマンドライン書式 + AccountProxySocks [name] [/SERVER:hostname:port] [/USERNAME:username] [/PASSWORD:password]
"AccountProxySocks" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更する接続設定の名前を指定します。
/SERVER + [ホスト名:ポート番号] の形式で、経由する SOCKS プロキシサーバーのホスト名、または IP アドレスとポート番号を指定します。
/PASSWORD + 経由する SOCKS プロキシサーバーに接続するためにユーザー認証が必要な場合、パスワードを指定します。/USERNAME パラメータと共に指定します。
+

 

+

6.5.37 "AccountServerCertEnable": 接続設定のサーバー証明書の検証オプションの有効化

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountServerCertEnable
コマンドの概要 + 接続設定のサーバー証明書の検証オプションの有効化
説明 + VPN Client に登録されている接続設定を指定し、その接続設定が VPN Server に対して接続する際に、接続先の VPN Server の提示する SSL 証明書が信頼できるかどうか検査するオプションを有効にします。
このオプションが有効になっている場合、接続先サーバーの SSL 証明書を、あらかじめ AccountServerCertSet コマンドで接続設定設定内に保存しておくか、または仮想 HUB の信頼する証明機関の証明書一覧に、サーバーの SSL 証明書を署名したルート証明書を CertAdd コマンドなどで登録しておくことを推奨します。登録されていない場合は、初回接続時に確認のメッセージが表示される場合があります。
接続設定のサーバー証明書の検証オプションが有効になっている状態で、接続した VPN Server の証明書が信頼できない場合、直ちに接続を解除して再試行を繰り返します。
コマンドライン書式 + AccountServerCertEnable [name]
"AccountServerCertEnable" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更する接続設定の名前を指定します。
+

 

+

6.5.38 "AccountServerCertDisable": 接続設定のサーバー証明書の検証オプションの無効化

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountServerCertDisable
コマンドの概要 + 接続設定のサーバー証明書の検証オプションの無効化
説明 + VPN Client に登録されている接続設定を指定し、その接続設定が VPN Server に対して接続する際に、接続先の VPN Server の提示する SSL 証明書が信頼できるかどうか検査するオプションを無効にします。
コマンドライン書式 + AccountServerCertDisable [name]
"AccountServerCertDisable" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更する接続設定の名前を指定します。
+

 

+

6.5.39 "AccountServerCertSet": 接続設定のサーバー固有証明書の設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountServerCertSet
コマンドの概要 + 接続設定のサーバー固有証明書の設定
説明 + VPN Client に登録されている接続設定を指定し、その接続設定が VPN Server に対して接続する際に、接続先の VPN Server の提示する SSL 証明書と同じ証明書をあらかじめ登録します。
接続設定のサーバー証明書の検証オプションが有効になっている場合、接続先サーバーの SSL 証明書をあらかじめこのコマンドで接続設定設定内に保存しておくか、または仮想 HUB の信頼する証明機関の証明書一覧に、サーバーの SSL 証明書を署名したルート証明書を CAAdd コマンドなどで登録しておく必要があります。
接続設定のサーバー証明書の検証オプションが有効になっている状態で、接続した VPN Server の証明書が信頼できない場合、直ちに接続を解除して再試行を繰り返します。
コマンドライン書式 + AccountServerCertSet [name] [/LOADCERT:cert]
"AccountServerCertSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更する接続設定の名前を指定します。
/LOADCERT + 設定するサーバー固有証明書が保存されている、X.509 形式の証明書ファイル名を指定します。
+

 

+

6.5.40 "AccountServerCertDelete": 接続設定のサーバー固有証明書の削除

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountServerCertDelete
コマンドの概要 + 接続設定のサーバー固有証明書の削除
説明 + VPN Client に登録されている接続設定を指定し、その接続設定にサーバー固有証明書が登録されている場合は、それを削除します。
コマンドライン書式 + AccountServerCertDelete [name]
"AccountServerCertDelete" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更する接続設定の名前を指定します。
+

 

+

6.5.41 "AccountServerCertGet": 接続設定のサーバー固有証明書の取得

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountServerCertGet
コマンドの概要 + 接続設定のサーバー固有証明書の取得
説明 + VPN Client に登録されている接続設定を指定し、その接続設定にサーバー固有証明書が登録されている場合はその証明書を取得して、X.509 形式の証明書ファイルとして保存します。
コマンドライン書式 + AccountServerCertGet [name] [/SAVECERT:path]
"AccountServerCertGet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更する接続設定の名前を指定します。
/SAVECERT + サーバー固有証明書を X.509 形式で保存する証明書ファイル名を指定します。
+

 

+

6.5.42 "AccountDetailSet": 接続設定の高度な通信設定の設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountDetailSet
コマンドの概要 + 接続設定の高度な通信設定の設定
説明 + VPN Client に登録されている接続設定を指定し、その接続設定が VPN Server と通信する際に使用される VPN プロトコルの通信設定をカスタマイズします。
コマンドライン書式 + AccountDetailSet [name] [/MAXTCP:max_connection] [/INTERVAL:additional_interval] [/TTL:disconnect_span] [/HALF:yes|no] [/BRIDGE:yes|no] [/MONITOR:yes|no] [/NOTRACK:yes|no] [/NOQOS:yes|no]
"AccountDetailSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更する接続設定の名前を指定します。
/MAXTCP + VPN 通信に使用する TCP コネクション数を、1 以上 32 以下の整数で指定します。VPN Server との間の VPN 通信セッションにおけるデータ伝送に、複数本の TCP コネクションを束ねて使用することにより、通信速度を向上できる場合があります。 +注意: サーバーへの接続回線が高速な場合は 8 本程度を、ダイヤルアップ等の低速な場合は 1 本をお勧めします。
/INTERVAL + 複数の TCP コネクションを確立して VPN 通信を行うとき、各 TCP コネクションの確立間隔を秒単位で指定します。規定値は 1 秒です。
/TTL + 各 TCP コネクションの寿命を設定する場合は、TCP コネクションが確立されてから切断されるまでの寿命を、秒数で指定します。0 を指定すると、寿命は設定されません。
/HALF + 半二重モードを有効にする場合は "yes" を指定します。2 本以上の TCP コネクションを束ねて VPN 通信を行う際、「半二重モード」を使用することができます。半二重モードを有効にすると、自動的に各 TCP コネクションのデータ伝送方向を、半数ずつ固定することができます。たとえば、8 本の TCP コネクションを使用して VPN セッションを確立した場合、半二重モードを有効にすると、4 本の TCP コネクションはアップロード方向専用、残りの 4 本のコネクションはダウンロード方向専用に固定され通信が行われます。
/BRIDGE + VPN Server に「ブリッジ / ルータモード」で接続する場合は "yes" を指定します。ブリッジ / ルータモードを使用して接続した場合、VPN Client の仮想 LAN カードの側で、別のネットワークにブリッジしたりルーティングしたりすることができるようになります。ただし、接続に使用するユーザーのセキュリティポリシーで、ブリッジまたはルーティングが禁止されている場合は、接続に失敗します。
/MONITOR + VPN Server に「モニタリングモード」で接続する場合は "yes" を指定します。モニタリングモードを使用して接続した場合、仮想 HUB 内を流れるすべてのパケットを受信することができます。ただし、接続に使用するユーザーのセキュリティポリシーで、モニタリングモードが許可されていない場合は、接続に失敗します。
/NOTRACK + ルーティングテーブルの調整処理を行わない場合は "yes" を指定します。通常は "no" を指定します。
/NOQOS + VoIP / QoS 対応機能を無効にする場合は "yes" を指定します。通常は "no" を指定します。
+

 

+

6.5.43 "AccountRename": 接続設定の名前の変更

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountRename
コマンドの概要 + 接続設定の名前の変更
説明 + VPN Client に登録されている接続設定を指定し、その接続設定の名前を変更します。
コマンドライン書式 + AccountRename [name] [/NEW:new_name]
"AccountRename" コマンドで指定することができるパラメータ引数の一覧:
name + 名前を変更する接続設定の現在の名前を指定します。
/NEW + 変更後の新しい名前を指定します。
+

 

+

6.5.44 "AccountConnect": 接続設定を使用して VPN Server へ接続を開始

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountConnect
コマンドの概要 + 接続設定を使用して VPN Server へ接続を開始
説明 + VPN Client に登録されている接続設定を指定し、その接続設定を使用して VPN Server への接続を開始します。接続処理中、または接続済みの状態になった接続設定は、AccountDisconnect コマンドで切断するまで VPN Server に常時接続、または接続を試行し続けます (ただし AccountRetrySet コマンドで再試行回数を指定してある場合は、指定された回数で試行を中断します)。
コマンドライン書式 + AccountConnect [name]
"AccountConnect" コマンドで指定することができるパラメータ引数の一覧:
name + 接続を開始する接続設定の名前を指定します。
+

 

+

6.5.45 "AccountDisconnect": 接続中の接続設定の切断

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountDisconnect
コマンドの概要 + 接続中の接続設定の切断
説明 + VPN Client に登録されている接続設定を指定し、その接続設定が接続処理中、または接続済みの状態である場合は直ちに切断します。
コマンドライン書式 + AccountDisconnect [name]
"AccountDisconnect" コマンドで指定することができるパラメータ引数の一覧:
name + 切断する接続設定の名前を指定します。
+

 

+

6.5.46 "AccountStatusGet": 接続設定の現在の状態の取得

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountStatusGet
コマンドの概要 + 接続設定の現在の状態の取得
説明 + VPN Client に登録されている接続設定を指定し、その接続設定が現在接続済みである場合は、その接続状態やその他の情報を取得します。
コマンドライン書式 + AccountStatusGet [name]
"AccountStatusGet" コマンドで指定することができるパラメータ引数の一覧:
name + 情報を取得する接続設定の名前を指定します。
+

 

+

6.5.47 "AccountNicSet": 接続設定で使用する仮想 LAN カードの設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountNicSet
コマンドの概要 + 接続設定で使用する仮想 LAN カードの設定
説明 + VPN Client に登録されている既存の接続設定が VPN Server への接続に使用する仮想 LAN カード名を変更します。
コマンドライン書式 + AccountNicSet [name] [/NICNAME:nicname]
"AccountNicSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更する接続設定の名前を指定します。
/NICNAME + VPN Server に接続する際に使用する仮想 LAN カード名を指定します。
+

 

+

6.5.48 "AccountStatusShow": VPN Server への接続中に接続状況やエラー画面を表示するように設定

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountStatusShow
コマンドの概要 + VPN Server への接続中に接続状況やエラー画面を表示するように設定
説明 + VPN Client に登録されている接続設定を指定し、その接続設定を用いて VPN Server に接続する際に、接続状況やエラー画面などをコンピュータのディスプレイ上に表示するように設定します。
コマンドライン書式 + AccountStatusShow [name]
"AccountStatusShow" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更する接続設定の名前を指定します。
+

 

+

6.5.49 "AccountStatusHide": VPN Server への接続中に接続状況やエラー画面を表示しないように設定

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountStatusHide
コマンドの概要 + VPN Server への接続中に接続状況やエラー画面を表示しないように設定
説明 + VPN Client に登録されている接続設定を指定し、その接続設定を用いて VPN Server に接続する際に、接続状況やエラー画面などをコンピュータのディスプレイ上に表示しないように設定します。
コマンドライン書式 + AccountStatusHide [name]
"AccountStatusHide" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更する接続設定の名前を指定します。
+

 

+

6.5.50 "AccountSecureCertSet": 接続設定のユーザー認証の種類をスマートカード認証に設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountSecureCertSet
コマンドの概要 + 接続設定のユーザー認証の種類をスマートカード認証に設定
説明 + VPN Client に登録されている接続設定を指定し、その接続設定が VPN Server に接続する際のユーザー認証の方法を [スマートカード認証] に設定します。また、スマートカード内に格納されている証明書オブジェクトと秘密鍵オブジェクトの名前を指定する必要があります。
コマンドライン書式 + AccountSecureCertSet [name] [/CERTNAME:cert] [/KEYNAME:key]
"AccountSecureCertSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更する接続設定の名前を指定します。
/CERTNAME + スマートカード内に格納されている証明書オブジェクトの名前を指定します。
/KEYNAME + スマートカード内に格納されている秘密鍵オブジェクトの名前を指定します。/CERTNAME で指定した証明書に対応している必要があります。
+

 

+

6.5.51 "AccountRetrySet": 接続設定の接続失敗または切断時の再試行回数と間隔の設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountRetrySet
コマンドの概要 + 接続設定の接続失敗または切断時の再試行回数と間隔の設定
説明 + VPN Client に登録されている接続設定を指定し、その接続設定が VPN Server に接続しようとする際、または接続中に VPN Server との通信が切断されたり、接続に失敗したりした場合に、接続を再試行する回数と接続再試行間隔を指定します。
なお、ユーザー認証の種類が [スマートカード認証] の場合は、接続試行回数の設定にかかわらず、再試行は行いません。
コマンドライン書式 + AccountRetrySet [name] [/NUM:num_retry] [/INTERVAL:retry_interval]
"AccountRetrySet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更する接続設定の名前を指定します。
/NUM + 連続して再接続を行う回数を指定します。"999" と指定すると、無限に再接続を試行します (常時接続)。0 を指定すると再接続を行いません。
/INTERVAL + 再接続を行う場合、前回接続が切断または接続失敗してから、何秒後に再接続処理を開始するかを設定します。
+

 

+

6.5.52 "AccountStartupSet": 接続設定をスタートアップ接続に設定

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountStartupSet
コマンドの概要 + 接続設定をスタートアップ接続に設定
説明 + VPN Client に登録されている接続設定を指定し、その接続設定をスタートアップ接続に設定します。スタートアップ接続に設定されている接続設定は、VPN Client サービスが起動すると同時に自動的に接続処理を開始します。
コマンドライン書式 + AccountStartupSet [name]
"AccountStartupSet" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更する接続設定の名前を指定します。
+

 

+

6.5.53 "AccountStartupRemove": 接続設定のスタートアップ接続を解除

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountStartupRemove
コマンドの概要 + 接続設定のスタートアップ接続を解除
説明 + VPN Client に登録されている接続設定を指定し、その接続設定が現在スタートアップ接続に設定されている場合は、スタートアップ接続設定を解除します。
コマンドライン書式 + AccountStartupRemove [name]
"AccountStartupRemove" コマンドで指定することができるパラメータ引数の一覧:
name + 設定を変更する接続設定の名前を指定します。
+

 

+

6.5.54 "AccountExport": 接続設定のエクスポート

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountExport
コマンドの概要 + 接続設定のエクスポート
説明 + VPN Client に登録されている接続設定を指定し、その接続設定の内容を、テキストファイルとしてエクスポートします。エクスポートされた接続設定ファイルを後からインポートすることによって、接続設定の内容を複製することができます。また、テキストファイルで保存されるため、一般的なテキストエディタで編集することも可能です。
エクスポート先のファイルは、UTF-8 形式のテキストファイルとして保存されます。なお、ファイル名に .vpn という拡張子を付けると、Windows 版 VPN クライアント接続マネージャと関連付けされるので便利です。
コマンドライン書式 + AccountExport [name] [/SAVEPATH:savepath]
"AccountExport" コマンドで指定することができるパラメータ引数の一覧:
name + 接続設定をエクスポートする接続設定名を指定します。
/SAVEPATH + 保存先のファイル名を指定します。
+

 

+

6.5.55 "AccountImport": 接続設定のインポート

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + AccountImport
コマンドの概要 + 接続設定のインポート
説明 + AccountExport コマンドによってエクスポートされた接続設定ファイルをインポートし、VPN Client に追加します。
コマンドライン書式 + AccountImport [path]
"AccountImport" コマンドで指定することができるパラメータ引数の一覧:
path + インポート元のファイル名を指定します。
+

 

+

6.5.56 "RemoteEnable": VPN Client サービスのリモート管理の許可

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + RemoteEnable
コマンドの概要 + VPN Client サービスのリモート管理の許可
説明 + VPN Client サービスに、localhost 以外のリモートコンピュータから、コマンドライン管理ユーティリティまたは VPN クライアント接続マネージャでリモート接続して管理することを許可します。
コマンドライン書式 + RemoteEnable
"RemoteEnable" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.5.57 "RemoteDisable": VPN Client サービスのリモート管理の禁止

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + RemoteDisable
コマンドの概要 + VPN Client サービスのリモート管理の禁止
説明 + VPN Client サービスに、localhost 以外のリモートコンピュータからコマンドライン管理ユーティリティまたは VPN クライアント接続マネージャでリモート接続して管理することを禁止します。
コマンドライン書式 + RemoteDisable
"RemoteDisable" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.5.58 "KeepEnable": インターネット接続の維持機能の有効化

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + KeepEnable
コマンドの概要 + インターネット接続の維持機能の有効化
説明 + [インターネット接続の維持機能] を有効にします。[インターネット接続の維持機能] を使用すると、一定期間無通信状態が続くと、自動的に接続が切断されるようなネットワーク接続環境の場合、インターネット上の任意のサーバーに対して一定間隔ごとにパケットを送信することにより、インターネット接続を維持することができます。
接続先のホスト名などについては、KeepSet コマンドで設定することができます。
VPN Server または VPN Bridge で、このコマンドを実行するには、管理者権限が必要です。
コマンドライン書式 + KeepEnable
"KeepEnable" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.5.59 "KeepDisable": インターネット接続の維持機能の無効化

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + KeepDisable
コマンドの概要 + インターネット接続の維持機能の無効化
説明 + [インターネット接続の維持機能] を無効にします。
VPN Server または VPN Bridge で、このコマンドを実行するには、管理者権限が必要です。
コマンドライン書式 + KeepDisable
"KeepDisable" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.5.60 "KeepSet": インターネット接続の維持機能の設定

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + KeepSet
コマンドの概要 + インターネット接続の維持機能の設定
説明 + [インターネット接続の維持機能] の接続先ホスト名などの設定を行ないます。一定期間無通信状態が続くと自動的に接続が切断されるようなネットワーク接続環境で、[インターネット接続の維持機能] を使用すると、インターネット上の任意のサーバーに対して、一定間隔ごとにパケットを送信することにより、インターネット接続を維持することができます。
このコマンドでは、通信先の [ホスト名]、[ポート番号]、[パケット送出間隔]、および [プロトコル] を指定することができます。
インターネット接続維持のために送信されるパケットは、ランダムな内容であり、コンピュータやユーザーを識別する個人情報などが送信されることはありません。
インターネット接続の維持機能は、KeepEnable コマンド、または KeepDisable コマンドを用いて、有効化 / 無効化することができます。KeepSet は有効 / 無効の状態を変更しません。
VPN Server または VPN Bridge で、このコマンドを実行するには、管理者権限が必要です。
コマンドライン書式 + KeepSet [/HOST:host:port] [/PROTOCOL:tcp|udp] [/INTERVAL:interval]
"KeepSet" コマンドで指定することができるパラメータ引数の一覧:
/HOST + [ホスト名:ポート番号] の形式で、通信先のホスト名、または IP アドレスとポート番号を指定します。
/PROTOCOL + tcp または udp を指定します。
/INTERVAL + パケットを送出する間隔を秒単位で指定します。
+

 

+

6.5.61 "KeepGet": インターネット接続の維持機能の取得

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + KeepGet
コマンドの概要 + インターネット接続の維持機能の取得
説明 + [インターネット接続の維持機能] の、現在の設定内容を取得します。通信先の [ホスト名]、[ポート番号]、[パケット送出間隔]、および [プロトコル] に加えて、現在の [インターネット接続の維持機能] の有効状態が取得できます。
コマンドライン書式 + KeepGet
"KeepGet" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.5.62 "MakeCert": 新しい X.509 証明書と秘密鍵の作成

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + MakeCert
コマンドの概要 + 新しい X.509 証明書と秘密鍵の作成
説明 + 新しい X.509 証明書と秘密鍵を作成し、ファイルとして保存します。
証明書の公開鍵と秘密鍵の生成アルゴリズムには、RSA 1024 bit が使用されます。
証明書の種類として、ルート証明書 (自己署名証明書) と他の証明書によって署名された証明書のどちらでも作成することができます。他の証明書によって署名された証明書を作成するためには、署名に使用する証明書 (X.509 形式のファイル) と対応する秘密鍵ファイル (Base 64 エンコード) が必要です。

作成する証明書には、名前 (CN)、所属機関 (O)、組織単位 (OU)、国 (C)、都道府県 (ST)、ローカル (L)、シリアル番号、有効期限を指定することができます。
作成された証明書は X.509 形式のファイルとして、秘密鍵ファイルは RSA 1024 bit 形式の Base 64 エンコードされたファイルとしてそれぞれ保存されます。

MakeCert コマンドは、証明書を作成するための必要最低限の機能を用意したツールです。本格的な証明書を作成したい場合は、OpenSSL などのフリーソフトや、市販の CA (証明機関) ソフトウェアを使用することを推奨します。

※注意: このコマンドは PacketiX VPN コマンドライン管理ユーティリティから呼び出すことが可能です。現在 VPN Server や VPN Client に管理モードで接続している場合も実行できますが、実際に RSA 演算を行い、証明書データを生成しファイルに保存するのはこのコマンドを実行しているコンピュータであり、管理モードで接続先のコンピュータとは一切関係ないコンテキストで実行されます。
コマンドライン書式 + MakeCert [/CN:cn] [/O:o] [/OU:ou] [/C:c] [/ST:st] [/L:l] [/SERIAL:serial] [/EXPIRES:expires] [/SIGNCERT:signcert] [/SIGNKEY:signkey] [/SAVECERT:savecert] [/SAVEKEY:savekey]
"MakeCert" コマンドで指定することができるパラメータ引数の一覧:
/CN + 作成する証明書の名前 (CN) 項目を指定します。none を指定することもできます。
/O + 作成する証明書の所属機関 (O) 項目を指定します。none を指定することもできます。
/OU + 作成する証明書の組織単位 (OU) 項目を指定します。none を指定することもできます。
/C + 作成する証明書の国 (C) 項目を指定します。none を指定することもできます。
/ST + 作成する証明書の都道府県 (ST) 項目を指定します。none を指定することもできます。
/L + 作成する証明書のローカル (L) 項目を指定します。none を指定することもできます。
/SERIAL + 作成する証明書のシリアル番号項目を指定します。16 進数で指定します。none を指定することもできます。
/EXPIRES + 作成する証明書の有効期限を指定します。none または 0 を指定すると、3650 日 (約 10 年) が使用されます。最大 10950 日 (約 30 年) まで指定できます。
/SIGNCERT + 作成する証明書を、既存の証明書によって署名する場合は、署名に使用する X.509 形式の証明書のファイル名を指定します。パラメータを省略した場合は、署名は行わず新しい証明書をルート証明書として作成します。
/SIGNKEY + /SIGNCERT で指定した証明書に対応する秘密鍵 (RSA, Base-64 エンコード) を指定します。
/SAVECERT + 作成した証明書を保存するファイル名を指定します。証明書は RSA 形式の 1024 bit の公開鍵を含んだ X.509 ファイルとして保存されます。
/SAVEKEY + 作成した証明書に対応する秘密鍵を保存するファイル名を指定します。秘密鍵は RSA 形式の 1024 bit の秘密鍵ファイルとして保存されます。
+

 

+

6.5.63 "TrafficClient": 通信スループット測定ツールクライアントの実行

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + TrafficClient
コマンドの概要 + 通信スループット測定ツールクライアントの実行
説明 + 通信スループット測定ツールの、クライアントプログラムを実行します。
通信スループット測定ツールは TrafficClient と TrafficServer の 2 つのコマンドとして利用し、IP ネットワーク上で接続された 2 台のコンピュータの間で伝送することができる通信スループットを計測することができます。すでに別のコンピュータ上で、TrafficServer コマンドを用いて通信スループット測定ツールサーバーを待機させておき、TrafficClient コマンドで、そのサーバーのホスト名または IP アドレスとポート番号を指定して接続し、通信速度を測定することができます。
通信速度の測定は、同時に複数本の TCP コネクションを確立し、それぞれのコネクションで最大限にストリームデータを伝送した結果、指定された時間内に実際に伝送することができたデータのビット数を計算し、それを元に通信スループットの平均値 (bps) を算出する方法で行われます。通常、1 本の TCP コネクションを用いた場合は TCP のアルゴリズム上の限界により、実際のネットワークスループットよりも遅い速度でしか通信できない場合が多いため、複数本の TCP コネクションを同時に確立して通信した結果を測定することを推奨します。この測定方法によって計測されたスループットは実際に TCP でストリームとして受信側に届いたデータのビット長から計算されるため、途中で発生したパケットロスやデータ破損したパケットは、実際に届いたパケットには含まれず、純粋なネットワークの最大通信可能帯域幅に近い値を算出することができます。
測定結果として TCP 内で伝送されたストリームサイズから、実際にネットワーク上を流れたデータ量の近似値を計算し、それを時間で割ってビット毎秒 (bps) を算出します。物理的なネットワークの種類は Ethernet (IEEE802.3) で、MAC フレームのペイロードサイズは 1,500 Bytes (TCP の MSS は 1,460 Bytes) と仮定して計算が行われます。/RAW オプションを指定すると、TCP/IP ヘッダや MAC ヘッダのデータ量を補正する計算は行われません。

※注意: このコマンドは PacketiX VPN コマンドライン管理ユーティリティから呼び出すことが可能です。現在 VPN Server や VPN Client に管理モードで接続している場合も実行できますが、実際に通信を行ってスループットを測定するのは、このコマンドを実行しているコンピュータであり、管理モードで接続先のコンピュータとは一切関係ないコンテキストで実行されます。
コマンドライン書式 + TrafficClient [host:port] [/NUMTCP:numtcp] [/TYPE:download|upload|full] [/SPAN:span] [/DOUBLE:yes|no] [/RAW:yes|no]
"TrafficClient" コマンドで指定することができるパラメータ引数の一覧:
host:port + 通信スループット測定ツールサーバー (TrafficServer) が待機しているホスト名、または IP アドレスとポート番号を指定します。ポート番号を省略した場合は、9821 が使用されます。
/NUMTCP + 同時にクライアントとサーバーとの間で確立されデータが伝送される TCP コネクション数を指定します。省略した場合は 32 が使用されます。
/TYPE + スループット測定を行う際の、データの流れる方向を指定します。"download"、"upload"、"full" のうち 1 つを指定します。download を指定すると、サーバー側からクライアント側にデータが伝送されます。upload を指定すると、クライアント側からサーバー側にデータが伝送されます。full を指定すると、双方向にデータが伝送されます。full を指定する場合は、NUMTCP の値は 2 以上の偶数に指定する必要があります (同時に接続される TCP コネクションのうち半数がダウンロード方向、残りの半数がアップロード方向に使用されます)。このパラメータを省略した場合は full が使用されます。
/SPAN + スループットを測定するためのデータ伝送を行う時間を、秒数単位で指定します。このパラメータを省略した場合は 15 秒が使用されます。
/DOUBLE + "yes" を指定した場合、計測した結果のスループットを 2 倍にして表示します。このオプションは、途中にネットワーク装置などがあり、そのネットワーク装置が入出力した合計のスループット能力を測定する場合に使用します。
/RAW + "yes" を指定すると、TCP/IP ヘッダや MAC ヘッダのデータ量を補正する計算を行いません。
+

 

+

6.5.64 "TrafficServer": 通信スループット測定ツールサーバーの実行

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + TrafficServer
コマンドの概要 + 通信スループット測定ツールサーバーの実行
説明 + 通信スループット測定ツールのサーバープログラムを実行します。
通信スループット測定ツールは、TrafficClient と TrafficServer の 2 つのコマンドとして利用し、IP ネットワーク上で接続された 2 台のコンピュータの間で伝送することができる通信スループットを計測することができます。
このコンピュータ上の TCP ポートを待機状態にして、別のコンピュータからの TrafficClient からの接続を待ち受けるには、TrafficServer コマンドにポート番号を指定して起動します。
通信スループット測定ツールに関する詳細は、TrafficClient /? と入力すると表示されます。

※注意: このコマンドは PacketiX VPN コマンドライン管理ユーティリティから呼び出すことが可能です。現在 VPN Server や VPN Client に管理モードで接続している場合も実行できますが、実際に通信を行ってスループットを測定するのは、このコマンドを実行しているコンピュータであり、管理モードで接続先のコンピュータとは一切関係ないコンテキストで実行されます。
コマンドライン書式 + TrafficServer [port]
"TrafficServer" コマンドで指定することができるパラメータ引数の一覧:
port + 接続を待ち受けるポート番号を整数で指定します。指定されたポートが、すでに別のプログラムによって使用中の場合や、ポートを開くことができない場合はエラーが発生します。
+

 

+

6.5.65 "Check": PacketiX VPN の動作が可能かどうかチェックする

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + Check
コマンドの概要 + PacketiX VPN の動作が可能かどうかチェックする
説明 + 現在 vpncmd を動作させているコンピュータが、PacketiX VPN Server / Bridge の動作プラットフォームとして適切であるかどうかをチェックします。
このチェックを通過したシステム上では、PacketiX VPN ソフトウェアが正しく動作する可能性が高いと思われます。
また、このチェックを通過できないシステム上では、PacketiX VPN ソフトウェアを使用した場合に、何らかの問題が発生する可能性があります。
コマンドライン書式 + Check
"Check" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+ + + + + + + + + + +------ 4 ------ + + + + + + + + + +

6.6.1 "About": バージョン情報の表示

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + About
コマンドの概要 + バージョン情報の表示
説明 + このコマンドライン管理ユーティリティのバージョン情報を表示します。バージョン情報には、vpncmd のバージョン番号、ビルド番号、ビルド情報などが含まれます。
コマンドライン書式 + About
"About" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

+

6.6.2 "MakeCert": 新しい X.509 証明書と秘密鍵の作成

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + MakeCert
コマンドの概要 + 新しい X.509 証明書と秘密鍵の作成
説明 + 新しい X.509 証明書と秘密鍵を作成し、ファイルとして保存します。
証明書の公開鍵と秘密鍵の生成アルゴリズムには、RSA 1024 bit が使用されます。
証明書の種類として、ルート証明書 (自己署名証明書) と他の証明書によって署名された証明書のどちらでも作成することができます。他の証明書によって署名された証明書を作成するためには、署名に使用する証明書 (X.509 形式のファイル) と対応する秘密鍵ファイル (Base 64 エンコード) が必要です。

作成する証明書には、名前 (CN)、所属機関 (O)、組織単位 (OU)、国 (C)、都道府県 (ST)、ローカル (L)、シリアル番号、有効期限を指定することができます。
作成された証明書は X.509 形式のファイルとして、秘密鍵ファイルは RSA 1024 bit 形式の Base 64 エンコードされたファイルとしてそれぞれ保存されます。

MakeCert コマンドは、証明書を作成するための必要最低限の機能を用意したツールです。本格的な証明書を作成したい場合は、OpenSSL などのフリーソフトや、市販の CA (証明機関) ソフトウェアを使用することを推奨します。

※注意: このコマンドは PacketiX VPN コマンドライン管理ユーティリティから呼び出すことが可能です。現在 VPN Server や VPN Client に管理モードで接続している場合も実行できますが、実際に RSA 演算を行い、証明書データを生成しファイルに保存するのはこのコマンドを実行しているコンピュータであり、管理モードで接続先のコンピュータとは一切関係ないコンテキストで実行されます。
コマンドライン書式 + MakeCert [/CN:cn] [/O:o] [/OU:ou] [/C:c] [/ST:st] [/L:l] [/SERIAL:serial] [/EXPIRES:expires] [/SIGNCERT:signcert] [/SIGNKEY:signkey] [/SAVECERT:savecert] [/SAVEKEY:savekey]
"MakeCert" コマンドで指定することができるパラメータ引数の一覧:
/CN + 作成する証明書の名前 (CN) 項目を指定します。none を指定することもできます。
/O + 作成する証明書の所属機関 (O) 項目を指定します。none を指定することもできます。
/OU + 作成する証明書の組織単位 (OU) 項目を指定します。none を指定することもできます。
/C + 作成する証明書の国 (C) 項目を指定します。none を指定することもできます。
/ST + 作成する証明書の都道府県 (ST) 項目を指定します。none を指定することもできます。
/L + 作成する証明書のローカル (L) 項目を指定します。none を指定することもできます。
/SERIAL + 作成する証明書のシリアル番号項目を指定します。16 進数で指定します。none を指定することもできます。
/EXPIRES + 作成する証明書の有効期限を指定します。none または 0 を指定すると、3650 日 (約 10 年) が使用されます。最大 10950 日 (約 30 年) まで指定できます。
/SIGNCERT + 作成する証明書を、既存の証明書によって署名する場合は、署名に使用する X.509 形式の証明書のファイル名を指定します。パラメータを省略した場合は、署名は行わず新しい証明書をルート証明書として作成します。
/SIGNKEY + /SIGNCERT で指定した証明書に対応する秘密鍵 (RSA, Base-64 エンコード) を指定します。
/SAVECERT + 作成した証明書を保存するファイル名を指定します。証明書は RSA 形式の 1024 bit の公開鍵を含んだ X.509 ファイルとして保存されます。
/SAVEKEY + 作成した証明書に対応する秘密鍵を保存するファイル名を指定します。秘密鍵は RSA 形式の 1024 bit の秘密鍵ファイルとして保存されます。
+

 

+

6.6.3 "TrafficClient": 通信スループット測定ツールクライアントの実行

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + TrafficClient
コマンドの概要 + 通信スループット測定ツールクライアントの実行
説明 + 通信スループット測定ツールの、クライアントプログラムを実行します。
通信スループット測定ツールは TrafficClient と TrafficServer の 2 つのコマンドとして利用し、IP ネットワーク上で接続された 2 台のコンピュータの間で伝送することができる通信スループットを計測することができます。すでに別のコンピュータ上で、TrafficServer コマンドを用いて通信スループット測定ツールサーバーを待機させておき、TrafficClient コマンドで、そのサーバーのホスト名または IP アドレスとポート番号を指定して接続し、通信速度を測定することができます。
通信速度の測定は、同時に複数本の TCP コネクションを確立し、それぞれのコネクションで最大限にストリームデータを伝送した結果、指定された時間内に実際に伝送することができたデータのビット数を計算し、それを元に通信スループットの平均値 (bps) を算出する方法で行われます。通常、1 本の TCP コネクションを用いた場合は TCP のアルゴリズム上の限界により、実際のネットワークスループットよりも遅い速度でしか通信できない場合が多いため、複数本の TCP コネクションを同時に確立して通信した結果を測定することを推奨します。この測定方法によって計測されたスループットは実際に TCP でストリームとして受信側に届いたデータのビット長から計算されるため、途中で発生したパケットロスやデータ破損したパケットは、実際に届いたパケットには含まれず、純粋なネットワークの最大通信可能帯域幅に近い値を算出することができます。
測定結果として TCP 内で伝送されたストリームサイズから、実際にネットワーク上を流れたデータ量の近似値を計算し、それを時間で割ってビット毎秒 (bps) を算出します。物理的なネットワークの種類は Ethernet (IEEE802.3) で、MAC フレームのペイロードサイズは 1,500 Bytes (TCP の MSS は 1,460 Bytes) と仮定して計算が行われます。/RAW オプションを指定すると、TCP/IP ヘッダや MAC ヘッダのデータ量を補正する計算は行われません。

※注意: このコマンドは PacketiX VPN コマンドライン管理ユーティリティから呼び出すことが可能です。現在 VPN Server や VPN Client に管理モードで接続している場合も実行できますが、実際に通信を行ってスループットを測定するのは、このコマンドを実行しているコンピュータであり、管理モードで接続先のコンピュータとは一切関係ないコンテキストで実行されます。
コマンドライン書式 + TrafficClient [host:port] [/NUMTCP:numtcp] [/TYPE:download|upload|full] [/SPAN:span] [/DOUBLE:yes|no] [/RAW:yes|no]
"TrafficClient" コマンドで指定することができるパラメータ引数の一覧:
host:port + 通信スループット測定ツールサーバー (TrafficServer) が待機しているホスト名、または IP アドレスとポート番号を指定します。ポート番号を省略した場合は、9821 が使用されます。
/NUMTCP + 同時にクライアントとサーバーとの間で確立されデータが伝送される TCP コネクション数を指定します。省略した場合は 32 が使用されます。
/TYPE + スループット測定を行う際の、データの流れる方向を指定します。"download"、"upload"、"full" のうち 1 つを指定します。download を指定すると、サーバー側からクライアント側にデータが伝送されます。upload を指定すると、クライアント側からサーバー側にデータが伝送されます。full を指定すると、双方向にデータが伝送されます。full を指定する場合は、NUMTCP の値は 2 以上の偶数に指定する必要があります (同時に接続される TCP コネクションのうち半数がダウンロード方向、残りの半数がアップロード方向に使用されます)。このパラメータを省略した場合は full が使用されます。
/SPAN + スループットを測定するためのデータ伝送を行う時間を、秒数単位で指定します。このパラメータを省略した場合は 15 秒が使用されます。
/DOUBLE + "yes" を指定した場合、計測した結果のスループットを 2 倍にして表示します。このオプションは、途中にネットワーク装置などがあり、そのネットワーク装置が入出力した合計のスループット能力を測定する場合に使用します。
/RAW + "yes" を指定すると、TCP/IP ヘッダや MAC ヘッダのデータ量を補正する計算を行いません。
+

 

+

6.6.4 "TrafficServer": 通信スループット測定ツールサーバーの実行

+ + + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + TrafficServer
コマンドの概要 + 通信スループット測定ツールサーバーの実行
説明 + 通信スループット測定ツールのサーバープログラムを実行します。
通信スループット測定ツールは、TrafficClient と TrafficServer の 2 つのコマンドとして利用し、IP ネットワーク上で接続された 2 台のコンピュータの間で伝送することができる通信スループットを計測することができます。
このコンピュータ上の TCP ポートを待機状態にして、別のコンピュータからの TrafficClient からの接続を待ち受けるには、TrafficServer コマンドにポート番号を指定して起動します。
通信スループット測定ツールに関する詳細は、TrafficClient /? と入力すると表示されます。

※注意: このコマンドは PacketiX VPN コマンドライン管理ユーティリティから呼び出すことが可能です。現在 VPN Server や VPN Client に管理モードで接続している場合も実行できますが、実際に通信を行ってスループットを測定するのは、このコマンドを実行しているコンピュータであり、管理モードで接続先のコンピュータとは一切関係ないコンテキストで実行されます。
コマンドライン書式 + TrafficServer [port]
"TrafficServer" コマンドで指定することができるパラメータ引数の一覧:
port + 接続を待ち受けるポート番号を整数で指定します。指定されたポートが、すでに別のプログラムによって使用中の場合や、ポートを開くことができない場合はエラーが発生します。
+

 

+

6.6.5 "Check": PacketiX VPN の動作が可能かどうかチェックする

+ + + + + + + + + + + + + + + + + + + + + + + +
コマンド名 + Check
コマンドの概要 + PacketiX VPN の動作が可能かどうかチェックする
説明 + 現在 vpncmd を動作させているコンピュータが、PacketiX VPN Server / Bridge の動作プラットフォームとして適切であるかどうかをチェックします。
このチェックを通過したシステム上では、PacketiX VPN ソフトウェアが正しく動作する可能性が高いと思われます。
また、このチェックを通過できないシステム上では、PacketiX VPN ソフトウェアを使用した場合に、何らかの問題が発生する可能性があります。
コマンドライン書式 + Check
"Check" コマンドで指定することができるパラメータ引数の一覧:
このコマンドには指定すべきパラメータ引数は 1 つもありません。
+

 

diff --git a/src/Mayaqua/Encrypt.c b/src/Mayaqua/Encrypt.c index f56fc86f..d93ef7d5 100644 --- a/src/Mayaqua/Encrypt.c +++ b/src/Mayaqua/Encrypt.c @@ -142,6 +142,8 @@ LOCK *openssl_lock = NULL; +int ssl_clientcert_index = 0; + LOCK **ssl_lock_obj = NULL; UINT ssl_lock_num; static bool openssl_inited = false; @@ -2456,7 +2458,6 @@ bool RsaVerifyEx(void *data, UINT data_size, void *sign, K *k, UINT bits) UCHAR hash_data[SIGN_HASH_SIZE]; UCHAR *decrypt_data; RSA *rsa; - UINT rsa_size; // Validate arguments if (data == NULL || sign == NULL || k == NULL || k->private_key != false) { @@ -2473,16 +2474,15 @@ bool RsaVerifyEx(void *data, UINT data_size, void *sign, K *k, UINT bits) return false; } + decrypt_data = ZeroMalloc(RSA_size(rsa)); + // Hash the data if (HashForSign(hash_data, sizeof(hash_data), data, data_size) == false) { + Free(decrypt_data); return false; } - rsa_size = RSA_size(rsa); - rsa_size = MAX(rsa_size, 1024); // For just in case - decrypt_data = ZeroMalloc(rsa_size); - // Decode the signature if (RSA_public_decrypt(bits / 8, sign, decrypt_data, rsa, RSA_PKCS1_PADDING) <= 0) { @@ -4137,6 +4137,8 @@ void InitCryptLibrary() ERR_load_crypto_strings(); SSL_load_error_strings(); + ssl_clientcert_index = SSL_get_ex_new_index(0, "struct SslClientCertInfo *", NULL, NULL, NULL); + #ifdef OS_UNIX { char *name1 = "/dev/random"; @@ -5171,5 +5173,1056 @@ static unsigned char *Internal_SHA0(const unsigned char *d, size_t n, unsigned c } +int GetSslClientCertIndex() +{ + return ssl_clientcert_index; +} + +//// RFC 8439: ChaCha20 and Poly1305 for IETF Protocols +//// Implementation from libsodium: https://github.com/jedisct1/libsodium +//// +//// SoftEther VPN must support OpenSSL versions between 1.0.2 to the latest version. +//// Since we are unable to use ChaCha20 and Poly1305 on OpenSSL 1.0.x, +//// we copied the C implementation from libsodium. +//// Please note that the C implementation for ChaCha20 and Poly1305 is slow than +//// the OpenSSL 1.0.0 or later's implementation for ChaCha20 and Poly1305. +//// +//// If OpenSSL 1.1.0 or later is linked, we use OpenSSL's ChaCha20 and Poly1305 implementation. + +/* + * ISC License + * + * Copyright (c) 2013-2018 + * Frank Denis + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef OS_WIN32 +#define inline __inline +#endif + +#define poly1305_block_size 16 + +#define U32C(v) (v##U) +#define U32V(v) ((UINT)(v) &U32C(0xFFFFFFFF)) +#define ROTATE(v, c) (ROTL32(v, c)) +#define XOR(v, w) ((v) ^ (w)) +#define PLUS(v, w) (U32V((v) + (w))) +#define PLUSONE(v) (PLUS((v), 1)) + +#define QUARTERROUND(a, b, c, d) \ + a = PLUS(a, b); \ + d = ROTATE(XOR(d, a), 16); \ + c = PLUS(c, d); \ + b = ROTATE(XOR(b, c), 12); \ + a = PLUS(a, b); \ + d = ROTATE(XOR(d, a), 8); \ + c = PLUS(c, d); \ + b = ROTATE(XOR(b, c), 7); + +#define ROTL32(X, B) rotl32((X), (B)) +static inline UINT +rotl32(const UINT x, const int b) +{ + return (x << b) | (x >> (32 - b)); +} + + +#define LOAD32_LE(SRC) load32_le(SRC) + +static inline UINT +load32_le(const UCHAR src[4]) +{ + if (IsBigEndian() == false) + { + UINT w; + memcpy(&w, src, sizeof w); + return w; + } + else + { + UINT w = (UINT) src[0]; + w |= (UINT) src[1] << 8; + w |= (UINT) src[2] << 16; + w |= (UINT) src[3] << 24; + return w; + } +} + +#define STORE32_LE(DST, W) store32_le((DST), (W)) +static inline void +store32_le(UCHAR dst[4], UINT w) +{ + if (IsBigEndian() == false) + { + memcpy(dst, &w, sizeof w); + } + else + { + dst[0] = (UCHAR) w; w >>= 8; + dst[1] = (UCHAR) w; w >>= 8; + dst[2] = (UCHAR) w; w >>= 8; + dst[3] = (UCHAR) w; + } +} + + +#define LOAD64_LE(SRC) load64_le(SRC) +static inline UINT64 +load64_le(const UCHAR src[8]) +{ + if (IsBigEndian() == false) + { + UINT64 w; + memcpy(&w, src, sizeof w); + return w; + } + else + { + UINT64 w = (UINT64) src[0]; + w |= (UINT64) src[1] << 8; + w |= (UINT64) src[2] << 16; + w |= (UINT64) src[3] << 24; + w |= (UINT64) src[4] << 32; + w |= (UINT64) src[5] << 40; + w |= (UINT64) src[6] << 48; + w |= (UINT64) src[7] << 56; + return w; + } +} + +#define STORE64_LE(DST, W) store64_le((DST), (W)) +static inline void +store64_le(UCHAR dst[8], UINT64 w) +{ + if (IsBigEndian() == false) + { + memcpy(dst, &w, sizeof w); + } + else + { + dst[0] = (UCHAR) w; w >>= 8; + dst[1] = (UCHAR) w; w >>= 8; + dst[2] = (UCHAR) w; w >>= 8; + dst[3] = (UCHAR) w; w >>= 8; + dst[4] = (UCHAR) w; w >>= 8; + dst[5] = (UCHAR) w; w >>= 8; + dst[6] = (UCHAR) w; w >>= 8; + dst[7] = (UCHAR) w; + } +} + + + +typedef struct chacha_ctx { + UINT input[16]; +} chacha_ctx; + + + + +#define crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX \ + (64ULL * (1ULL << 32)) + +typedef struct crypto_onetimeauth_poly1305_state { + unsigned char opaque[256]; +} crypto_onetimeauth_poly1305_state; + +/* 17 + sizeof(unsigned long long) + 14*sizeof(unsigned long) */ +typedef struct poly1305_state_internal_t { + unsigned long r[5]; + unsigned long h[5]; + unsigned long pad[4]; + unsigned long long leftover; + unsigned char buffer[poly1305_block_size]; + unsigned char final; +} poly1305_state_internal_t; +static void +chacha_keysetup(chacha_ctx *ctx, const UCHAR *k) +{ + ctx->input[0] = U32C(0x61707865); + ctx->input[1] = U32C(0x3320646e); + ctx->input[2] = U32C(0x79622d32); + ctx->input[3] = U32C(0x6b206574); + ctx->input[4] = LOAD32_LE(k + 0); + ctx->input[5] = LOAD32_LE(k + 4); + ctx->input[6] = LOAD32_LE(k + 8); + ctx->input[7] = LOAD32_LE(k + 12); + ctx->input[8] = LOAD32_LE(k + 16); + ctx->input[9] = LOAD32_LE(k + 20); + ctx->input[10] = LOAD32_LE(k + 24); + ctx->input[11] = LOAD32_LE(k + 28); +} + +static void +chacha_ietf_ivsetup(chacha_ctx *ctx, const UCHAR *iv, const UCHAR *counter) +{ + ctx->input[12] = counter == NULL ? 0 : LOAD32_LE(counter); + ctx->input[13] = LOAD32_LE(iv + 0); + ctx->input[14] = LOAD32_LE(iv + 4); + ctx->input[15] = LOAD32_LE(iv + 8); +} + +static void +chacha20_encrypt_bytes(chacha_ctx *ctx, const UCHAR *m, UCHAR *c, + unsigned long long bytes) +{ + UINT x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, + x15; + UINT j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, + j15; + UCHAR *ctarget = NULL; + UCHAR tmp[64]; + unsigned int i; + + if (!bytes) { + return; /* LCOV_EXCL_LINE */ + } + j0 = ctx->input[0]; + j1 = ctx->input[1]; + j2 = ctx->input[2]; + j3 = ctx->input[3]; + j4 = ctx->input[4]; + j5 = ctx->input[5]; + j6 = ctx->input[6]; + j7 = ctx->input[7]; + j8 = ctx->input[8]; + j9 = ctx->input[9]; + j10 = ctx->input[10]; + j11 = ctx->input[11]; + j12 = ctx->input[12]; + j13 = ctx->input[13]; + j14 = ctx->input[14]; + j15 = ctx->input[15]; + + for (;;) { + if (bytes < 64) { + memset(tmp, 0, 64); + for (i = 0; i < bytes; ++i) { + tmp[i] = m[i]; + } + m = tmp; + ctarget = c; + c = tmp; + } + x0 = j0; + x1 = j1; + x2 = j2; + x3 = j3; + x4 = j4; + x5 = j5; + x6 = j6; + x7 = j7; + x8 = j8; + x9 = j9; + x10 = j10; + x11 = j11; + x12 = j12; + x13 = j13; + x14 = j14; + x15 = j15; + for (i = 20; i > 0; i -= 2) { + QUARTERROUND(x0, x4, x8, x12) + QUARTERROUND(x1, x5, x9, x13) + QUARTERROUND(x2, x6, x10, x14) + QUARTERROUND(x3, x7, x11, x15) + QUARTERROUND(x0, x5, x10, x15) + QUARTERROUND(x1, x6, x11, x12) + QUARTERROUND(x2, x7, x8, x13) + QUARTERROUND(x3, x4, x9, x14) + } + x0 = PLUS(x0, j0); + x1 = PLUS(x1, j1); + x2 = PLUS(x2, j2); + x3 = PLUS(x3, j3); + x4 = PLUS(x4, j4); + x5 = PLUS(x5, j5); + x6 = PLUS(x6, j6); + x7 = PLUS(x7, j7); + x8 = PLUS(x8, j8); + x9 = PLUS(x9, j9); + x10 = PLUS(x10, j10); + x11 = PLUS(x11, j11); + x12 = PLUS(x12, j12); + x13 = PLUS(x13, j13); + x14 = PLUS(x14, j14); + x15 = PLUS(x15, j15); + + x0 = XOR(x0, LOAD32_LE(m + 0)); + x1 = XOR(x1, LOAD32_LE(m + 4)); + x2 = XOR(x2, LOAD32_LE(m + 8)); + x3 = XOR(x3, LOAD32_LE(m + 12)); + x4 = XOR(x4, LOAD32_LE(m + 16)); + x5 = XOR(x5, LOAD32_LE(m + 20)); + x6 = XOR(x6, LOAD32_LE(m + 24)); + x7 = XOR(x7, LOAD32_LE(m + 28)); + x8 = XOR(x8, LOAD32_LE(m + 32)); + x9 = XOR(x9, LOAD32_LE(m + 36)); + x10 = XOR(x10, LOAD32_LE(m + 40)); + x11 = XOR(x11, LOAD32_LE(m + 44)); + x12 = XOR(x12, LOAD32_LE(m + 48)); + x13 = XOR(x13, LOAD32_LE(m + 52)); + x14 = XOR(x14, LOAD32_LE(m + 56)); + x15 = XOR(x15, LOAD32_LE(m + 60)); + + j12 = PLUSONE(j12); + /* LCOV_EXCL_START */ + if (!j12) { + j13 = PLUSONE(j13); + } + /* LCOV_EXCL_STOP */ + + STORE32_LE(c + 0, x0); + STORE32_LE(c + 4, x1); + STORE32_LE(c + 8, x2); + STORE32_LE(c + 12, x3); + STORE32_LE(c + 16, x4); + STORE32_LE(c + 20, x5); + STORE32_LE(c + 24, x6); + STORE32_LE(c + 28, x7); + STORE32_LE(c + 32, x8); + STORE32_LE(c + 36, x9); + STORE32_LE(c + 40, x10); + STORE32_LE(c + 44, x11); + STORE32_LE(c + 48, x12); + STORE32_LE(c + 52, x13); + STORE32_LE(c + 56, x14); + STORE32_LE(c + 60, x15); + + if (bytes <= 64) { + if (bytes < 64) { + for (i = 0; i < (unsigned int) bytes; ++i) { + ctarget[i] = c[i]; /* ctarget cannot be NULL */ + } + } + ctx->input[12] = j12; + ctx->input[13] = j13; + + return; + } + bytes -= 64; + c += 64; + m += 64; + } +} + +static int +stream_ietf_ext_ref(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + struct chacha_ctx ctx; + + if (!clen) { + return 0; + } + chacha_keysetup(&ctx, k); + chacha_ietf_ivsetup(&ctx, n, NULL); + memset(c, 0, (UINT)clen); + chacha20_encrypt_bytes(&ctx, c, c, clen); + Zero(&ctx, sizeof ctx); + + return 0; +} + +int +crypto_stream_chacha20_ietf(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + return stream_ietf_ext_ref(c, clen, n, k); +} + +static void +poly1305_init(poly1305_state_internal_t *st, const unsigned char key[32]) +{ + /* r &= 0xffffffc0ffffffc0ffffffc0fffffff - wiped after finalization */ + st->r[0] = (LOAD32_LE(&key[0])) & 0x3ffffff; + st->r[1] = (LOAD32_LE(&key[3]) >> 2) & 0x3ffff03; + st->r[2] = (LOAD32_LE(&key[6]) >> 4) & 0x3ffc0ff; + st->r[3] = (LOAD32_LE(&key[9]) >> 6) & 0x3f03fff; + st->r[4] = (LOAD32_LE(&key[12]) >> 8) & 0x00fffff; + + /* h = 0 */ + st->h[0] = 0; + st->h[1] = 0; + st->h[2] = 0; + st->h[3] = 0; + st->h[4] = 0; + + /* save pad for later */ + st->pad[0] = LOAD32_LE(&key[16]); + st->pad[1] = LOAD32_LE(&key[20]); + st->pad[2] = LOAD32_LE(&key[24]); + st->pad[3] = LOAD32_LE(&key[28]); + + st->leftover = 0; + st->final = 0; +} + +static void +poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, + unsigned long long bytes) +{ + const unsigned long hibit = (st->final) ? 0UL : (1UL << 24); /* 1 << 128 */ + unsigned long r0, r1, r2, r3, r4; + unsigned long s1, s2, s3, s4; + unsigned long h0, h1, h2, h3, h4; + unsigned long long d0, d1, d2, d3, d4; + unsigned long c; + + r0 = st->r[0]; + r1 = st->r[1]; + r2 = st->r[2]; + r3 = st->r[3]; + r4 = st->r[4]; + + s1 = r1 * 5; + s2 = r2 * 5; + s3 = r3 * 5; + s4 = r4 * 5; + + h0 = st->h[0]; + h1 = st->h[1]; + h2 = st->h[2]; + h3 = st->h[3]; + h4 = st->h[4]; + + while (bytes >= poly1305_block_size) { + /* h += m[i] */ + h0 += (LOAD32_LE(m + 0)) & 0x3ffffff; + h1 += (LOAD32_LE(m + 3) >> 2) & 0x3ffffff; + h2 += (LOAD32_LE(m + 6) >> 4) & 0x3ffffff; + h3 += (LOAD32_LE(m + 9) >> 6) & 0x3ffffff; + h4 += (LOAD32_LE(m + 12) >> 8) | hibit; + + /* h *= r */ + d0 = ((unsigned long long) h0 * r0) + ((unsigned long long) h1 * s4) + + ((unsigned long long) h2 * s3) + ((unsigned long long) h3 * s2) + + ((unsigned long long) h4 * s1); + d1 = ((unsigned long long) h0 * r1) + ((unsigned long long) h1 * r0) + + ((unsigned long long) h2 * s4) + ((unsigned long long) h3 * s3) + + ((unsigned long long) h4 * s2); + d2 = ((unsigned long long) h0 * r2) + ((unsigned long long) h1 * r1) + + ((unsigned long long) h2 * r0) + ((unsigned long long) h3 * s4) + + ((unsigned long long) h4 * s3); + d3 = ((unsigned long long) h0 * r3) + ((unsigned long long) h1 * r2) + + ((unsigned long long) h2 * r1) + ((unsigned long long) h3 * r0) + + ((unsigned long long) h4 * s4); + d4 = ((unsigned long long) h0 * r4) + ((unsigned long long) h1 * r3) + + ((unsigned long long) h2 * r2) + ((unsigned long long) h3 * r1) + + ((unsigned long long) h4 * r0); + + /* (partial) h %= p */ + c = (unsigned long) (d0 >> 26); + h0 = (unsigned long) d0 & 0x3ffffff; + d1 += c; + c = (unsigned long) (d1 >> 26); + h1 = (unsigned long) d1 & 0x3ffffff; + d2 += c; + c = (unsigned long) (d2 >> 26); + h2 = (unsigned long) d2 & 0x3ffffff; + d3 += c; + c = (unsigned long) (d3 >> 26); + h3 = (unsigned long) d3 & 0x3ffffff; + d4 += c; + c = (unsigned long) (d4 >> 26); + h4 = (unsigned long) d4 & 0x3ffffff; + h0 += c * 5; + c = (h0 >> 26); + h0 = h0 & 0x3ffffff; + h1 += c; + + m += poly1305_block_size; + bytes -= poly1305_block_size; + } + + st->h[0] = h0; + st->h[1] = h1; + st->h[2] = h2; + st->h[3] = h3; + st->h[4] = h4; +} + +static void +poly1305_update(poly1305_state_internal_t *st, const unsigned char *m, + unsigned long long bytes) +{ + unsigned long long i; + + /* handle leftover */ + if (st->leftover) { + unsigned long long want = (poly1305_block_size - st->leftover); + + if (want > bytes) { + want = bytes; + } + for (i = 0; i < want; i++) { + st->buffer[st->leftover + i] = m[i]; + } + bytes -= want; + m += want; + st->leftover += want; + if (st->leftover < poly1305_block_size) { + return; + } + poly1305_blocks(st, st->buffer, poly1305_block_size); + st->leftover = 0; + } + + /* process full blocks */ + if (bytes >= poly1305_block_size) { + unsigned long long want = (bytes & ~(poly1305_block_size - 1)); + + poly1305_blocks(st, m, want); + m += want; + bytes -= want; + } + + /* store leftover */ + if (bytes) { + for (i = 0; i < bytes; i++) { + st->buffer[st->leftover + i] = m[i]; + } + st->leftover += bytes; + } +} + +static int +crypto_onetimeauth_poly1305_init(crypto_onetimeauth_poly1305_state *state, + const unsigned char *key) +{ + poly1305_init((poly1305_state_internal_t *) (void *) state, key); + + return 0; +} + +static int +crypto_onetimeauth_poly1305_update( + crypto_onetimeauth_poly1305_state *state, const unsigned char *in, + unsigned long long inlen) +{ + poly1305_update((poly1305_state_internal_t *) (void *) state, in, inlen); + + return 0; +} + +static int +stream_ietf_ext_ref_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + UINT ic, const unsigned char *k) +{ + struct chacha_ctx ctx; + UCHAR ic_bytes[4]; + + if (!mlen) { + return 0; + } + STORE32_LE(ic_bytes, ic); + chacha_keysetup(&ctx, k); + chacha_ietf_ivsetup(&ctx, n, ic_bytes); + chacha20_encrypt_bytes(&ctx, m, c, mlen); + Zero(&ctx, sizeof ctx); + + return 0; +} + +int +crypto_stream_chacha20_ietf_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, UINT ic, + const unsigned char *k) +{ + return stream_ietf_ext_ref_xor_ic(c, m, mlen, n, ic, k); +} + + +static void +poly1305_finish(poly1305_state_internal_t *st, unsigned char mac[16]) +{ + unsigned long h0, h1, h2, h3, h4, c; + unsigned long g0, g1, g2, g3, g4; + unsigned long long f; + unsigned long mask; + + /* process the remaining block */ + if (st->leftover) { + unsigned long long i = st->leftover; + + st->buffer[i++] = 1; + for (; i < poly1305_block_size; i++) { + st->buffer[i] = 0; + } + st->final = 1; + poly1305_blocks(st, st->buffer, poly1305_block_size); + } + + /* fully carry h */ + h0 = st->h[0]; + h1 = st->h[1]; + h2 = st->h[2]; + h3 = st->h[3]; + h4 = st->h[4]; + + c = h1 >> 26; + h1 = h1 & 0x3ffffff; + h2 += c; + c = h2 >> 26; + h2 = h2 & 0x3ffffff; + h3 += c; + c = h3 >> 26; + h3 = h3 & 0x3ffffff; + h4 += c; + c = h4 >> 26; + h4 = h4 & 0x3ffffff; + h0 += c * 5; + c = h0 >> 26; + h0 = h0 & 0x3ffffff; + h1 += c; + + /* compute h + -p */ + g0 = h0 + 5; + c = g0 >> 26; + g0 &= 0x3ffffff; + g1 = h1 + c; + c = g1 >> 26; + g1 &= 0x3ffffff; + g2 = h2 + c; + c = g2 >> 26; + g2 &= 0x3ffffff; + g3 = h3 + c; + c = g3 >> 26; + g3 &= 0x3ffffff; + g4 = h4 + c - (1UL << 26); + + /* select h if h < p, or h + -p if h >= p */ + mask = (g4 >> ((sizeof(unsigned long) * 8) - 1)) - 1; + g0 &= mask; + g1 &= mask; + g2 &= mask; + g3 &= mask; + g4 &= mask; + mask = ~mask; + + h0 = (h0 & mask) | g0; + h1 = (h1 & mask) | g1; + h2 = (h2 & mask) | g2; + h3 = (h3 & mask) | g3; + h4 = (h4 & mask) | g4; + + /* h = h % (2^128) */ + h0 = ((h0) | (h1 << 26)) & 0xffffffff; + h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff; + h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff; + h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff; + + /* mac = (h + pad) % (2^128) */ + f = (unsigned long long) h0 + st->pad[0]; + h0 = (unsigned long) f; + f = (unsigned long long) h1 + st->pad[1] + (f >> 32); + h1 = (unsigned long) f; + f = (unsigned long long) h2 + st->pad[2] + (f >> 32); + h2 = (unsigned long) f; + f = (unsigned long long) h3 + st->pad[3] + (f >> 32); + h3 = (unsigned long) f; + + STORE32_LE(mac + 0, (UINT) h0); + STORE32_LE(mac + 4, (UINT) h1); + STORE32_LE(mac + 8, (UINT) h2); + STORE32_LE(mac + 12, (UINT) h3); + + /* zero out the state */ + Zero((void *) st, sizeof *st); +} + +static int +crypto_onetimeauth_poly1305_final( + crypto_onetimeauth_poly1305_state *state, unsigned char *out) +{ + poly1305_finish((poly1305_state_internal_t *) (void *) state, out); + + return 0; +} + +static const unsigned char _pad0[16] = { 0 }; + +int +crypto_aead_chacha20poly1305_ietf_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + crypto_onetimeauth_poly1305_state state; + unsigned char block0[64U]; + unsigned char slen[8U]; + + (void) nsec; + Zero(block0, sizeof block0); + crypto_stream_chacha20_ietf(block0, sizeof block0, npub, k); + crypto_onetimeauth_poly1305_init(&state, block0); + + crypto_onetimeauth_poly1305_update(&state, ad, adlen); + crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - adlen) & 0xf); + + crypto_stream_chacha20_ietf_xor_ic(c, m, mlen, npub, 1U, k); + + crypto_onetimeauth_poly1305_update(&state, c, mlen); + crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - mlen) & 0xf); + + STORE64_LE(slen, (UINT64) adlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + STORE64_LE(slen, (UINT64) mlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + crypto_onetimeauth_poly1305_final(&state, mac); + Zero(&state, sizeof state); + + if (maclen_p != NULL) { + *maclen_p = 16; + } + return 0; +} + + + +int +crypto_aead_chacha20poly1305_ietf_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + crypto_onetimeauth_poly1305_state state; + unsigned char block0[64U]; + unsigned char slen[8U]; + unsigned char computed_mac[16]; + unsigned long long mlen; + int ret; + + (void) nsec; + Zero(block0, sizeof block0); + crypto_stream_chacha20_ietf(block0, sizeof block0, npub, k); + crypto_onetimeauth_poly1305_init(&state, block0); + + crypto_onetimeauth_poly1305_update(&state, ad, adlen); + crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - adlen) & 0xf); + + mlen = clen; + crypto_onetimeauth_poly1305_update(&state, c, mlen); + crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - mlen) & 0xf); + + STORE64_LE(slen, (UINT64) adlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + STORE64_LE(slen, (UINT64) mlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + crypto_onetimeauth_poly1305_final(&state, computed_mac); + Zero(&state, sizeof state); + + ret = Cmp((void *)computed_mac, (void *)mac, 16); + Zero(computed_mac, sizeof computed_mac); + if (m == NULL) { + return ret; + } + if (ret != 0) { + memset(m, 0, (UINT)mlen); + return -1; + } + crypto_stream_chacha20_ietf_xor_ic(m, c, mlen, npub, 1U, k); + + return 0; +} + +int +crypto_aead_chacha20poly1305_ietf_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned long long mlen = 0ULL; + int ret = -1; + + if (clen >= 16) { + ret = crypto_aead_chacha20poly1305_ietf_decrypt_detached + (m, nsec, + c, clen - 16, + c + clen - AEAD_CHACHA20_POLY1305_MAC_SIZE, + ad, adlen, npub, k); + } + if (mlen_p != NULL) { + if (ret == 0) { + mlen = clen - AEAD_CHACHA20_POLY1305_MAC_SIZE; + } + *mlen_p = mlen; + } + return ret; +} + + +int +crypto_aead_chacha20poly1305_ietf_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned long long clen = 0ULL; + int ret; + + ret = crypto_aead_chacha20poly1305_ietf_encrypt_detached(c, + c + mlen, NULL, + m, mlen, + ad, adlen, + nsec, npub, k); + if (clen_p != NULL) { + if (ret == 0) { + clen = mlen + AEAD_CHACHA20_POLY1305_MAC_SIZE; + } + *clen_p = clen; + } + return ret; +} + +// RFC 8439: ChaCha20-Poly1305-IETF Encryption with AEAD +void Aead_ChaCha20Poly1305_Ietf_Encrypt(void *dst, void *src, UINT src_size, + void *key, void *nonce, void *aad, UINT aad_size) +{ +#ifdef USE_OPENSSL_AEAD_CHACHA20POLY1305 + Aead_ChaCha20Poly1305_Ietf_Encrypt_OpenSSL(dst, src, src_size, key, nonce, aad, aad_size); +#else // USE_OPENSSL_AEAD_CHACHA20POLY1305 + Aead_ChaCha20Poly1305_Ietf_Encrypt_Embedded(dst, src, src_size, key, nonce, aad, aad_size); +#endif // USE_OPENSSL_AEAD_CHACHA20POLY1305 +} +void Aead_ChaCha20Poly1305_Ietf_Encrypt_OpenSSL(void *dst, void *src, UINT src_size, + void *key, void *nonce, void *aad, UINT aad_size) +{ +#ifdef USE_OPENSSL_AEAD_CHACHA20POLY1305 + EVP_CIPHER_CTX *ctx; + int outlen = 0; + + if ((src_size != 0 && (dst == NULL || src == NULL)) || + key == NULL || nonce == NULL || + (aad_size != 0 && aad == NULL)) + { + Zero(dst, src_size); + return; + } + + ctx = EVP_CIPHER_CTX_new(); + + EVP_EncryptInit_ex(ctx, EVP_chacha20_poly1305(), 0, 0, 0); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, AEAD_CHACHA20_POLY1305_NONCE_SIZE, 0); + EVP_EncryptInit_ex(ctx, NULL, NULL, key, nonce); + EVP_EncryptUpdate(ctx, NULL, &outlen, aad, aad_size); + EVP_EncryptUpdate(ctx, dst, &outlen, src, src_size); + EVP_EncryptFinal_ex(ctx, dst, &outlen); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, AEAD_CHACHA20_POLY1305_MAC_SIZE, + ((UCHAR *)dst) + src_size); + + EVP_CIPHER_CTX_free(ctx); +#endif // USE_OPENSSL_AEAD_CHACHA20POLY1305 +} +void Aead_ChaCha20Poly1305_Ietf_Encrypt_Embedded(void *dst, void *src, UINT src_size, + void *key, void *nonce, void *aad, UINT aad_size) +{ + if ((src_size != 0 && (dst == NULL || src == NULL)) || + key == NULL || nonce == NULL || + (aad_size != 0 && aad == NULL)) + { + Zero(dst, src_size); + return; + } + crypto_aead_chacha20poly1305_ietf_encrypt(dst, NULL, src, src_size, aad, aad_size, + NULL, nonce, key); +} + +// RFC 8439: ChaCha20-Poly1305-IETF Decryption with AEAD +bool Aead_ChaCha20Poly1305_Ietf_Decrypt(void *dst, void *src, UINT src_size, void *key, void *nonce, void *aad, UINT aad_size) +{ +#ifdef USE_OPENSSL_AEAD_CHACHA20POLY1305 + return Aead_ChaCha20Poly1305_Ietf_Decrypt_OpenSSL(dst, src, src_size, key, + nonce, aad, aad_size); +#else // USE_OPENSSL_AEAD_CHACHA20POLY1305 + return Aead_ChaCha20Poly1305_Ietf_Decrypt_Embedded(dst, src, src_size, key, + nonce, aad, aad_size); +#endif // USE_OPENSSL_AEAD_CHACHA20POLY1305 +} +bool Aead_ChaCha20Poly1305_Ietf_Decrypt_OpenSSL(void *dst, void *src, UINT src_size, void *key, + void *nonce, void *aad, UINT aad_size) +{ +#ifdef USE_OPENSSL_AEAD_CHACHA20POLY1305 + EVP_CIPHER_CTX *ctx; + int outlen = 0; + bool ret = false; + + if ((src_size != 0 && (dst == NULL || src == NULL)) || + key == NULL || nonce == NULL || + (aad_size != 0 && aad == NULL) || + (src_size < AEAD_CHACHA20_POLY1305_MAC_SIZE)) + { + Zero(dst, src_size); + return false; + } + + ctx = EVP_CIPHER_CTX_new(); + + EVP_DecryptInit_ex(ctx, EVP_chacha20_poly1305(), 0, 0, 0); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, AEAD_CHACHA20_POLY1305_NONCE_SIZE, 0); + + if (EVP_DecryptInit_ex(ctx, NULL, NULL, key, nonce) == 1) + { + if (EVP_DecryptUpdate(ctx, NULL, &outlen, aad, aad_size) == 1) + { + if (EVP_DecryptUpdate(ctx, dst, &outlen, src, src_size - AEAD_CHACHA20_POLY1305_MAC_SIZE) == 1) + { + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, AEAD_CHACHA20_POLY1305_MAC_SIZE, + ((UCHAR *)src) + (src_size - AEAD_CHACHA20_POLY1305_MAC_SIZE)); + + if (EVP_DecryptFinal_ex(ctx, dst, &outlen)) + { + ret = true; + } + } + } + } + + EVP_CIPHER_CTX_free(ctx); + + return ret; +#else // USE_OPENSSL_AEAD_CHACHA20POLY1305 + return false; +#endif // USE_OPENSSL_AEAD_CHACHA20POLY1305 +} +bool Aead_ChaCha20Poly1305_Ietf_Decrypt_Embedded(void *dst, void *src, UINT src_size, void *key, + void *nonce, void *aad, UINT aad_size) +{ + int ret; + if ((src_size != 0 && (dst == NULL || src == NULL)) || + key == NULL || nonce == NULL || + (aad_size != 0 && aad == NULL) || + (src_size < AEAD_CHACHA20_POLY1305_MAC_SIZE)) + { + Zero(dst, src_size); + return false; + } + + ret = crypto_aead_chacha20poly1305_ietf_decrypt( + dst, NULL, NULL, src, src_size, aad, aad_size, nonce, key); + + if (ret == -1) + { + return false; + } + + return true; +} + +bool Aead_ChaCha20Poly1305_Ietf_IsOpenSSL() +{ +#ifdef USE_OPENSSL_AEAD_CHACHA20POLY1305 + return true; +#else // USE_OPENSSL_AEAD_CHACHA20POLY1305 + return false; +#endif // USE_OPENSSL_AEAD_CHACHA20POLY1305 +} + +// RFC 8439: ChaCha20-Poly1305-IETF AEAD Test +void Aead_ChaCha20Poly1305_Ietf_Test() +{ + char *nonce_hex = "07 00 00 00 40 41 42 43 44 45 46 47"; + char *plaintext_hex = + "4c 61 64 69 65 73 20 61 6e 64 20 47 65 6e 74 6c " + "65 6d 65 6e 20 6f 66 20 74 68 65 20 63 6c 61 73 " + "73 20 6f 66 20 27 39 39 3a 20 49 66 20 49 20 63 " + "6f 75 6c 64 20 6f 66 66 65 72 20 79 6f 75 20 6f " + "6e 6c 79 20 6f 6e 65 20 74 69 70 20 66 6f 72 20 " + "74 68 65 20 66 75 74 75 72 65 2c 20 73 75 6e 73 " + "63 72 65 65 6e 20 77 6f 75 6c 64 20 62 65 20 69 " + "74 2e"; + char *aad_hex = "50 51 52 53 c0 c1 c2 c3 c4 c5 c6 c7"; + char *key_hex = + "80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f " + "90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f"; + BUF *nonce = StrToBin(nonce_hex); + BUF *plaintext = StrToBin(plaintext_hex); + BUF *aad = StrToBin(aad_hex); + BUF *key = StrToBin(key_hex); + UINT plaintext_size = plaintext->Size; + UCHAR *encrypted = Malloc(plaintext_size + AEAD_CHACHA20_POLY1305_MAC_SIZE); + UCHAR *decrypted = Malloc(plaintext_size); + char encrypted_hex[MAX_SIZE]; + char mac_hex[MAX_SIZE]; + + Print("Aead_ChaCha20Poly1305_Ietf_Test()\n\n"); + + Aead_ChaCha20Poly1305_Ietf_Encrypt(encrypted, plaintext->Buf, plaintext_size, + key->Buf, nonce->Buf, aad->Buf, aad->Size); + + BinToStrEx(encrypted_hex, sizeof(encrypted_hex), encrypted, plaintext_size); + + BinToStrEx(mac_hex, sizeof(mac_hex), encrypted + plaintext_size, AEAD_CHACHA20_POLY1305_MAC_SIZE); + + Print("Encrypted:\n%s\n\n", encrypted_hex); + + Print("MAC:\n%s\n\n", mac_hex); + + Print("Please check the results with https://tools.ietf.org/html/rfc8439#section-2.8.2 by your great eyes.\n\n"); + + if (Aead_ChaCha20Poly1305_Ietf_Decrypt(decrypted, encrypted, plaintext_size + AEAD_CHACHA20_POLY1305_MAC_SIZE, + key->Buf, nonce->Buf, aad->Buf, aad->Size) == false) + { + Print("Decrypt failed.\n"); + } + else + { + Print("Decrypt OK.\n"); + if (Cmp(plaintext->Buf, decrypted, plaintext_size) == 0) + { + Print("Same OK.\n"); + } + else + { + Print("Different !!!\n"); + } + } + + FreeBuf(nonce); + FreeBuf(plaintext); + FreeBuf(aad); + FreeBuf(key); + Free(encrypted); + Free(decrypted); +} + diff --git a/src/Mayaqua/Encrypt.h b/src/Mayaqua/Encrypt.h index 1be31649..d5b334b7 100644 --- a/src/Mayaqua/Encrypt.h +++ b/src/Mayaqua/Encrypt.h @@ -105,6 +105,10 @@ #ifndef ENCRYPT_H #define ENCRYPT_H +#if OPENSSL_VERSION_NUMBER >= 0x10100000L +//#define USE_OPENSSL_AEAD_CHACHA20POLY1305 +#endif + // Function of OpenSSL void RAND_Init_For_SoftEther(); void RAND_Free_For_SoftEther(); @@ -132,6 +136,12 @@ void RAND_Free_For_SoftEther(); #define AES_IV_SIZE 16 // AES IV size #define AES_MAX_KEY_SIZE 32 // Maximum AES key size +// RFC 8439: ChaCha20 and Poly1305 for IETF Protocols +#define AEAD_CHACHA20_POLY1305_MAC_SIZE 16 // MAC size +#define AEAD_CHACHA20_POLY1305_NONCE_SIZE 12 // Nonce size +#define AEAD_CHACHA20_POLY1305_KEY_SIZE 32 // Key size + + // IANA definitions taken from IKEv1 Phase 1 #define SHA1_160 2 #define SHA2_256 4 @@ -574,6 +584,22 @@ BUF *EasyDecrypt(BUF *src_buf); void DisableIntelAesAccel(); +int GetSslClientCertIndex(); + +void Aead_ChaCha20Poly1305_Ietf_Encrypt_Embedded(void *dst, void *src, UINT src_size, void *key, void *nonce, void *aad, UINT aad_size); +bool Aead_ChaCha20Poly1305_Ietf_Decrypt_Embedded(void *dst, void *src, UINT src_size, void *key, void *nonce, void *aad, UINT aad_size); + +void Aead_ChaCha20Poly1305_Ietf_Encrypt_OpenSSL(void *dst, void *src, UINT src_size, void *key, void *nonce, void *aad, UINT aad_size); +bool Aead_ChaCha20Poly1305_Ietf_Decrypt_OpenSSL(void *dst, void *src, UINT src_size, void *key, void *nonce, void *aad, UINT aad_size); + +void Aead_ChaCha20Poly1305_Ietf_Encrypt(void *dst, void *src, UINT src_size, void *key, void *nonce, void *aad, UINT aad_size); +bool Aead_ChaCha20Poly1305_Ietf_Decrypt(void *dst, void *src, UINT src_size, void *key, void *nonce, void *aad, UINT aad_size); + +bool Aead_ChaCha20Poly1305_Ietf_IsOpenSSL(); + +void Aead_ChaCha20Poly1305_Ietf_Test(); + + #ifdef ENCRYPT_C // Inner function diff --git a/src/Mayaqua/FileIO.c b/src/Mayaqua/FileIO.c index 7d731404..f40d3b3a 100644 --- a/src/Mayaqua/FileIO.c +++ b/src/Mayaqua/FileIO.c @@ -1292,6 +1292,12 @@ void BuildHamcore(char *dst_filename, char *src_dir, bool unix_only) } } + if (InStr(rpath, "\\node_modules\\")) + { + // Exclude node_modules in the hamcore\webroot + ok = false; + } + if (ok) { b = ReadDump(s); diff --git a/src/Mayaqua/Kernel.c b/src/Mayaqua/Kernel.c index ddc9b748..28dd4b6e 100644 --- a/src/Mayaqua/Kernel.c +++ b/src/Mayaqua/Kernel.c @@ -1622,11 +1622,102 @@ void GetDateTimeStrMilli(char *str, UINT size, SYSTEMTIME *st) st->wMilliseconds); } +// Convert string RFC3339 format (example: 2017-09-27T18:25:55.434-9:00) to UINT64 +UINT64 DateTimeStrRFC3339ToSystemTime64(char *str) +{ + SYSTEMTIME st; + if (DateTimeStrRFC3339ToSystemTime(&st, str)) + { + return SystemToUINT64(&st); + } + else + { + return 0; + } +} + +// Convert string RFC3339 format (example: 2017-09-27T18:25:55.434-9:00) to SYSTEMTIME +bool DateTimeStrRFC3339ToSystemTime(SYSTEMTIME *st, char *str) +{ + bool ok = false; + UINT index_plus; + char tmp[MAX_PATH]; + Zero(st, sizeof(SYSTEMTIME)); + if (st == NULL || str == NULL) + { + return false; + } + + StrCpy(tmp, sizeof(tmp), str); + + index_plus = SearchStrEx(tmp, "+", 0, false); + if (index_plus != INFINITE) + { + tmp[index_plus] = 0; + } + + if (StrLen(tmp) >= 19) + { + if (tmp[4] == '-' && tmp[7] == '-' && tmp[10] == 'T' && tmp[13] == ':' && + tmp[16] == ':') + { + char str_year[16], str_month[16], str_day[16], str_hour[16], str_minute[16], + str_second[16], str_msec[16]; + + StrCpy(str_year, sizeof(str_year), tmp + 0); + str_year[4] = 0; + + StrCpy(str_month, sizeof(str_month), tmp + 5); + str_month[2] = 0; + + StrCpy(str_day, sizeof(str_day), tmp + 8); + str_day[2] = 0; + + StrCpy(str_hour, sizeof(str_hour), tmp + 11); + str_hour[2] = 0; + + StrCpy(str_minute, sizeof(str_minute), tmp + 14); + str_minute[2] = 0; + + StrCpy(str_second, sizeof(str_second), tmp + 17); + str_second[2] = 0; + + str_msec[0] = 0; + + if (StrLen(tmp) >= 21 && tmp[19] == '.') + { + StrCpy(str_msec, sizeof(str_msec), tmp + 20); + str_msec[StrLen(tmp) - 21] = 0; + while (StrLen(str_msec) < 3) + { + StrCat(str_msec, sizeof(str_msec), "0"); + } + str_msec[3] = 0; + } + + st->wYear = ToInt(str_year); + st->wMonth = ToInt(str_month); + st->wDay = ToInt(str_day); + st->wHour = ToInt(str_hour); + st->wMinute = ToInt(str_minute); + st->wSecond = ToInt(str_second); + st->wMilliseconds = ToInt(str_msec); + + NormalizeSystem(st); + + ok = true; + } + } + + return ok; +} + // Get the date and time string in RFC3339 format (example: 2017-09-27T18:25:55.434-9:00) void GetDateTimeStrRFC3339(char *str, UINT size, SYSTEMTIME *st, int timezone_min){ // Validate arguments if (str == NULL || st == NULL) { + ClearStr(str, size); return; } diff --git a/src/Mayaqua/Kernel.h b/src/Mayaqua/Kernel.h index 5ba4a72c..35dd9679 100644 --- a/src/Mayaqua/Kernel.h +++ b/src/Mayaqua/Kernel.h @@ -240,6 +240,8 @@ void GetDateStrEx64(wchar_t *str, UINT size, UINT64 sec64, LOCALE *locale); void GetTimeStrMilli64(char *str, UINT size, UINT64 sec64); void GetTimeStr64(char *str, UINT size, UINT64 sec64); void GetDateTimeStrRFC3339(char *str, UINT size, SYSTEMTIME *st, int timezone_min); +bool DateTimeStrRFC3339ToSystemTime(SYSTEMTIME *st, char *str); +UINT64 DateTimeStrRFC3339ToSystemTime64(char *str); UINT64 SafeTime64(UINT64 sec64); bool Run(char *filename, char *arg, bool hide, bool wait); bool RunW(wchar_t *filename, wchar_t *arg, bool hide, bool wait); diff --git a/src/Mayaqua/MayaType.h b/src/Mayaqua/MayaType.h index 01810e7c..ae173617 100644 --- a/src/Mayaqua/MayaType.h +++ b/src/Mayaqua/MayaType.h @@ -136,7 +136,7 @@ typedef struct x509_crl_st X509_CRL; #define BUF_SIZE 512 // Support Windows OS list -#define SUPPORTED_WINDOWS_LIST "Windows 98 / 98 SE / ME / NT 4.0 SP6a / 2000 SP4 / XP SP2, SP3 / Vista SP1, SP2 / 7 SP1 / 8 / 8.1 / 10 / Server 2003 SP2 / Server 2008 SP1, SP2 / Hyper-V Server 2008 / Server 2008 R2 SP1 / Hyper-V Server 2008 R2 / Server 2012 / Hyper-V Server 2012 / Server 2012 R2 / Hyper-V Server 2012 R2 / Server 2016" +#define SUPPORTED_WINDOWS_LIST "Windows 98 / 98 SE / ME / NT 4.0 SP6a / 2000 SP4 / XP SP2, SP3 / Vista SP1, SP2 / 7 SP1 / 8 / 8.1 / 10 / Server 2003 SP2 / Server 2008 SP1, SP2 / Hyper-V Server 2008 / Server 2008 R2 SP1 / Hyper-V Server 2008 R2 / Server 2012 / Hyper-V Server 2012 / Server 2012 R2 / Hyper-V Server 2012 R2 / Server 2016 / Server 2019" // Infinite #ifndef WINDOWS_H @@ -421,6 +421,9 @@ typedef struct PRAND PRAND; // Str.h typedef struct TOKEN_LIST TOKEN_LIST; typedef struct INI_ENTRY INI_ENTRY; +typedef struct JSON_OBJECT JSON_OBJECT; +typedef struct JSON_ARRAY JSON_ARRAY; +typedef struct JSON_VALUE JSON_VALUE; // Internat.h typedef struct UNI_TOKEN_LIST UNI_TOKEN_LIST; @@ -457,6 +460,8 @@ typedef struct INSTANCE INSTANCE; typedef struct VALUE VALUE; typedef struct ELEMENT ELEMENT; typedef struct PACK PACK; +typedef struct JSONPACKHINT JSONPACKHINT; +typedef struct JSONPACKHINT_ITEM JSONPACKHINT_ITEM; // Cfg.h typedef struct FOLDER FOLDER; diff --git a/src/Mayaqua/Memory.c b/src/Mayaqua/Memory.c index f13d0e47..14bbcafb 100644 --- a/src/Mayaqua/Memory.c +++ b/src/Mayaqua/Memory.c @@ -1646,6 +1646,48 @@ bool ReplaceListPointer(LIST *o, void *oldptr, void *newptr) return false; } +// New string list +LIST *NewStrList() +{ + return NewListFast(CompareStr); +} + +// Release string list +void ReleaseStrList(LIST *o) +{ + UINT i; + if (o == NULL) + { + return; + } + + for (i = 0;i < LIST_NUM(o);i++) + { + char *s = LIST_DATA(o, i); + Free(s); + } + + ReleaseList(o); +} + +// Add a string distinct to the string list +bool AddStrToStrListDistinct(LIST *o, char *str) +{ + if (o == NULL || str == NULL) + { + return false; + } + + if (IsInListStr(o, str) == false) + { + Add(o, CopyStr(str)); + + return true; + } + + return false; +} + // Examine whether a string items are present in the list bool IsInListStr(LIST *o, char *str) { @@ -3361,6 +3403,43 @@ void WriteBufBuf(BUF *b, BUF *bb) WriteBuf(b, bb->Buf, bb->Size); } +// Write the buffer (from the offset) to a buffer +void WriteBufBufWithOffset(BUF *b, BUF *bb) +{ + // Validate arguments + if (b == NULL || bb == NULL) + { + return; + } + + WriteBuf(b, ((UCHAR *)bb->Buf) + bb->Current, bb->Size - bb->Current); +} + +// Skip UTF-8 BOM +bool BufSkipUtf8Bom(BUF *b) +{ + if (b == NULL) + { + return false; + } + + SeekBufToBegin(b); + + if (b->Size >= 3) + { + UCHAR *data = b->Buf; + + if (data[0] == 0xEF && data[1] == 0xBB && data[2] == 0xBF) + { + SeekBuf(b, 3, 1); + + return true; + } + } + + return false; +} + // Read into a buffer from the buffer BUF *ReadBufFromBuf(BUF *b, UINT size) { @@ -4226,7 +4305,7 @@ void *InternalReAlloc(void *addr, UINT size) } #ifndef DONT_USE_KERNEL_STATUS - TrackChangeObjSize((DWORD)addr, size, (DWORD)new_addr); + TrackChangeObjSize(POINTER_TO_UINT64(addr), size, POINTER_TO_UINT64(new_addr)); #endif // DONT_USE_KERNEL_STATUS return new_addr; diff --git a/src/Mayaqua/Memory.h b/src/Mayaqua/Memory.h index 8b981aa9..04392e7e 100644 --- a/src/Mayaqua/Memory.h +++ b/src/Mayaqua/Memory.h @@ -305,7 +305,9 @@ BUF *NewBufFromMemory(void *buf, UINT size); void ClearBuf(BUF *b); void WriteBuf(BUF *b, void *buf, UINT size); void WriteBufBuf(BUF *b, BUF *bb); +void WriteBufBufWithOffset(BUF *b, BUF *bb); UINT ReadBuf(BUF *b, void *buf, UINT size); +bool BufSkipUtf8Bom(BUF *b); BUF *ReadBufFromBuf(BUF *b, UINT size); void AdjustBufSize(BUF *b, UINT new_size); void SeekBuf(BUF *b, UINT offset, int mode); @@ -469,5 +471,9 @@ void CleanupSharedBuffer(SHARED_BUFFER *b); void AppendBufUtf8(BUF *b, wchar_t *str); void AppendBufStr(BUF *b, char *str); +LIST *NewStrList(); +void ReleaseStrList(LIST *o); +bool AddStrToStrListDistinct(LIST *o, char *str); + #endif // MEMORY_H diff --git a/src/Mayaqua/Microsoft.c b/src/Mayaqua/Microsoft.c index 8d71f29c..b4e95a2a 100644 --- a/src/Mayaqua/Microsoft.c +++ b/src/Mayaqua/Microsoft.c @@ -3413,6 +3413,60 @@ HANDLE MsCreateUserToken() } +// Check whether SHA-2 kernel mode signature is supported +bool MsIsSha2KernelModeSignatureSupported() +{ + HINSTANCE hDll; + bool ret = false; + + if (MsIsWindows8()) + { + return true; + } + + hDll = LoadLibrary("Wintrust.dll"); + if (hDll == NULL) + { + return false; + } + + if (GetProcAddress(hDll, "CryptCATAdminAcquireContext2") != NULL) + { + ret = true; + } + + FreeLibrary(hDll); + + return ret; +} + +// Check whether KB3033929 is required +bool MsIsKB3033929RequiredAndMissing() +{ + OS_INFO *info = GetOsInfo(); + + if (info == NULL) + { + return false; + } + + if (OS_IS_WINDOWS_NT(info->OsType)) + { + if (GET_KETA(info->OsType, 100) == 6) + { + if (MsIsX64()) + { + if (MsIsSha2KernelModeSignatureSupported() == false) + { + return true; + } + } + } + } + + return false; +} + // Check the digital signature of the file bool MsCheckFileDigitalSignature(HWND hWnd, char *name, bool *danger) { diff --git a/src/Mayaqua/Microsoft.h b/src/Mayaqua/Microsoft.h index c5d85d50..8046e95d 100644 --- a/src/Mayaqua/Microsoft.h +++ b/src/Mayaqua/Microsoft.h @@ -1017,6 +1017,9 @@ bool MsIsInfCatalogRequired(); bool MsCheckFileDigitalSignature(HWND hWnd, char *name, bool *danger); bool MsCheckFileDigitalSignatureW(HWND hWnd, wchar_t *name, bool *danger); +bool MsIsKB3033929RequiredAndMissing(); +bool MsIsSha2KernelModeSignatureSupported(); + bool MsGetProcessExeName(char *path, UINT size, UINT id); bool MsGetProcessExeNameW(wchar_t *path, UINT size, UINT id); diff --git a/src/Mayaqua/Network.c b/src/Mayaqua/Network.c index f7768a57..ded99b77 100644 --- a/src/Mayaqua/Network.c +++ b/src/Mayaqua/Network.c @@ -2651,70 +2651,128 @@ void RUDPBulkSend(RUDP_STACK *r, RUDP_SESSION *se, void *data, UINT data_size) UCHAR crypt_key_src[SHA1_SIZE * 2]; UCHAR crypt_key[SHA1_SIZE]; UINT icmp_type; - UCHAR sign[SHA1_SIZE]; - UCHAR iv[SHA1_SIZE + 1]; // Validate arguments if (r == NULL || se == NULL || (data == NULL && data_size != 0)) { return; } - padding_size = Rand32() % 31 + 1; - - buf_size = SHA1_SIZE + SHA1_SIZE + sizeof(UINT64) + data_size + padding_size; - buf = Malloc(buf_size); - - // SEQ NO - WRITE_UINT64(buf + SHA1_SIZE + SHA1_SIZE, se->BulkNextSeqNo); - se->BulkNextSeqNo++; - - // Data - Copy(buf + SHA1_SIZE + SHA1_SIZE + sizeof(UINT64), data, data_size); - - // Padding - for (i = 0;i < padding_size;i++) + if (se->BulkSendKey->Size == RUDP_BULK_KEY_SIZE_V2) { - buf[SHA1_SIZE + SHA1_SIZE + sizeof(UINT64) + data_size + i] = (UCHAR)padding_size; - } + // Ver 2 + UCHAR iv[RUDP_BULK_IV_SIZE_V2]; - // Encryption - Copy(iv, se->BulkNextIv, SHA1_SIZE); - Copy(crypt_key_src + 0, se->BulkSendKey->Data, SHA1_SIZE); - Copy(crypt_key_src + SHA1_SIZE, iv, SHA1_SIZE); - HashSha1(crypt_key, crypt_key_src, SHA1_SIZE * 2); - c = NewCrypt(crypt_key, sizeof(crypt_key)); - Encrypt(c, buf + SHA1_SIZE + SHA1_SIZE, buf + SHA1_SIZE + SHA1_SIZE, sizeof(UINT64) + data_size + padding_size); - FreeCrypt(c); + padding_size = Rand32() % 31 + 1; - // IV - Copy(buf + SHA1_SIZE, iv, SHA1_SIZE); + // Packet: IV + Encrypted(SEQ_NO + Data + padding) + MAC + buf_size = RUDP_BULK_IV_SIZE_V2 + sizeof(UINT64) + data_size + padding_size + RUDP_BULK_MAC_SIZE_V2; + buf = Malloc(buf_size); - // Sign - if (se->UseHMac == false) - { - Copy(buf + 0, se->BulkSendKey->Data, SHA1_SIZE); - HashSha1(sign, buf, SHA1_SIZE + SHA1_SIZE + sizeof(UINT64) + data_size + padding_size); - Copy(buf + 0, sign, SHA1_SIZE); + // IV + Copy(iv, se->BulkNextIv_V2, RUDP_BULK_IV_SIZE_V2); + Copy(buf, iv, RUDP_BULK_IV_SIZE_V2); + + // SEQ NO + WRITE_UINT64(buf + RUDP_BULK_IV_SIZE_V2, se->BulkNextSeqNo); + se->BulkNextSeqNo++; + + // Data + Copy(buf + RUDP_BULK_IV_SIZE_V2 + sizeof(UINT64), data, data_size); + + // Padding + for (i = 0;i < padding_size;i++) + { + buf[RUDP_BULK_IV_SIZE_V2 + sizeof(UINT64) + data_size + i] = (UCHAR)padding_size; + } + + // Encryption + Aead_ChaCha20Poly1305_Ietf_Encrypt(buf + RUDP_BULK_IV_SIZE_V2, + buf + RUDP_BULK_IV_SIZE_V2, + sizeof(UINT64) + data_size + padding_size, + se->BulkSendKey->Data, + iv, + NULL, + 0); + + // Next IV + Copy(se->BulkNextIv_V2, buf + RUDP_BULK_IV_SIZE_V2 + sizeof(UINT64) + data_size + padding_size - RUDP_BULK_IV_SIZE_V2, + RUDP_BULK_IV_SIZE_V2); + + if (r->Protocol == RUDP_PROTOCOL_ICMP) + { + icmp_type = se->Icmp_Type; + } + else if (r->Protocol == RUDP_PROTOCOL_DNS) + { + icmp_type = se->Dns_TranId; + } + RUDPSendPacket(r, &se->YourIp, se->YourPort, buf, buf_size, icmp_type); + + Free(buf); } else { - HMacSha1(buf + 0, se->BulkSendKey->Data, SHA1_SIZE, buf + SHA1_SIZE, SHA1_SIZE + sizeof(UINT64) + data_size + padding_size); - } + UCHAR sign[SHA1_SIZE]; + UCHAR iv[SHA1_SIZE]; - // Next IV - Copy(se->BulkNextIv, buf + buf_size - SHA1_SIZE, SHA1_SIZE); + // Ver 1 + padding_size = Rand32() % 31 + 1; - if (r->Protocol == RUDP_PROTOCOL_ICMP) - { - icmp_type = se->Icmp_Type; - } - else if (r->Protocol == RUDP_PROTOCOL_DNS) - { - icmp_type = se->Dns_TranId; - } - RUDPSendPacket(r, &se->YourIp, se->YourPort, buf, buf_size, icmp_type); + buf_size = SHA1_SIZE + SHA1_SIZE + sizeof(UINT64) + data_size + padding_size; + buf = Malloc(buf_size); - Free(buf); + // SEQ NO + WRITE_UINT64(buf + SHA1_SIZE + SHA1_SIZE, se->BulkNextSeqNo); + se->BulkNextSeqNo++; + + // Data + Copy(buf + SHA1_SIZE + SHA1_SIZE + sizeof(UINT64), data, data_size); + + // Padding + for (i = 0;i < padding_size;i++) + { + buf[SHA1_SIZE + SHA1_SIZE + sizeof(UINT64) + data_size + i] = (UCHAR)padding_size; + } + + // Encryption + Copy(iv, se->BulkNextIv, SHA1_SIZE); + Copy(crypt_key_src + 0, se->BulkSendKey->Data, SHA1_SIZE); + Copy(crypt_key_src + SHA1_SIZE, iv, SHA1_SIZE); + HashSha1(crypt_key, crypt_key_src, SHA1_SIZE * 2); + c = NewCrypt(crypt_key, sizeof(crypt_key)); + Encrypt(c, buf + SHA1_SIZE + SHA1_SIZE, buf + SHA1_SIZE + SHA1_SIZE, sizeof(UINT64) + data_size + padding_size); + FreeCrypt(c); + + // IV + Copy(buf + SHA1_SIZE, iv, SHA1_SIZE); + + // Sign + if (se->UseHMac == false) + { + Copy(buf + 0, se->BulkSendKey->Data, SHA1_SIZE); + HashSha1(sign, buf, SHA1_SIZE + SHA1_SIZE + sizeof(UINT64) + data_size + padding_size); + Copy(buf + 0, sign, SHA1_SIZE); + } + else + { + HMacSha1(buf + 0, se->BulkSendKey->Data, SHA1_SIZE, buf + SHA1_SIZE, SHA1_SIZE + sizeof(UINT64) + data_size + padding_size); + } + + // Next IV + Copy(se->BulkNextIv, buf + buf_size - SHA1_SIZE, SHA1_SIZE); + + if (r->Protocol == RUDP_PROTOCOL_ICMP) + { + icmp_type = se->Icmp_Type; + } + else if (r->Protocol == RUDP_PROTOCOL_DNS) + { + icmp_type = se->Dns_TranId; + } + RUDPSendPacket(r, &se->YourIp, se->YourPort, buf, buf_size, icmp_type); + + Free(buf); + } } // Start a socket for R-UDP Listening @@ -2775,14 +2833,20 @@ SOCK *AcceptRUDP(SOCK *s) { case RUDP_PROTOCOL_UDP: StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_NAT_T); + AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), + "RUDP/UDP"); break; case RUDP_PROTOCOL_DNS: StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_DNS); + AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), + "RUDP/DNS"); break; case RUDP_PROTOCOL_ICMP: StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_ICMP); + AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), + "RUDP/ICMP"); break; } @@ -2835,26 +2899,55 @@ bool RUDPCheckSignOfRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data, } // Verification signature (bulk packet) - if (se->UseHMac == false) + if (se->BulkRecvKey->Size == RUDP_BULK_KEY_SIZE_V2) { - Copy(sign, p, SHA1_SIZE); - Copy(p, se->BulkRecvKey->Data, SHA1_SIZE); - HashSha1(sign2, p, recv_size); - Copy(p, sign, SHA1_SIZE); - - if (Cmp(sign, sign2, SHA1_SIZE) == 0) + // Ver 2 + UCHAR *iv = p; + // Packet: IV + Encrypted(SEQ_NO + Data + padding) + MAC + // IV + if (size < RUDP_BULK_IV_SIZE_V2) { + return false; + } + iv = p; + p += RUDP_BULK_IV_SIZE_V2; + size -= RUDP_BULK_IV_SIZE_V2; + + // Decrypt + if (size < (RUDP_BULK_MAC_SIZE_V2 + 1)) + { + return false; + } + if (Aead_ChaCha20Poly1305_Ietf_Decrypt(r->TmpBuf, p, size, se->BulkRecvKey->Data, iv, NULL, 0) == false) + { + return false; + } + return true; + } + else + { + // Ver 1 + if (se->UseHMac == false) + { + Copy(sign, p, SHA1_SIZE); + Copy(p, se->BulkRecvKey->Data, SHA1_SIZE); + HashSha1(sign2, p, recv_size); + Copy(p, sign, SHA1_SIZE); + + if (Cmp(sign, sign2, SHA1_SIZE) == 0) + { + return true; + } + } + + HMacSha1(sign2, se->BulkRecvKey->Data, SHA1_SIZE, p + SHA1_SIZE, size - SHA1_SIZE); + if (Cmp(p, sign2, SHA1_SIZE) == 0) + { + se->UseHMac = true; return true; } } - HMacSha1(sign2, se->BulkRecvKey->Data, SHA1_SIZE, p + SHA1_SIZE, size - SHA1_SIZE); - if (Cmp(p, sign2, SHA1_SIZE) == 0) - { - se->UseHMac = true; - return true; - } - return false; } @@ -2886,15 +2979,76 @@ bool RUDPProcessBulkRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data, return false; } - // Validate the signature - if (se->UseHMac == false) + if (se->BulkRecvKey->Size == RUDP_BULK_KEY_SIZE_V2) { - Copy(sign, p, SHA1_SIZE); - Copy(p, se->BulkRecvKey->Data, SHA1_SIZE); - HashSha1(sign2, p, recv_size); - Copy(p, sign, SHA1_SIZE); + // Ver 2 + // Packet: IV + Encrypted(SEQ_NO + Data + padding) + MAC + // IV + if (size < RUDP_BULK_IV_SIZE_V2) + { + WHERE; + return false; + } + iv = p; + p += RUDP_BULK_IV_SIZE_V2; + size -= RUDP_BULK_IV_SIZE_V2; - if (Cmp(sign, sign2, SHA1_SIZE) != 0) + // Decrypt + if (size < (RUDP_BULK_MAC_SIZE_V2 + 1)) + { + WHERE; + return false; + } + if (Aead_ChaCha20Poly1305_Ietf_Decrypt(p, p, size, se->BulkRecvKey->Data, iv, NULL, 0) == false) + { + WHERE; + return false; + } + + size -= RUDP_BULK_MAC_SIZE_V2; + + // padlen + padlen = p[size - 1]; + if (padlen == 0) + { + WHERE; + return false; + } + if (size < padlen) + { + WHERE; + return false; + } + size -= padlen; + } + else + { + // Validate the signature + if (se->UseHMac == false) + { + Copy(sign, p, SHA1_SIZE); + Copy(p, se->BulkRecvKey->Data, SHA1_SIZE); + HashSha1(sign2, p, recv_size); + Copy(p, sign, SHA1_SIZE); + + if (Cmp(sign, sign2, SHA1_SIZE) != 0) + { + HMacSha1(sign2, se->BulkRecvKey->Data, SHA1_SIZE, p + SHA1_SIZE, recv_size - SHA1_SIZE); + + if (Cmp(p, sign2, SHA1_SIZE) != 0) + { + return false; + } + else + { + se->UseHMac = true; + } + } + else + { + } + } + else { HMacSha1(sign2, se->BulkRecvKey->Data, SHA1_SIZE, p + SHA1_SIZE, recv_size - SHA1_SIZE); @@ -2902,61 +3056,45 @@ bool RUDPProcessBulkRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data, { return false; } - else - { - se->UseHMac = true; - } } - else - { - } - } - else - { - HMacSha1(sign2, se->BulkRecvKey->Data, SHA1_SIZE, p + SHA1_SIZE, recv_size - SHA1_SIZE); - if (Cmp(p, sign2, SHA1_SIZE) != 0) + p += SHA1_SIZE; + size -= SHA1_SIZE; + + // IV + if (size < SHA1_SIZE) { return false; } - } + iv = p; + p += SHA1_SIZE; + size -= SHA1_SIZE; - p += SHA1_SIZE; - size -= SHA1_SIZE; + // Decrypt + if (size < 1) + { + return false; + } + Copy(keygen + 0, se->BulkRecvKey->Data, SHA1_SIZE); + Copy(keygen + SHA1_SIZE, iv, SHA1_SIZE); + HashSha1(key, keygen, sizeof(keygen)); - // IV - if (size < SHA1_SIZE) - { - return false; - } - iv = p; - p += SHA1_SIZE; - size -= SHA1_SIZE; + c = NewCrypt(key, sizeof(key)); + Encrypt(c, p, p, size); + FreeCrypt(c); - // Decrypt - if (size < 1) - { - return false; + // padlen + padlen = p[size - 1]; + if (padlen == 0) + { + return false; + } + if (size < padlen) + { + return false; + } + size -= padlen; } - Copy(keygen + 0, se->BulkRecvKey->Data, SHA1_SIZE); - Copy(keygen + SHA1_SIZE, iv, SHA1_SIZE); - HashSha1(key, keygen, sizeof(keygen)); - - c = NewCrypt(key, sizeof(key)); - Encrypt(c, p, p, size); - FreeCrypt(c); - - // padlen - padlen = p[size - 1]; - if (padlen == 0) - { - return false; - } - if (size < padlen) - { - return false; - } - size -= padlen; // SEQ NO seq_no = READ_UINT64(p); @@ -3769,8 +3907,8 @@ RUDP_SESSION *RUDPNewSession(bool server_mode, IP *my_ip, UINT my_port, IP *your RUDP_SESSION *se; UCHAR key1[SHA1_SIZE]; UCHAR key2[SHA1_SIZE]; - UCHAR bulk_send_key[SHA1_SIZE]; - UCHAR bulk_recv_key[SHA1_SIZE]; + UCHAR bulk_send_key[RUDP_BULK_KEY_SIZE_MAX]; + UCHAR bulk_recv_key[RUDP_BULK_KEY_SIZE_MAX]; BUF *b; se = ZeroMalloc(sizeof(RUDP_SESSION)); @@ -3856,6 +3994,8 @@ RUDP_SESSION *RUDPNewSession(bool server_mode, IP *my_ip, UINT my_port, IP *your se->BulkRecvKey = NewSharedBuffer(bulk_recv_key, sizeof(bulk_recv_key)); Rand(se->BulkNextIv, sizeof(se->BulkNextIv)); + Rand(se->BulkNextIv_V2, sizeof(se->BulkNextIv_V2)); + se->BulkNextSeqNo = 1; return se; @@ -5806,8 +5946,53 @@ int cb_test(int a, X509_STORE_CTX *ctx) return 1; } +// Verify client SSL certificate during TLS handshake. +// +// (actually, only save the certificate for later authentication in Protocol.c) +int SslCertVerifyCallback(int preverify_ok, X509_STORE_CTX *ctx) +{ + SSL *ssl; + struct SslClientCertInfo *clientcert; + + ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); + clientcert = SSL_get_ex_data(ssl, GetSslClientCertIndex()); + + if (clientcert != NULL) + { + clientcert->PreverifyErr = 0; + clientcert->PreverifyErrMessage[0] = '\0'; + if (!preverify_ok) + { + char *msg; + clientcert->PreverifyErr = X509_STORE_CTX_get_error(ctx); + msg = (char *)X509_verify_cert_error_string(clientcert->PreverifyErr); + StrCpy(clientcert->PreverifyErrMessage, PREVERIFY_ERR_MESSAGE_SIZE, msg); + Debug("SslCertVerifyCallback preverify error: '%s'\n", msg); + } + else + { + if (ctx->cert != NULL) + { + X *tmpX = X509ToX(ctx->cert); // this only wraps ctx->cert, but we need to make a copy + X *copyX = CloneX(tmpX); + tmpX->do_not_free = true; // do not release inner X509 object + FreeX(tmpX); + clientcert->X = copyX; + } + } + } + + return 1; /* allow the verification process to continue */ +} + // Create a new SSL pipe SSL_PIPE *NewSslPipe(bool server_mode, X *x, K *k, DH_CTX *dh) +{ + return NewSslPipeEx(server_mode, x, k, dh, false, NULL); +} + +// Create a new SSL pipe with extended options +SSL_PIPE *NewSslPipeEx(bool server_mode, X *x, K *k, DH_CTX *dh, bool verify_peer, struct SslClientCertInfo *clientcert) { SSL_PIPE *s; SSL *ssl; @@ -5832,7 +6017,10 @@ SSL_PIPE *NewSslPipe(bool server_mode, X *x, K *k, DH_CTX *dh) SSL_CTX_set_ssl_version(ssl_ctx, SSLv23_client_method()); } - //SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, cb_test); + if (verify_peer) + { + SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, SslCertVerifyCallback); + } if (dh != NULL) { @@ -5845,6 +6033,8 @@ SSL_PIPE *NewSslPipe(bool server_mode, X *x, K *k, DH_CTX *dh) } ssl = SSL_new(ssl_ctx); + + SSL_set_ex_data(ssl, GetSslClientCertIndex(), clientcert); } Unlock(openssl_lock); @@ -12654,6 +12844,50 @@ void InitSockSet(SOCKSET *set) Zero(set, sizeof(SOCKSET)); } +// Receive data and discard all of them +bool RecvAllWithDiscard(SOCK *sock, UINT size, bool secure) +{ + static UCHAR buffer[4096]; + UINT recv_size, sz, ret; + if (sock == NULL) + { + return false; + } + if (size == 0) + { + return true; + } + if (sock->AsyncMode) + { + return false; + } + + recv_size = 0; + + while (true) + { + sz = MIN(size - recv_size, sizeof(buffer)); + ret = Recv(sock, buffer, sz, secure); + if (ret == 0) + { + return false; + } + if (ret == SOCK_LATER) + { + // I suppose that this is safe because the RecvAll() function is used only + // if the sock->AsyncMode == true. And the Recv() function may return + // SOCK_LATER only if the sock->AsyncMode == false. Therefore the call of + // Recv() function in the RecvAll() function never returns SOCK_LATER. + return false; + } + recv_size += ret; + if (recv_size >= size) + { + return true; + } + } +} + // Receive all by TCP bool RecvAll(SOCK *sock, void *data, UINT size, bool secure) { @@ -14024,6 +14258,8 @@ SOCK *Accept(SOCK *sock) StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_NATIVE_V4); + AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "IPv4"); + return ret; } @@ -14134,6 +14370,8 @@ SOCK *Accept6(SOCK *sock) StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_NATIVE_V6); + AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "IPv6"); + return ret; } @@ -15372,6 +15610,8 @@ SOCK *ConnectEx4(char *hostname, UINT port, UINT timeout, bool *cancel_flag, cha if (nat_t_sock != NULL) { StrCpy(nat_t_sock->UnderlayProtocol, sizeof(nat_t_sock->UnderlayProtocol), SOCK_UNDERLAY_NAT_T); + AddProtocolDetailsStr(nat_t_sock->ProtocolDetails, sizeof(nat_t_sock->ProtocolDetails), + "RUDP"); } Copy(ret_ip, &ip4, sizeof(IP)); @@ -15599,6 +15839,8 @@ SOCK *ConnectEx4(char *hostname, UINT port, UINT timeout, bool *cancel_flag, cha StrCpy(p2.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p2.Result_Nat_T_Sock->UnderlayProtocol), SOCK_UNDERLAY_NAT_T); + AddProtocolDetailsStr(p2.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p2.Result_Nat_T_Sock->UnderlayProtocol), + "RUDP/UDP"); Copy(ret_ip, &ip4, sizeof(IP)); @@ -15613,6 +15855,8 @@ SOCK *ConnectEx4(char *hostname, UINT port, UINT timeout, bool *cancel_flag, cha StrCpy(p4.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p4.Result_Nat_T_Sock->UnderlayProtocol), SOCK_UNDERLAY_DNS); + AddProtocolDetailsStr(p4.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p4.Result_Nat_T_Sock->UnderlayProtocol), + "RUDP/DNS"); Copy(ret_ip, &ip4, sizeof(IP)); @@ -15623,6 +15867,8 @@ SOCK *ConnectEx4(char *hostname, UINT port, UINT timeout, bool *cancel_flag, cha // Use this if over ICMP success StrCpy(p3.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p3.Result_Nat_T_Sock->UnderlayProtocol), SOCK_UNDERLAY_ICMP); + AddProtocolDetailsStr(p3.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p3.Result_Nat_T_Sock->UnderlayProtocol), + "RUDP/ICMP"); Copy(ret_ip, &ip4, sizeof(IP)); @@ -15689,6 +15935,9 @@ SOCK *ConnectEx4(char *hostname, UINT port, UINT timeout, bool *cancel_flag, cha StrCpy(sock->UnderlayProtocol, sizeof(sock->UnderlayProtocol), (is_ipv6 ? SOCK_UNDERLAY_NATIVE_V6 : SOCK_UNDERLAY_NATIVE_V4)); + AddProtocolDetailsStr(sock->ProtocolDetails, sizeof(sock->ProtocolDetails), + is_ipv6 ? "IPv6" : "IPv4"); + // Host name resolution if (no_get_hostname || (GetHostName(tmp, sizeof(tmp), ¤t_ip) == false)) { @@ -15737,6 +15986,75 @@ SOCK *ConnectEx4(char *hostname, UINT port, UINT timeout, bool *cancel_flag, cha return sock; } +// Get the current accepting IPv4 address +void TryGetCurrentAcceptingIPv4Address(IP *ip) +{ + SOCK *s = ConnectEx(UDP_NAT_T_GET_PRIVATE_IP_TCP_SERVER, 80, 2000); + + if (s != NULL) + { + Disconnect(s); + ReleaseSock(s); + } + + if (GetCurrentGlobalIP(ip, false)) + { + return; + } + + GetCurrentGlobalIPGuess(ip, false); +} + +// Add a protocol details strings +void AddProtocolDetailsStr(char *dst, UINT dst_size, char *str) +{ + TOKEN_LIST *t1, *t2; + UINT i, j; + if (dst == NULL || str == NULL) + { + return; + } + + t1 = ParseTokenWithoutNullStr(dst, " "); + t2 = ParseTokenWithoutNullStr(str, " "); + + for (i = 0;i < t2->NumTokens;i++) + { + bool exists = false; + for (j = 0;j < t1->NumTokens;j++) + { + if (StrCmpi(t1->Token[j], t2->Token[i]) == 0) + { + exists = true; + break; + } + } + + if (exists == false) + { + StrCat(dst, dst_size, t2->Token[i]); + StrCat(dst, dst_size, " "); + } + } + + FreeToken(t1); + FreeToken(t2); +} +void AddProtocolDetailsKeyValueStr(char *dst, UINT dst_size, char *key, char *value) +{ + char tmp[128]; + StrCpy(tmp, sizeof(tmp), key); + StrCat(tmp, sizeof(tmp), "="); + StrCat(tmp, sizeof(tmp), value); + AddProtocolDetailsStr(dst, dst_size, tmp); +} +void AddProtocolDetailsKeyValueInt(char *dst, UINT dst_size, char *key, UINT value) +{ + char tmp[128]; + ToStr(tmp, value); + AddProtocolDetailsKeyValueStr(dst, dst_size, key, tmp); +} + // Maximize the I/O buffer size of the socket void SetSocketSendRecvBufferSize(SOCKET s, UINT size) { @@ -21029,6 +21347,8 @@ SOCK *AcceptReverse(SOCK *s) { StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_AZURE); + AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "VPNAzure"); + return ret; } @@ -21077,6 +21397,8 @@ SOCK *AcceptInProc(SOCK *s) { StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_INPROC); + AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "InProc"); + return ret; } @@ -21525,6 +21847,10 @@ void FlushTubeFlushList(TUBE_FLUSH_LIST *f) // The server receives a PACK from the client PACK *HttpServerRecv(SOCK *s) +{ + return HttpServerRecvEx(s, 0); +} +PACK *HttpServerRecvEx(SOCK *s, UINT max_data_size) { BUF *b; PACK *p; @@ -21533,6 +21859,7 @@ PACK *HttpServerRecv(SOCK *s) UCHAR *tmp; HTTP_VALUE *v; UINT num_noop = 0; + if (max_data_size == 0) max_data_size = HTTP_PACK_MAX_SIZE; // Validate arguments if (s == NULL) { @@ -21563,7 +21890,7 @@ START: } size = GetContentLength(h); - if (size == 0 || size > HTTP_PACK_MAX_SIZE) + if (size == 0 || (size > max_data_size)) { FreeHttpHeader(h); goto BAD_REQUEST; @@ -21924,6 +22251,35 @@ bool HttpSendNotImplemented(SOCK *s, char *method, char *target, char *version) return ret; } +// Sending a HTTP body contents +bool HttpSendBody(SOCK *s, void *data, UINT size, char *contents_type) +{ + HTTP_HEADER *h; + char date_str[MAX_SIZE]; + bool ret; + if (s == NULL || (size != 0 && data == NULL)) + { + return false; + } + if (contents_type == NULL) + { + contents_type = "application/octet-stream"; + } + // Creating a header + h = NewHttpHeader("HTTP/1.1", "200", "OK"); + + GetHttpDateStr(date_str, sizeof(date_str), SystemTime64()); + AddHttpValue(h, NewHttpValue("Date", date_str)); + AddHttpValue(h, NewHttpValue("Content-Type", contents_type)); + AddHttpValue(h, NewHttpValue("Cache-Control", "no-cache")); + + ret = PostHttp(s, h, data, size); + + FreeHttpHeader(h); + + return ret; +} + // Sending a 404 Not Found error bool HttpSendNotFound(SOCK *s, char *target) { @@ -22321,11 +22677,6 @@ HTTP_HEADER *RecvHttpHeader(SOCK *s) // The colon does not exist goto LABEL_ERROR; } - if ((pos + 1) >= StrLen(str)) - { - // There is no data - goto LABEL_ERROR; - } // Divide into the name and the data value_name = Malloc(pos + 1); diff --git a/src/Mayaqua/Network.h b/src/Mayaqua/Network.h index 14ac23d8..ad18ffea 100644 --- a/src/Mayaqua/Network.h +++ b/src/Mayaqua/Network.h @@ -306,6 +306,7 @@ struct SOCK UINT CurrentTtl; // Current TTL value RUDP_STACK *R_UDP_Stack; // R-UDP stack char UnderlayProtocol[64]; // Underlying protocol + char ProtocolDetails[256]; // Protocol Details QUEUE *ReverseAcceptQueue; // Accept queue for the reverse socket EVENT *ReverseAcceptEvent; // Accept event for the reverse socket bool IsReverseAcceptedSocket; // Whether it is a reverse socket @@ -660,6 +661,12 @@ struct IPBLOCK #define RUDP_TIMEOUT 12000 // Time-out of R-UDP communication #define RUDP_DIRECT_CONNECT_TIMEOUT 5000 // R-UDP direct connection time-out #define RUDP_MAX_SEGMENT_SIZE 512 // Maximum segment size +#define RUDP_BULK_KEY_SIZE_MAX 128 // Bulk key size Max + +#define RUDP_BULK_KEY_SIZE_V2 32 // V2: Bulk key size +#define RUDP_BULK_IV_SIZE_V2 12 // V2: Bulk IV size +#define RUDP_BULK_MAC_SIZE_V2 16 // V2: Bulk MAC size + // Maximum R-UDP packet size #define RUDP_MAX_PACKET_SIZE (RUDP_MAX_SEGMENT_SIZE + sizeof(UINT64) * RUDP_MAX_NUM_ACK + SHA1_SIZE * 2 + sizeof(UINT64) * 4 + sizeof(UINT) + 255) #define RUDP_MAX_NUM_ACK 64 // Maximum number of ACKs @@ -748,6 +755,7 @@ struct RUDP_SESSION UINT64 BulkNextSeqNo; // Next SEQ NO to the bulk send bool FlushBulkSendTube; // Flag to be Flush the bulk send Tube UINT64 BulkRecvSeqNoMax; // Highest sequence number received + UCHAR BulkNextIv_V2[RUDP_BULK_IV_SIZE_V2]; // Next IV to the bulk send (Ver 2) }; // NAT Traversal Server Information @@ -1045,11 +1053,13 @@ UINT GetContentLength(HTTP_HEADER *header); void GetHttpDateStr(char *str, UINT size, UINT64 t); bool HttpSendForbidden(SOCK *s, char *target, char *server_id); bool HttpSendNotFound(SOCK *s, char *target); +bool HttpSendBody(SOCK *s, void *data, UINT size, char *contents_type); bool HttpSendNotImplemented(SOCK *s, char *method, char *target, char *version); bool HttpSendInvalidHostname(SOCK *s, char *method); bool HttpServerSend(SOCK *s, PACK *p); bool HttpClientSend(SOCK *s, PACK *p); PACK *HttpServerRecv(SOCK *s); +PACK *HttpServerRecvEx(SOCK *s, UINT max_data_size); PACK *HttpClientRecv(SOCK *s); bool HttpSendServerError(SOCK *s, char *target); @@ -1307,7 +1317,7 @@ bool SendAll(SOCK *sock, void *data, UINT size, bool secure); void SendAdd(SOCK *sock, void *data, UINT size); bool SendNow(SOCK *sock, int secure); bool RecvAll(SOCK *sock, void *data, UINT size, bool secure); -bool RecvAllEx(SOCK *sock, void **data_new_ptr, UINT size, bool secure); +bool RecvAllWithDiscard(SOCK *sock, UINT size, bool secure); void InitSockSet(SOCKSET *set); void AddSockSet(SOCKSET *set, SOCK *sock); CANCEL *NewCancel(); @@ -1433,6 +1443,10 @@ void DebugPrintRoute(ROUTE_ENTRY *e); void DebugPrintRouteTable(ROUTE_TABLE *r); bool IsIPv6LocalNetworkAddress(IP *ip); UINT GetNumWaitThread(); +void AddProtocolDetailsStr(char *dst, UINT dst_size, char *str); +void AddProtocolDetailsKeyValueStr(char *dst, UINT dst_size, char *key, char *value); +void AddProtocolDetailsKeyValueInt(char *dst, UINT dst_size, char *key, UINT value); +void TryGetCurrentAcceptingIPv4Address(IP *ip); #ifdef ENABLE_SSL_LOGGING void SockEnableSslLogging(SOCK *s); @@ -1605,7 +1619,16 @@ void Win32WaitForTubes(TUBE **tubes, UINT num, UINT timeout); void UnixWaitForTubes(TUBE **tubes, UINT num, UINT timeout); #endif // OS_WIN32 +#define PREVERIFY_ERR_MESSAGE_SIZE 100 +// Info on client certificate collected during TLS handshake +struct SslClientCertInfo { + int PreverifyErr; + char PreverifyErrMessage[PREVERIFY_ERR_MESSAGE_SIZE]; + X *X; +}; + SSL_PIPE *NewSslPipe(bool server_mode, X *x, K *k, DH_CTX *dh); +SSL_PIPE *NewSslPipeEx(bool server_mode, X *x, K *k, DH_CTX *dh, bool verify_peer, struct SslClientCertInfo *clientcert); void FreeSslPipe(SSL_PIPE *s); bool SyncSslPipe(SSL_PIPE *s); diff --git a/src/Mayaqua/Pack.c b/src/Mayaqua/Pack.c index 881ada2e..42072bc0 100644 --- a/src/Mayaqua/Pack.c +++ b/src/Mayaqua/Pack.c @@ -741,13 +741,13 @@ ELEMENT *NewElement(char *name, UINT type, UINT num_value, VALUE **values) } // Memory allocation - e = Malloc(sizeof(ELEMENT)); + e = ZeroMalloc(sizeof(ELEMENT)); StrCpy(e->name, sizeof(e->name), name); e->num_value = num_value; e->type = type; // Copy of the pointer list to the element - e->values = (VALUE **)Malloc(sizeof(VALUE *) * num_value); + e->values = (VALUE **)ZeroMalloc(sizeof(VALUE *) * num_value); for (i = 0;i < e->num_value;i++) { e->values[i] = values[i]; @@ -864,6 +864,10 @@ bool AddElement(PACK *p, ELEMENT *e) // Adding Add(p->elements, e); + + // Set JsonHint_GroupName + StrCpy(e->JsonHint_GroupName, sizeof(e->JsonHint_GroupName), p->CurrentJsonHint_GroupName); + return true; } @@ -885,6 +889,11 @@ void FreePack(PACK *p) } Free(elements); + if (p->json_subitem_names != NULL) + { + FreeStrList(p->json_subitem_names); + } + ReleaseList(p->elements); Free(p); } @@ -895,7 +904,7 @@ PACK *NewPack() PACK *p; // Memory allocation - p = MallocEx(sizeof(PACK), true); + p = ZeroMallocEx(sizeof(PACK), true); // Creating a List p->elements = NewListFast(ComparePackName); @@ -921,6 +930,12 @@ K *PackGetK(PACK *p, char *name) } k = BufToK(b, true, false, NULL); + + if (k == NULL) + { + k = BufToK(b, true, true, NULL); + } + FreeBuf(b); return k; @@ -944,49 +959,61 @@ X *PackGetX(PACK *p, char *name) } x = BufToX(b, false); + + if (x == NULL) + { + x = BufToX(b, true); + } + FreeBuf(b); return x; } // Add the K to the PACK -void PackAddK(PACK *p, char *name, K *k) +ELEMENT *PackAddK(PACK *p, char *name, K *k) { BUF *b; + ELEMENT *e = NULL; // Validate arguments if (p == NULL || name == NULL || k == NULL) { - return; + return NULL; } b = KToBuf(k, false, NULL); if (b == NULL) { - return; + return NULL; } - PackAddBuf(p, name, b); + e = PackAddBuf(p, name, b); FreeBuf(b); + + return e; } // Add an X into the PACK -void PackAddX(PACK *p, char *name, X *x) +ELEMENT *PackAddX(PACK *p, char *name, X *x) { BUF *b; + ELEMENT *e = NULL; // Validate arguments if (p == NULL || name == NULL || x == NULL) { - return; + return NULL; } b = XToBuf(x, false); if (b == NULL) { - return; + return NULL; } - PackAddBuf(p, name, b); + e = PackAddBuf(p, name, b); FreeBuf(b); + + return e; } // Get a buffer from the PACK @@ -1149,30 +1176,65 @@ bool PackGetBoolEx(PACK *p, char *name, UINT index) return PackGetIntEx(p, name, index) == 0 ? false : true; } -// Add a bool type into the PACK -void PackAddBool(PACK *p, char *name, bool b) +// Set CurrentJsonHint_GroupName to PACK +void PackSetCurrentJsonGroupName(PACK *p, char *json_group_name) { - PackAddInt(p, name, b ? 1 : 0); -} -void PackAddBoolEx(PACK *p, char *name, bool b, UINT index, UINT total) -{ - PackAddIntEx(p, name, b ? 1 : 0, index, total); -} - -// Add the IPV6_ADDR to the PACK -void PackAddIp6AddrEx(PACK *p, char *name, IPV6_ADDR *addr, UINT index, UINT total) -{ - // Validate arguments - if (p == NULL || name == NULL || addr == NULL) + if (p == NULL) { return; } - PackAddDataEx(p, name, addr, sizeof(IPV6_ADDR), index, total); + if (json_group_name == NULL) + { + ClearStr(p->CurrentJsonHint_GroupName, sizeof(p->CurrentJsonHint_GroupName)); + } + else + { + StrCpy(p->CurrentJsonHint_GroupName, sizeof(p->CurrentJsonHint_GroupName), json_group_name); + + if (p->json_subitem_names == NULL) + { + p->json_subitem_names = NewStrList(); + } + + AddStrToStrListDistinct(p->json_subitem_names, json_group_name); + } } -void PackAddIp6Addr(PACK *p, char *name, IPV6_ADDR *addr) + +// Add a bool type into the PACK +ELEMENT *PackAddBool(PACK *p, char *name, bool b) { - PackAddIp6AddrEx(p, name, addr, 0, 1); + ELEMENT *e = PackAddInt(p, name, b ? 1 : 0); + if (e != NULL) + { + e->JsonHint_IsBool = true; + } + return e; +} +ELEMENT *PackAddBoolEx(PACK *p, char *name, bool b, UINT index, UINT total) +{ + ELEMENT *e = PackAddIntEx(p, name, b ? 1 : 0, index, total); + if (e != NULL) + { + e->JsonHint_IsBool = true; + } + return e; +} + +// Add the IPV6_ADDR to the PACK +ELEMENT *PackAddIp6AddrEx(PACK *p, char *name, IPV6_ADDR *addr, UINT index, UINT total) +{ + // Validate arguments + if (p == NULL || name == NULL || addr == NULL) + { + return NULL; + } + + return PackAddDataEx(p, name, addr, sizeof(IPV6_ADDR), index, total); +} +ELEMENT *PackAddIp6Addr(PACK *p, char *name, IPV6_ADDR *addr) +{ + return PackAddIp6AddrEx(p, name, addr, 0, 1); } // Get an IPV6_ADDR from the PACK @@ -1194,6 +1256,10 @@ bool PackGetIp6Addr(PACK *p, char *name, IPV6_ADDR *addr) // Add the IP to the PACK void PackAddIp32Ex(PACK *p, char *name, UINT ip32, UINT index, UINT total) +{ + PackAddIp32Ex2(p, name, ip32, index, total, false); +} +void PackAddIp32Ex2(PACK *p, char *name, UINT ip32, UINT index, UINT total, bool is_single) { IP ip; // Validate arguments @@ -1204,32 +1270,45 @@ void PackAddIp32Ex(PACK *p, char *name, UINT ip32, UINT index, UINT total) UINTToIP(&ip, ip32); - PackAddIpEx(p, name, &ip, index, total); + PackAddIpEx2(p, name, &ip, index, total, is_single); } void PackAddIp32(PACK *p, char *name, UINT ip32) { - PackAddIp32Ex(p, name, ip32, 0, 1); + PackAddIp32Ex2(p, name, ip32, 0, 1, true); } void PackAddIpEx(PACK *p, char *name, IP *ip, UINT index, UINT total) +{ + PackAddIpEx2(p, name, ip, index, total, false); +} +void PackAddIpEx2(PACK *p, char *name, IP *ip, UINT index, UINT total, bool is_single) { UINT i; bool b = false; char tmp[MAX_PATH]; + ELEMENT *e; // Validate arguments if (p == NULL || name == NULL || ip == NULL) { return; } + if (total >= 2) + { + is_single = false; + } b = IsIP6(ip); Format(tmp, sizeof(tmp), "%s@ipv6_bool", name); - PackAddBoolEx(p, tmp, b, index, total); + e = PackAddBoolEx(p, tmp, b, index, total); + if (e != NULL && is_single) e->JsonHint_IsArray = false; + if (e != NULL) e->JsonHint_IsIP = true; Format(tmp, sizeof(tmp), "%s@ipv6_array", name); if (b) { - PackAddDataEx(p, tmp, ip->ipv6_addr, sizeof(ip->ipv6_addr), index, total); + e = PackAddDataEx(p, tmp, ip->ipv6_addr, sizeof(ip->ipv6_addr), index, total); + if (e != NULL && is_single) e->JsonHint_IsArray = false; + if (e != NULL) e->JsonHint_IsIP = true; } else { @@ -1237,17 +1316,23 @@ void PackAddIpEx(PACK *p, char *name, IP *ip, UINT index, UINT total) Zero(dummy, sizeof(dummy)); - PackAddDataEx(p, tmp, dummy, sizeof(dummy), index, total); + e = PackAddDataEx(p, tmp, dummy, sizeof(dummy), index, total); + if (e != NULL && is_single) e->JsonHint_IsArray = false; + if (e != NULL) e->JsonHint_IsIP = true; } Format(tmp, sizeof(tmp), "%s@ipv6_scope_id", name); if (b) { - PackAddIntEx(p, tmp, ip->ipv6_scope_id, index, total); + e = PackAddIntEx(p, tmp, ip->ipv6_scope_id, index, total); + if (e != NULL && is_single) e->JsonHint_IsArray = false; + if (e != NULL) e->JsonHint_IsIP = true; } else { - PackAddIntEx(p, tmp, 0, index, total); + e = PackAddIntEx(p, tmp, 0, index, total); + if (e != NULL && is_single) e->JsonHint_IsArray = false; + if (e != NULL) e->JsonHint_IsIP = true; } i = IPToUINT(ip); @@ -1257,11 +1342,13 @@ void PackAddIpEx(PACK *p, char *name, IP *ip, UINT index, UINT total) i = Swap32(i); } - PackAddIntEx(p, name, i, index, total); + e = PackAddIntEx(p, name, i, index, total); + if (e != NULL && is_single) e->JsonHint_IsArray = false; + if (e != NULL) e->JsonHint_IsIP = true; } void PackAddIp(PACK *p, char *name, IP *ip) { - PackAddIpEx(p, name, ip, 0, 1); + PackAddIpEx2(p, name, ip, 0, 1, true); } // Get an IP from the PACK @@ -1441,34 +1528,35 @@ bool PackGetStrEx(PACK *p, char *name, char *str, UINT size, UINT index) } // Add the buffer to the PACK (array) -void PackAddBufEx(PACK *p, char *name, BUF *b, UINT index, UINT total) +ELEMENT *PackAddBufEx(PACK *p, char *name, BUF *b, UINT index, UINT total) { // Validate arguments if (p == NULL || name == NULL || b == NULL || total == 0) { - return; + return NULL; } - PackAddDataEx(p, name, b->Buf, b->Size, index, total); + return PackAddDataEx(p, name, b->Buf, b->Size, index, total); } // Add the data to the PACK (array) -void PackAddDataEx(PACK *p, char *name, void *data, UINT size, UINT index, UINT total) +ELEMENT *PackAddDataEx(PACK *p, char *name, void *data, UINT size, UINT index, UINT total) { VALUE *v; ELEMENT *e; // Validate arguments if (p == NULL || data == NULL || name == NULL || total == 0) { - return; + return NULL; } v = NewDataValue(data, size); e = GetElement(p, name, VALUE_DATA); if (e != NULL) { - if (e->num_value <= total) + if (e->num_value >= total) { + FreeValue(e->values[index], VALUE_DATA); e->values[index] = v; } else @@ -1484,53 +1572,68 @@ void PackAddDataEx(PACK *p, char *name, void *data, UINT size, UINT index, UINT e->type = VALUE_DATA; e->values = ZeroMallocEx(sizeof(VALUE *) * total, true); e->values[index] = v; - AddElement(p, e); + if (AddElement(p, e) == false) + { + return NULL; + } } + + e->JsonHint_IsArray = true; + + return e; } // Add the buffer to the PACK -void PackAddBuf(PACK *p, char *name, BUF *b) +ELEMENT *PackAddBuf(PACK *p, char *name, BUF *b) { // Validate arguments if (p == NULL || name == NULL || b == NULL) { - return; + return NULL; } - PackAddData(p, name, b->Buf, b->Size); + return PackAddData(p, name, b->Buf, b->Size); } // Add the data to the PACK -void PackAddData(PACK *p, char *name, void *data, UINT size) +ELEMENT *PackAddData(PACK *p, char *name, void *data, UINT size) { VALUE *v; + ELEMENT *e; // Validate arguments if (p == NULL || data == NULL || name == NULL) { - return; + return NULL; } v = NewDataValue(data, size); - AddElement(p, NewElement(name, VALUE_DATA, 1, &v)); + e = NewElement(name, VALUE_DATA, 1, &v); + if (AddElement(p, e) == false) + { + return NULL; + } + + return e; } // Add a 64 bit integer (array) to the PACK -void PackAddInt64Ex(PACK *p, char *name, UINT64 i, UINT index, UINT total) +ELEMENT *PackAddInt64Ex(PACK *p, char *name, UINT64 i, UINT index, UINT total) { VALUE *v; ELEMENT *e; // Validate arguments if (p == NULL || name == NULL || total == 0) { - return; + return NULL; } v = NewInt64Value(i); e = GetElement(p, name, VALUE_INT64); if (e != NULL) { - if (e->num_value <= total) + if (e->num_value >= total) { + FreeValue(e->values[index], VALUE_INT64); e->values[index] = v; } else @@ -1546,27 +1649,36 @@ void PackAddInt64Ex(PACK *p, char *name, UINT64 i, UINT index, UINT total) e->type = VALUE_INT64; e->values = ZeroMallocEx(sizeof(VALUE *) * total, true); e->values[index] = v; - AddElement(p, e); + + if (AddElement(p, e) == false) + { + return NULL; + } } + + e->JsonHint_IsArray = true; + + return e; } // Add an integer to the PACK (array) -void PackAddIntEx(PACK *p, char *name, UINT i, UINT index, UINT total) +ELEMENT *PackAddIntEx(PACK *p, char *name, UINT i, UINT index, UINT total) { VALUE *v; ELEMENT *e; // Validate arguments if (p == NULL || name == NULL || total == 0) { - return; + return NULL; } v = NewIntValue(i); e = GetElement(p, name, VALUE_INT); if (e != NULL) { - if (e->num_value <= total) + if (e->num_value >= total) { + FreeValue(e->values[index], VALUE_INT); e->values[index] = v; } else @@ -1582,61 +1694,103 @@ void PackAddIntEx(PACK *p, char *name, UINT i, UINT index, UINT total) e->type = VALUE_INT; e->values = ZeroMallocEx(sizeof(VALUE *) * total, true); e->values[index] = v; - AddElement(p, e); + + if (AddElement(p, e) == false) + { + return NULL; + } } + + e->JsonHint_IsArray = true; + + return e; } +// Add 64 bit integer time value to the PACK +ELEMENT *PackAddTime64(PACK *p, char *name, UINT64 i) +{ + ELEMENT *e = PackAddInt64(p, name, i); + if (e != NULL) + { + e->JsonHint_IsDateTime = true; + } + return e; +} +ELEMENT *PackAddTime64Ex(PACK *p, char *name, UINT64 i, UINT index, UINT total) +{ + ELEMENT *e = PackAddInt64Ex(p, name, i, index, total); + if (e != NULL) + { + e->JsonHint_IsDateTime = true; + } + return e; +} + + // Add a 64 bit integer to the PACK -void PackAddInt64(PACK *p, char *name, UINT64 i) +ELEMENT *PackAddInt64(PACK *p, char *name, UINT64 i) { VALUE *v; + ELEMENT *e; // Validate arguments if (p == NULL || name == NULL) { - return; + return NULL; } v = NewInt64Value(i); - AddElement(p, NewElement(name, VALUE_INT64, 1, &v)); + e = NewElement(name, VALUE_INT64, 1, &v); + if (AddElement(p, e) == false) + { + return NULL; + } + return e; } // Add the number of items to the PACK -void PackAddNum(PACK *p, char *name, UINT num) +ELEMENT *PackAddNum(PACK *p, char *name, UINT num) { - PackAddInt(p, name, num); + return PackAddInt(p, name, num); } // Add an integer to the PACK -void PackAddInt(PACK *p, char *name, UINT i) +ELEMENT *PackAddInt(PACK *p, char *name, UINT i) { VALUE *v; + ELEMENT *e = NULL; // Validate arguments if (p == NULL || name == NULL) { - return; + return NULL; } v = NewIntValue(i); - AddElement(p, NewElement(name, VALUE_INT, 1, &v)); + e = NewElement(name, VALUE_INT, 1, &v); + if (AddElement(p, e) == false) + { + return NULL; + } + return e; } // Add a Unicode string (array) to the PACK -void PackAddUniStrEx(PACK *p, char *name, wchar_t *unistr, UINT index, UINT total) +ELEMENT *PackAddUniStrEx(PACK *p, char *name, wchar_t *unistr, UINT index, UINT total) { VALUE *v; ELEMENT *e; // Validate arguments if (p == NULL || name == NULL || unistr == NULL || total == 0) { - return; + return NULL; } v = NewUniStrValue(unistr); e = GetElement(p, name, VALUE_UNISTR); if (e != NULL) { - if (e->num_value <= total) + if (e->num_value >= total) { + FreeValue(e->values[index], VALUE_UNISTR); e->values[index] = v; } else @@ -1652,41 +1806,55 @@ void PackAddUniStrEx(PACK *p, char *name, wchar_t *unistr, UINT index, UINT tota e->type = VALUE_UNISTR; e->values = ZeroMallocEx(sizeof(VALUE *) * total, true); e->values[index] = v; - AddElement(p, e); + if (AddElement(p, e) == false) + { + return NULL; + } } + + e->JsonHint_IsArray = true; + + return e; } // Add a Unicode string to the PACK -void PackAddUniStr(PACK *p, char *name, wchar_t *unistr) +ELEMENT *PackAddUniStr(PACK *p, char *name, wchar_t *unistr) { VALUE *v; + ELEMENT *e = NULL; // Validate arguments if (p == NULL || name == NULL || unistr == NULL) { - return; + return NULL; } v = NewUniStrValue(unistr); - AddElement(p, NewElement(name, VALUE_UNISTR, 1, &v)); + e = NewElement(name, VALUE_UNISTR, 1, &v); + if (AddElement(p, e) == false) + { + return NULL; + } + return e; } // Add a string to the PACK (array) -void PackAddStrEx(PACK *p, char *name, char *str, UINT index, UINT total) +ELEMENT *PackAddStrEx(PACK *p, char *name, char *str, UINT index, UINT total) { VALUE *v; ELEMENT *e; // Validate arguments if (p == NULL || name == NULL || str == NULL || total == 0) { - return; + return NULL; } v = NewStrValue(str); e = GetElement(p, name, VALUE_STR); if (e != NULL) { - if (e->num_value <= total) + if (e->num_value >= total) { + FreeValue(e->values[index], VALUE_STR); e->values[index] = v; } else @@ -1702,22 +1870,704 @@ void PackAddStrEx(PACK *p, char *name, char *str, UINT index, UINT total) e->type = VALUE_STR; e->values = ZeroMallocEx(sizeof(VALUE *) * total, true); e->values[index] = v; - AddElement(p, e); + if (AddElement(p, e) == false) + { + return NULL; + } } + + e->JsonHint_IsArray = true; + + return e; } // Add a string to the PACK -void PackAddStr(PACK *p, char *name, char *str) +ELEMENT *PackAddStr(PACK *p, char *name, char *str) { VALUE *v; + ELEMENT *e = NULL; // Validate arguments if (p == NULL || name == NULL || str == NULL) + { + return NULL; + } + + v = NewStrValue(str); + e = NewElement(name, VALUE_STR, 1, &v); + if (AddElement(p, e) == false) + { + return NULL; + } + return e; +} + +// Add an element of PACK array to JSON Array +void PackArrayElementToJsonArray(JSON_ARRAY *ja, PACK *p, ELEMENT *e, UINT index) +{ + if (ja == NULL || p == NULL || e == NULL || index >= e->num_value) { return; } - v = NewStrValue(str); - AddElement(p, NewElement(name, VALUE_STR, 1, &v)); + switch (e->type) + { + case VALUE_INT: + if (e->JsonHint_IsIP) + { + if (InStr(e->name, "@") == false) + { + IP ip; + if (PackGetIpEx(p, e->name, &ip, index)) + { + char ip_str[64]; + IPToStr(ip_str, sizeof(ip_str), &ip); + JsonArrayAddStr(ja, ip_str); + } + } + } + else if (e->JsonHint_IsBool) + { + JsonArrayAddBool(ja, PackGetBoolEx(p, e->name, index)); + } + else + { + JsonArrayAddNumber(ja, PackGetIntEx(p, e->name, index)); + } + break; + case VALUE_INT64: + if (e->JsonHint_IsIP == false) + { + if (e->JsonHint_IsDateTime == false) + { + JsonArrayAddNumber(ja, PackGetInt64Ex(p, e->name, index)); + } + else + { + char dtstr[64]; + + SystemTime64ToJsonStr(dtstr, sizeof(dtstr), PackGetInt64Ex(p, e->name, index)); + JsonArrayAddStr(ja, dtstr); + } + } + break; + case VALUE_DATA: + if (e->JsonHint_IsIP == false) + { + BUF *buf = PackGetBufEx(p, e->name, index); + if (buf != NULL) + { + JsonArrayAddData(ja, buf->Buf, buf->Size); + FreeBuf(buf); + } + else + { + UCHAR zero = 0; + JsonArrayAddData(ja, &zero, 0); + } + } + break; + case VALUE_STR: + if (e->JsonHint_IsIP == false) + { + if (e->values[index] != NULL) + { + JsonArrayAddStr(ja, e->values[index]->Str); + } + else + { + JsonArrayAddStr(ja, ""); + } + } + break; + case VALUE_UNISTR: + if (e->JsonHint_IsIP == false) + { + if (e->values[index] != NULL) + { + JsonArrayAddUniStr(ja, e->values[index]->UniStr); + } + else + { + JsonArrayAddUniStr(ja, L""); + } + } + break; + } +} + +// Add an element of PACK to JSON Object +void PackElementToJsonObject(JSON_OBJECT *o, PACK *p, ELEMENT *e, UINT index) +{ + char *suffix; + char name[MAX_PATH]; + if (o == NULL || p == NULL || e == NULL) + { + return; + } + + suffix = DetermineJsonSuffixForPackElement(e); + + if (suffix == NULL) + { + return; + } + + StrCpy(name, sizeof(name), e->name); + StrCat(name, sizeof(name), suffix); + + switch (e->type) + { + case VALUE_INT: + if (e->JsonHint_IsIP) + { + if (InStr(e->name, "@") == false) + { + IP ip; + if (PackGetIpEx(p, e->name, &ip, index)) + { + char ip_str[64]; + IPToStr(ip_str, sizeof(ip_str), &ip); + JsonSetStr(o, name, ip_str); + } + } + } + else if (e->JsonHint_IsBool) + { + JsonSetBool(o, name, PackGetBoolEx(p, e->name, index)); + } + else + { + JsonSetNumber(o, name, PackGetIntEx(p, e->name, index)); + } + break; + case VALUE_INT64: + if (e->JsonHint_IsIP == false) + { + if (e->JsonHint_IsDateTime == false) + { + JsonSetNumber(o, name, PackGetInt64Ex(p, e->name, index)); + } + else + { + char dtstr[64]; + + SystemTime64ToJsonStr(dtstr, sizeof(dtstr), PackGetInt64Ex(p, e->name, index)); + JsonSetStr(o, name, dtstr); + } + } + break; + case VALUE_DATA: + if (e->JsonHint_IsIP == false) + { + BUF *buf = PackGetBufEx(p, e->name, index); + if (buf != NULL) + { + JsonSetData(o, name, buf->Buf, buf->Size); + FreeBuf(buf); + } + else + { + UCHAR zero = 0; + JsonSetData(o, name, &zero, 0); + } + } + break; + case VALUE_STR: + if (e->JsonHint_IsIP == false) + { + if (e->values[index] != NULL) + { + JsonSetStr(o, name, e->values[index]->Str); + } + else + { + JsonSetStr(o, name, ""); + } + } + break; + case VALUE_UNISTR: + if (e->JsonHint_IsIP == false) + { + if (e->values[index] != NULL) + { + JsonSetUniStr(o, name, e->values[index]->UniStr); + } + else + { + JsonSetUniStr(o, name, L""); + } + } + break; + } +} + +// Determine JSON element suffix for PACK element +char *DetermineJsonSuffixForPackElement(ELEMENT *e) +{ + switch (e->type) + { + case VALUE_INT: + if (e->JsonHint_IsIP) + { + if (InStr(e->name, "@") == false) + { + return "_ip"; + } + } + else if (e->JsonHint_IsBool) + { + return "_bool"; + } + else + { + return "_u32"; + } + break; + case VALUE_INT64: + if (e->JsonHint_IsIP == false) + { + if (e->JsonHint_IsDateTime == false) + { + return "_u64"; + } + else + { + return "_dt"; + } + } + break; + case VALUE_DATA: + if (e->JsonHint_IsIP == false) + { + return "_bin"; + } + break; + case VALUE_STR: + if (e->JsonHint_IsIP == false) + { + return "_str"; + } + break; + case VALUE_UNISTR: + if (e->JsonHint_IsIP == false) + { + return "_utf"; + } + break; + } + + return NULL; +} + +// Convert JSON to PACK +PACK *JsonToPack(JSON_VALUE *v) +{ + PACK *p = NULL; + JSON_OBJECT *jo; + if (v == NULL) + { + return NULL; + } + + p = NewPack(); + + jo = JsonValueGetObject(v); + + if (jo != NULL) + { + UINT i; + for (i = 0;i < jo->count;i++) + { + char *name = jo->names[i]; + JSON_VALUE *value = jo->values[i]; + + if (value->type == JSON_TYPE_ARRAY) + { + UINT j; + JSON_ARRAY *ja = value->value.array; + + for (j = 0;j < ja->count;j++) + { + if (ja->items[j]->type != JSON_TYPE_OBJECT) + { + JsonTryParseValueAddToPack(p, ja->items[j], name, j, ja->count, false); + } + else + { + JSON_VALUE *v = ja->items[j]; + JSON_OBJECT *o = v->value.object; + UINT k; + + for (k = 0;k < o->count;k++) + { + char *name2 = o->names[k]; + JSON_VALUE *value2 = o->values[k]; + + PackSetCurrentJsonGroupName(p, name); + JsonTryParseValueAddToPack(p, value2, name2, j, ja->count, false); + PackSetCurrentJsonGroupName(p, NULL); + } + } + } + } + else + { + JsonTryParseValueAddToPack(p, value, name, 0, 1, true); + } + } + } + + return p; +} + +ELEMENT *ElementNullSafe(ELEMENT *p) +{ + static ELEMENT dummy; + if (p == NULL) + { + Zero(&dummy, sizeof(dummy)); + return &dummy; + } + return p; +} + +bool JsonTryParseValueAddToPack(PACK *p, JSON_VALUE *v, char *v_name, UINT index, UINT total, bool is_single) +{ + char name[MAX_PATH]; + bool ok = true; + if (p == NULL || v == NULL) + { + return false; + } + + if (TrimEndWith(name, sizeof(name), v_name, "_bool")) + { + if (v->type == JSON_TYPE_BOOL) + { + ElementNullSafe(PackAddBoolEx(p, name, MAKEBOOL(v->value.boolean), index, total))->JsonHint_IsArray = !is_single; + ok = true; + } + else if (v->type == JSON_TYPE_NUMBER) + { + ElementNullSafe(PackAddBoolEx(p, name, MAKEBOOL(v->value.number), index, total))->JsonHint_IsArray = !is_single; + ok = true; + } + else if (v->type == JSON_TYPE_STRING) + { + ElementNullSafe(PackAddBoolEx(p, name, ToBool(v->value.string), index, total))->JsonHint_IsArray = !is_single; + ok = true; + } + } + else if (TrimEndWith(name, sizeof(name), v_name, "_u32")) + { + if (v->type == JSON_TYPE_BOOL) + { + ElementNullSafe(PackAddIntEx(p, name, MAKEBOOL(v->value.boolean), index, total))->JsonHint_IsArray = !is_single; + ok = true; + } + else if (v->type == JSON_TYPE_NUMBER) + { + ElementNullSafe(PackAddIntEx(p, name, (UINT)v->value.number, index, total))->JsonHint_IsArray = !is_single; + ok = true; + } + else if (v->type == JSON_TYPE_STRING) + { + ElementNullSafe(PackAddIntEx(p, name, ToInt(v->value.string), index, total))->JsonHint_IsArray = !is_single; + ok = true; + } + } + else if (TrimEndWith(name, sizeof(name), v_name, "_u64")) + { + if (v->type == JSON_TYPE_BOOL) + { + ElementNullSafe(PackAddInt64Ex(p, name, MAKEBOOL(v->value.boolean), index, total))->JsonHint_IsArray = !is_single; + ok = true; + } + else if (v->type == JSON_TYPE_NUMBER) + { + ElementNullSafe(PackAddInt64Ex(p, name, v->value.number, index, total))->JsonHint_IsArray = !is_single; + ok = true; + } + else if (v->type == JSON_TYPE_STRING) + { + ElementNullSafe(PackAddInt64Ex(p, name, ToInt64(v->value.string), index, total))->JsonHint_IsArray = !is_single; + ok = true; + } + } + else if (TrimEndWith(name, sizeof(name), v_name, "_str")) + { + if (v->type == JSON_TYPE_BOOL) + { + ElementNullSafe(PackAddStrEx(p, name, MAKEBOOL(v->value.boolean) ? "true" : "false", index, total))->JsonHint_IsArray = !is_single; + ok = true; + } + else if (v->type == JSON_TYPE_NUMBER) + { + char tmp[64]; + ToStr64(tmp, v->value.number); + ElementNullSafe(PackAddStrEx(p, name, tmp, index, total))->JsonHint_IsArray = !is_single; + ok = true; + } + else if (v->type == JSON_TYPE_STRING) + { + ElementNullSafe(PackAddStrEx(p, name, v->value.string, index, total))->JsonHint_IsArray = !is_single; + ok = true; + } + } + else if (TrimEndWith(name, sizeof(name), v_name, "_utf")) + { + if (v->type == JSON_TYPE_BOOL) + { + ElementNullSafe(PackAddUniStrEx(p, name, MAKEBOOL(v->value.boolean) ? L"true" : L"false", index, total))->JsonHint_IsArray = !is_single; + ok = true; + } + else if (v->type == JSON_TYPE_NUMBER) + { + char tmp[64]; + wchar_t tmp2[64]; + ToStr64(tmp, v->value.number); + StrToUni(tmp2, sizeof(tmp2), tmp); + ElementNullSafe(PackAddUniStrEx(p, name, tmp2, index, total))->JsonHint_IsArray = !is_single; + ok = true; + } + else if (v->type == JSON_TYPE_STRING) + { + wchar_t *uni = CopyUtfToUni(v->value.string); + ElementNullSafe(PackAddUniStrEx(p, name, uni, index, total))->JsonHint_IsArray = !is_single; + Free(uni); + ok = true; + } + } + else if (TrimEndWith(name, sizeof(name), v_name, "_bin")) + { + if (v->type == JSON_TYPE_STRING) + { + UINT len = StrLen(v->value.string); + UCHAR *data = ZeroMalloc(len * 4 + 64); + UINT size = B64_Decode(data, v->value.string, len); + ElementNullSafe(PackAddDataEx(p, name, data, size, index, total))->JsonHint_IsArray = !is_single; + Free(data); + ok = true; + } + } + else if (TrimEndWith(name, sizeof(name), v_name, "_dt")) + { + if (v->type == JSON_TYPE_NUMBER) + { + ElementNullSafe(PackAddInt64Ex(p, name, v->value.number, index, total))->JsonHint_IsArray = !is_single; + ok = true; + } + else if (v->type == JSON_TYPE_STRING) + { + UINT64 time = DateTimeStrRFC3339ToSystemTime64(v->value.string); + ELEMENT *e = PackAddInt64Ex(p, name, time, index, total); + if (e != NULL) + { + e->JsonHint_IsArray = !is_single; + e->JsonHint_IsDateTime = true; + } + ok = true; + } + } + else if (TrimEndWith(name, sizeof(name), v_name, "_ip")) + { + if (v->type == JSON_TYPE_STRING) + { + IP ip; + if (StrToIP(&ip, v->value.string)) + { + PackAddIpEx2(p, name, &ip, index, total, is_single); + ok = true; + } + } + } + + return ok; +} + +// Convert JSON string to PACK +PACK *JsonStrToPack(char *str) +{ + JSON_VALUE *v = StrToJson(str); + PACK *ret; + + if (v == NULL) + { + return NULL; + } + + ret = JsonToPack(v); + + JsonFree(v); + + return ret; +} + +// Convert PACK to JSON string +char *PackToJsonStr(PACK *p) +{ + char *ret; + JSON_VALUE *json = PackToJson(p); + + ret = JsonToStr(json); + + JsonFree(json); + + return ret; +} + +// Convert PACK to JSON +JSON_VALUE *PackToJson(PACK *p) +{ + JSON_VALUE *v; + JSON_OBJECT *o; + UINT i, j, k; + LIST *json_group_id_list; + if (p == NULL) + { + return JsonNewObject(); + } + + // suppress quick sort in the enumeration process + GetElement(p, "_dummy_", VALUE_INT); + + json_group_id_list = NewStrList(); + + for (i = 0;i < LIST_NUM(p->elements);i++) + { + ELEMENT *e = LIST_DATA(p->elements, i); + + if (e->num_value >= 2 || e->JsonHint_IsArray) + { + if (IsEmptyStr(e->JsonHint_GroupName) == false) + { + AddStrToStrListDistinct(json_group_id_list, e->JsonHint_GroupName); + } + } + } + + for (i = 0;i < LIST_NUM(p->json_subitem_names);i++) + { + char *group_name = LIST_DATA(p->json_subitem_names, i); + + if (IsEmptyStr(group_name) == false) + { + AddStrToStrListDistinct(json_group_id_list, group_name); + } + } + + v = JsonNewObject(); + o = JsonValueGetObject(v); + + for (k = 0;k < LIST_NUM(json_group_id_list);k++) + { + char *group_name = LIST_DATA(json_group_id_list, k); + UINT array_count = INFINITE; + bool ok = true; + + for (i = 0;i < LIST_NUM(p->elements);i++) + { + ELEMENT *e = LIST_DATA(p->elements, i); + + if (e->num_value >= 2 || e->JsonHint_IsArray) + { + if (StrCmpi(e->JsonHint_GroupName, group_name) == 0) + { + if (array_count == INFINITE) + { + array_count = e->num_value; + } + else + { + if (array_count != e->num_value) + { + ok = false; + } + } + } + } + } + + if (array_count == INFINITE) + { + array_count = 0; + } + + if (ok) + { + JSON_VALUE **json_objects = ZeroMalloc(sizeof(void *) * array_count); + JSON_VALUE *jav = JsonNewArray(); + JSON_ARRAY *ja = JsonArray(jav); + + JsonSet(o, group_name, jav); + + for (j = 0;j < array_count;j++) + { + json_objects[j] = JsonNewObject(); + + JsonArrayAdd(ja, json_objects[j]); + } + + for (i = 0;i < LIST_NUM(p->elements);i++) + { + ELEMENT *e = LIST_DATA(p->elements, i); + + if (e->num_value >= 2 || e->JsonHint_IsArray) + { + if (StrCmpi(e->JsonHint_GroupName, group_name) == 0) + { + for (j = 0;j < e->num_value;j++) + { + PackElementToJsonObject(JsonValueGetObject(json_objects[j]), + p, e, j); + } + } + } + } + + Free(json_objects); + } + } + + for (i = 0;i < LIST_NUM(p->elements);i++) + { + ELEMENT *e = LIST_DATA(p->elements, i); + + if (e->num_value >= 2 || e->JsonHint_IsArray) + { + if (IsEmptyStr(e->JsonHint_GroupName)) + { + char *suffix = DetermineJsonSuffixForPackElement(e); + + if (suffix != NULL) + { + JSON_VALUE *jav = JsonNewArray(); + JSON_ARRAY *ja = JsonArray(jav); + char name[MAX_PATH]; + + for (j = 0;j < e->num_value;j++) + { + PackArrayElementToJsonArray(ja, p, e, j); + } + + StrCpy(name, sizeof(name), e->name); + StrCat(name, sizeof(name), suffix); + + JsonSet(o, name, jav); + } + } + } + else if (e->num_value == 1) + { + PackElementToJsonObject(o, p, e, 0); + } + } + + ReleaseStrList(json_group_id_list); + + return v; } + + diff --git a/src/Mayaqua/Pack.h b/src/Mayaqua/Pack.h index 3880d5b7..53a13840 100644 --- a/src/Mayaqua/Pack.h +++ b/src/Mayaqua/Pack.h @@ -152,12 +152,40 @@ struct ELEMENT UINT num_value; // Number of values (>=1) UINT type; // Type VALUE **values; // List of pointers to the value + bool JsonHint_IsArray; + bool JsonHint_IsBool; + bool JsonHint_IsDateTime; + bool JsonHint_IsIP; + char JsonHint_GroupName[MAX_ELEMENT_NAME_LEN + 1]; }; + + // PACK object struct PACK { LIST *elements; // Element list + LIST *json_subitem_names; // JSON sub-item names + char CurrentJsonHint_GroupName[MAX_ELEMENT_NAME_LEN + 1]; +}; + + +#define MAX_JSONPACK_HINT_ITEMS 64 +#define JSONPACK_HINT_TYPE_ARRAY 1 + +// JSON/PACK converter hint element +struct JSONPACKHINT_ITEM +{ + UINT Type; + char ArrayNumNameInPack[MAX_ELEMENT_NAME_LEN + 1]; + char ArrayMembersInPack[MAX_SIZE + 1]; +}; + +// JSON/PACK converter hint +struct JSONPACKHINT +{ + UINT NumHints; + JSONPACKHINT_ITEM Hints[MAX_JSONPACK_HINT_ITEMS]; }; @@ -198,21 +226,23 @@ TOKEN_LIST *GetPackElementNames(PACK *p); X *PackGetX(PACK *p, char *name); K *PackGetK(PACK *p, char *name); -void PackAddX(PACK *p, char *name, X *x); -void PackAddK(PACK *p, char *name, K *k); -void PackAddStr(PACK *p, char *name, char *str); -void PackAddStrEx(PACK *p, char *name, char *str, UINT index, UINT total); -void PackAddUniStr(PACK *p, char *name, wchar_t *unistr); -void PackAddUniStrEx(PACK *p, char *name, wchar_t *unistr, UINT index, UINT total); -void PackAddInt(PACK *p, char *name, UINT i); -void PackAddNum(PACK *p, char *name, UINT num); -void PackAddIntEx(PACK *p, char *name, UINT i, UINT index, UINT total); -void PackAddInt64(PACK *p, char *name, UINT64 i); -void PackAddInt64Ex(PACK *p, char *name, UINT64 i, UINT index, UINT total); -void PackAddData(PACK *p, char *name, void *data, UINT size); -void PackAddDataEx(PACK *p, char *name, void *data, UINT size, UINT index, UINT total); -void PackAddBuf(PACK *p, char *name, BUF *b); -void PackAddBufEx(PACK *p, char *name, BUF *b, UINT index, UINT total); +ELEMENT *PackAddX(PACK *p, char *name, X *x); +ELEMENT *PackAddK(PACK *p, char *name, K *k); +ELEMENT *PackAddStr(PACK *p, char *name, char *str); +ELEMENT *PackAddStrEx(PACK *p, char *name, char *str, UINT index, UINT total); +ELEMENT *PackAddUniStr(PACK *p, char *name, wchar_t *unistr); +ELEMENT *PackAddUniStrEx(PACK *p, char *name, wchar_t *unistr, UINT index, UINT total); +ELEMENT *PackAddInt(PACK *p, char *name, UINT i); +ELEMENT *PackAddNum(PACK *p, char *name, UINT num); +ELEMENT *PackAddIntEx(PACK *p, char *name, UINT i, UINT index, UINT total); +ELEMENT *PackAddInt64(PACK *p, char *name, UINT64 i); +ELEMENT *PackAddInt64Ex(PACK *p, char *name, UINT64 i, UINT index, UINT total); +ELEMENT *PackAddTime64(PACK *p, char *name, UINT64 i); +ELEMENT *PackAddTime64Ex(PACK *p, char *name, UINT64 i, UINT index, UINT total); +ELEMENT *PackAddData(PACK *p, char *name, void *data, UINT size); +ELEMENT *PackAddDataEx(PACK *p, char *name, void *data, UINT size, UINT index, UINT total); +ELEMENT *PackAddBuf(PACK *p, char *name, BUF *b); +ELEMENT *PackAddBufEx(PACK *p, char *name, BUF *b, UINT index, UINT total); bool PackGetStr(PACK *p, char *name, char *str, UINT size); bool PackGetStrEx(PACK *p, char *name, char *str, UINT size, UINT index); bool PackGetUniStr(PACK *p, char *name, wchar_t *unistr, UINT size); @@ -231,23 +261,39 @@ bool PackGetDataEx(PACK *p, char *name, void *data, UINT index); BUF *PackGetBuf(PACK *p, char *name); BUF *PackGetBufEx(PACK *p, char *name, UINT index); bool PackGetBool(PACK *p, char *name); -void PackAddBool(PACK *p, char *name, bool b); -void PackAddBoolEx(PACK *p, char *name, bool b, UINT index, UINT total); +ELEMENT *PackAddBool(PACK *p, char *name, bool b); +ELEMENT *PackAddBoolEx(PACK *p, char *name, bool b, UINT index, UINT total); bool PackGetBoolEx(PACK *p, char *name, UINT index); void PackAddIp(PACK *p, char *name, IP *ip); void PackAddIpEx(PACK *p, char *name, IP *ip, UINT index, UINT total); +void PackAddIpEx2(PACK *p, char *name, IP *ip, UINT index, UINT total, bool is_single); bool PackGetIp(PACK *p, char *name, IP *ip); bool PackGetIpEx(PACK *p, char *name, IP *ip, UINT index); UINT PackGetIp32(PACK *p, char *name); UINT PackGetIp32Ex(PACK *p, char *name, UINT index); void PackAddIp32(PACK *p, char *name, UINT ip32); void PackAddIp32Ex(PACK *p, char *name, UINT ip32, UINT index, UINT total); -void PackAddIp6AddrEx(PACK *p, char *name, IPV6_ADDR *addr, UINT index, UINT total); +void PackAddIp32Ex2(PACK *p, char *name, UINT ip32, UINT index, UINT total, bool is_single); +ELEMENT *PackAddIp6AddrEx(PACK *p, char *name, IPV6_ADDR *addr, UINT index, UINT total); bool PackGetIp6AddrEx(PACK *p, char *name, IPV6_ADDR *addr, UINT index); -void PackAddIp6Addr(PACK *p, char *name, IPV6_ADDR *addr); +ELEMENT *PackAddIp6Addr(PACK *p, char *name, IPV6_ADDR *addr); bool PackGetIp6Addr(PACK *p, char *name, IPV6_ADDR *addr); bool PackGetData2(PACK *p, char *name, void *data, UINT size); bool PackGetDataEx2(PACK *p, char *name, void *data, UINT size, UINT index); bool PackIsValueExists(PACK *p, char *name); +void PackSetCurrentJsonGroupName(PACK *p, char *json_group_name); +ELEMENT *ElementNullSafe(ELEMENT *p); + +JSON_VALUE *PackToJson(PACK *p); +char *PackToJsonStr(PACK *p); + +PACK *JsonToPack(JSON_VALUE *v); +PACK *JsonStrToPack(char *str); + +void PackArrayElementToJsonArray(JSON_ARRAY *ja, PACK *p, ELEMENT *e, UINT index); +void PackElementToJsonObject(JSON_OBJECT *o, PACK *p, ELEMENT *e, UINT index); +char *DetermineJsonSuffixForPackElement(ELEMENT *e); +bool JsonTryParseValueAddToPack(PACK *p, JSON_VALUE *v, char *v_name, UINT index, UINT total, bool is_single); + #endif // PACK_H diff --git a/src/Mayaqua/Str.c b/src/Mayaqua/Str.c index 6e0a6ecf..ec4023da 100644 --- a/src/Mayaqua/Str.c +++ b/src/Mayaqua/Str.c @@ -108,6 +108,7 @@ #include #include #include +#include #include #include #include @@ -133,6 +134,60 @@ static BYTESTR bytestr[] = {0, "Bytes"}, }; +// Decode URL string +char *UrlDecode(char *url_str) +{ + UINT i, len; + BUF *b; + char *ret; + if (url_str == NULL) + { + return NULL; + } + + len = StrLen(url_str); + + b = NewBuf(); + + for (i = 0;i < len;i++) + { + char c = url_str[i]; + + if (c == '%' && ((i + 2) < len)) + { + char hex_str[8]; + UINT value; + + hex_str[0] = url_str[i + 1]; + hex_str[1] = url_str[i + 2]; + hex_str[2] = 0; + + value = HexToInt(hex_str); + + WriteBufChar(b, (UCHAR)value); + + i += 2; + continue; + } + else + { + if (c == '+') + { + c = ' '; + } + WriteBufChar(b, c); + } + } + + WriteBufChar(b, 0); + + ret = CopyStr(b->Buf); + + FreeBuf(b); + + return ret; +} + // Change the case of the string by the bit array void SetStrCaseAccordingToBits(char *str, UINT bits) { @@ -1764,6 +1819,73 @@ UINT64 ToInt64(char *str) return ret; } +UINT64 Json_ToInt64Ex(char *str, char **endptr, bool *error) +{ + UINT i; + UINT64 ret = 0; + if (error != NULL) *error = true; + // Validate arguments + if (str == NULL) + { + if (endptr != NULL) + { + *endptr = NULL; + } + return 0; + } + + for (i = 0;;i++) + { + char c = str[i]; + if (endptr != NULL) + { + *endptr = &str[i]; + } + if (c == 0) + { + break; + } + if ('0' <= c && c <= '9') + { + ret = ret * (UINT64)10 + (UINT64)(c - '0'); + if (error != NULL) *error = false; + } + else + { + break; + } + } + + return ret; +} + +// Trim EndWith +bool TrimEndWith(char *dst, UINT dst_size, char *str, char *key) +{ + if (dst == NULL || str == NULL) + { + ClearStr(dst, dst_size); + return false; + } + + StrCpy(dst, dst_size, str); + + if (EndWith(str, key)) + { + UINT src_len = StrLen(str); + UINT key_len = StrLen(key); + + if (src_len >= key_len) + { + dst[src_len - key_len] = 0; + } + + return true; + } + + return false; +} + // Check whether the str ends with the key bool EndWith(char *str, char *key) { @@ -3454,3 +3576,1991 @@ UINT StrLen(char *str) } +// *** JSON strings support +// Original source code from Parson ( http://kgabis.github.com/parson/ ) +// Modified by dnobori +/* +Parson ( http://kgabis.github.com/parson/ ) +Copyright (c) 2012 - 2017 Krzysztof Gabis + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + + + +/* Apparently sscanf is not implemented in some "standard" libraries, so don't use it, if you +* don't have to. */ +#define sscanf THINK_TWICE_ABOUT_USING_SSCANF + +#define STARTING_CAPACITY 16 +#define MAX_NESTING 2048 +#define FLOAT_FORMAT "%1.17g" + +#define SIZEOF_TOKEN(a) (sizeof(a) - 1) +#define SKIP_CHAR(str) ((*str)++) +#define SKIP_WHITESPACES(str) while (isspace((unsigned char)(**str))) { SKIP_CHAR(str); } + +static JSON_Malloc_Function parson_malloc = Malloc; +static JSON_Free_Function parson_free = Free; + +#define IS_CONT(b) (((unsigned char)(b) & 0xC0) == 0x80) /* is utf-8 continuation byte */ + +/* Various */ +static void remove_comments(char *string, char *start_token, char *end_token); +static char * parson_strndup(char *string, UINT n); +static char * parson_strdup(char *string); +static int hex_char_to_int(char c); +static int parse_utf16_hex(char *string, unsigned int *result); +static int num_bytes_in_utf8_sequence(unsigned char c); +static int verify_utf8_sequence(unsigned char *string, int *len); +static int is_valid_utf8(char *string, UINT string_len); +static int is_decimal(char *string, UINT length); + +/* JSON Object */ +static JSON_OBJECT * json_object_init(JSON_VALUE *wrapping_value); +static UINT json_object_add(JSON_OBJECT *object, char *name, JSON_VALUE *value); +static UINT json_object_resize(JSON_OBJECT *object, UINT new_capacity); +static JSON_VALUE * json_object_nget_value(JSON_OBJECT *object, char *name, UINT n); +static void json_object_free(JSON_OBJECT *object); + +/* JSON Array */ +static JSON_ARRAY * json_array_init(JSON_VALUE *wrapping_value); +static UINT json_array_add(JSON_ARRAY *array, JSON_VALUE *value); +static UINT json_array_resize(JSON_ARRAY *array, UINT new_capacity); +static void json_array_free(JSON_ARRAY *array); + +/* JSON Value */ +static JSON_VALUE * json_value_init_string_no_copy(char *string); + +/* Parser */ +static UINT skip_quotes(char **string); +static int parse_utf16(char **unprocessed, char **processed); +static char * process_string(char *input, UINT len); +static char * get_quoted_string(char **string); +static JSON_VALUE * parse_object_value(char **string, UINT nesting); +static JSON_VALUE * parse_array_value(char **string, UINT nesting); +static JSON_VALUE * parse_string_value(char **string); +static JSON_VALUE * parse_boolean_value(char **string); +static JSON_VALUE * parse_number_value(char **string); +static JSON_VALUE * parse_null_value(char **string); +static JSON_VALUE * parse_value(char **string, UINT nesting); + +/* Serialization */ +static int json_serialize_to_buffer_r(JSON_VALUE *value, char *buf, int level, int is_pretty, char *num_buf); +static int json_serialize_string(char *string, char *buf); +static int append_indent(char *buf, int level); +static int append_string(char *buf, char *string); + +/* Various */ +static char * parson_strndup(char *string, UINT n) { + char *output_string = (char*)parson_malloc(n + 1); + if (!output_string) { + return NULL; + } + output_string[n] = '\0'; + strncpy(output_string, string, n); + return output_string; +} + +static char * parson_strdup(char *string) { + return parson_strndup(string, StrLen(string)); +} + +static int hex_char_to_int(char c) { + if (c >= '0' && c <= '9') { + return c - '0'; + } + else if (c >= 'a' && c <= 'f') { + return c - 'a' + 10; + } + else if (c >= 'A' && c <= 'F') { + return c - 'A' + 10; + } + return -1; +} + +static int parse_utf16_hex(char *s, unsigned int *result) { + int x1, x2, x3, x4; + if (s[0] == '\0' || s[1] == '\0' || s[2] == '\0' || s[3] == '\0') { + return 0; + } + x1 = hex_char_to_int(s[0]); + x2 = hex_char_to_int(s[1]); + x3 = hex_char_to_int(s[2]); + x4 = hex_char_to_int(s[3]); + if (x1 == -1 || x2 == -1 || x3 == -1 || x4 == -1) { + return 0; + } + *result = (unsigned int)((x1 << 12) | (x2 << 8) | (x3 << 4) | x4); + return 1; +} + +static int num_bytes_in_utf8_sequence(unsigned char c) { + if (c == 0xC0 || c == 0xC1 || c > 0xF4 || IS_CONT(c)) { + return 0; + } + else if ((c & 0x80) == 0) { /* 0xxxxxxx */ + return 1; + } + else if ((c & 0xE0) == 0xC0) { /* 110xxxxx */ + return 2; + } + else if ((c & 0xF0) == 0xE0) { /* 1110xxxx */ + return 3; + } + else if ((c & 0xF8) == 0xF0) { /* 11110xxx */ + return 4; + } + return 0; /* won't happen */ +} + +static int verify_utf8_sequence(unsigned char *string, int *len) { + unsigned int cp = 0; + *len = num_bytes_in_utf8_sequence(string[0]); + + if (*len == 1) { + cp = string[0]; + } + else if (*len == 2 && IS_CONT(string[1])) { + cp = string[0] & 0x1F; + cp = (cp << 6) | (string[1] & 0x3F); + } + else if (*len == 3 && IS_CONT(string[1]) && IS_CONT(string[2])) { + cp = ((unsigned char)string[0]) & 0xF; + cp = (cp << 6) | (string[1] & 0x3F); + cp = (cp << 6) | (string[2] & 0x3F); + } + else if (*len == 4 && IS_CONT(string[1]) && IS_CONT(string[2]) && IS_CONT(string[3])) { + cp = string[0] & 0x7; + cp = (cp << 6) | (string[1] & 0x3F); + cp = (cp << 6) | (string[2] & 0x3F); + cp = (cp << 6) | (string[3] & 0x3F); + } + else { + return 0; + } + + /* overlong encodings */ + if ((cp < 0x80 && *len > 1) || + (cp < 0x800 && *len > 2) || + (cp < 0x10000 && *len > 3)) { + return 0; + } + + /* invalid unicode */ + if (cp > 0x10FFFF) { + return 0; + } + + /* surrogate halves */ + if (cp >= 0xD800 && cp <= 0xDFFF) { + return 0; + } + + return 1; +} + +static int is_valid_utf8(char *string, UINT string_len) { + int len = 0; + char *string_end = string + string_len; + while (string < string_end) { + if (!verify_utf8_sequence((unsigned char*)string, &len)) { + return 0; + } + string += len; + } + return 1; +} + +static int is_decimal(char *string, UINT length) { + if (length > 1 && string[0] == '0' && string[1] != '.') { + return 0; + } + if (length > 2 && !strncmp(string, "-0", 2) && string[2] != '.') { + return 0; + } + while (length--) { + if (strchr("xX", string[length])) { + return 0; + } + } + return 1; +} + +static void remove_comments(char *string, char *start_token, char *end_token) { + int in_string = 0, escaped = 0; + UINT i; + char *ptr = NULL, current_char; + UINT start_token_len = StrLen(start_token); + UINT end_token_len = StrLen(end_token); + if (start_token_len == 0 || end_token_len == 0) { + return; + } + while ((current_char = *string) != '\0') { + if (current_char == '\\' && !escaped) { + escaped = 1; + string++; + continue; + } + else if (current_char == '\"' && !escaped) { + in_string = !in_string; + } + else if (!in_string && strncmp(string, start_token, start_token_len) == 0) { + for (i = 0; i < start_token_len; i++) { + string[i] = ' '; + } + string = string + start_token_len; + ptr = strstr(string, end_token); + if (!ptr) { + return; + } + for (i = 0; i < (ptr - string) + end_token_len; i++) { + string[i] = ' '; + } + string = ptr + end_token_len - 1; + } + escaped = 0; + string++; + } +} + +/* JSON Object */ +static JSON_OBJECT * json_object_init(JSON_VALUE *wrapping_value) { + JSON_OBJECT *new_obj = (JSON_OBJECT*)parson_malloc(sizeof(JSON_OBJECT)); + if (new_obj == NULL) { + return NULL; + } + new_obj->wrapping_value = wrapping_value; + new_obj->names = (char**)NULL; + new_obj->values = (JSON_VALUE**)NULL; + new_obj->capacity = 0; + new_obj->count = 0; + return new_obj; +} + +static UINT json_object_add(JSON_OBJECT *object, char *name, JSON_VALUE *value) { + UINT index = 0; + if (object == NULL || name == NULL || value == NULL) { + return JSON_RET_ERROR; + } + if (JsonGet(object, name) != NULL) { + return JSON_RET_ERROR; + } + if (object->count >= object->capacity) { + UINT new_capacity = MAX(object->capacity * 2, STARTING_CAPACITY); + if (json_object_resize(object, new_capacity) == JSON_RET_ERROR) { + return JSON_RET_ERROR; + } + } + index = object->count; + object->names[index] = parson_strdup(name); + if (object->names[index] == NULL) { + return JSON_RET_ERROR; + } + value->parent = JsonGetWrappingValue(object); + object->values[index] = value; + object->count++; + return JSON_RET_OK; +} + +static UINT json_object_resize(JSON_OBJECT *object, UINT new_capacity) { + char **temp_names = NULL; + JSON_VALUE **temp_values = NULL; + + if ((object->names == NULL && object->values != NULL) || + (object->names != NULL && object->values == NULL) || + new_capacity == 0) { + return JSON_RET_ERROR; /* Shouldn't happen */ + } + temp_names = (char**)parson_malloc(new_capacity * sizeof(char*)); + if (temp_names == NULL) { + return JSON_RET_ERROR; + } + temp_values = (JSON_VALUE**)parson_malloc(new_capacity * sizeof(JSON_VALUE*)); + if (temp_values == NULL) { + parson_free(temp_names); + return JSON_RET_ERROR; + } + if (object->names != NULL && object->values != NULL && object->count > 0) { + memcpy(temp_names, object->names, object->count * sizeof(char*)); + memcpy(temp_values, object->values, object->count * sizeof(JSON_VALUE*)); + } + parson_free(object->names); + parson_free(object->values); + object->names = temp_names; + object->values = temp_values; + object->capacity = new_capacity; + return JSON_RET_OK; +} + +static JSON_VALUE * json_object_nget_value(JSON_OBJECT *object, char *name, UINT n) { + UINT i, name_length; + for (i = 0; i < JsonGetCount(object); i++) { + name_length = StrLen(object->names[i]); + if (name_length != n) { + continue; + } + if (strncmp(object->names[i], name, n) == 0) { + return object->values[i]; + } + } + return NULL; +} + +static void json_object_free(JSON_OBJECT *object) { + UINT i; + for (i = 0; i < object->count; i++) { + parson_free(object->names[i]); + JsonFree(object->values[i]); + } + parson_free(object->names); + parson_free(object->values); + parson_free(object); +} + +/* JSON Array */ +static JSON_ARRAY * json_array_init(JSON_VALUE *wrapping_value) { + JSON_ARRAY *new_array = (JSON_ARRAY*)parson_malloc(sizeof(JSON_ARRAY)); + if (new_array == NULL) { + return NULL; + } + new_array->wrapping_value = wrapping_value; + new_array->items = (JSON_VALUE**)NULL; + new_array->capacity = 0; + new_array->count = 0; + return new_array; +} + +static UINT json_array_add(JSON_ARRAY *array, JSON_VALUE *value) { + if (array->count >= array->capacity) { + UINT new_capacity = MAX(array->capacity * 2, STARTING_CAPACITY); + if (json_array_resize(array, new_capacity) == JSON_RET_ERROR) { + return JSON_RET_ERROR; + } + } + value->parent = JsonArrayGetWrappingValue(array); + array->items[array->count] = value; + array->count++; + return JSON_RET_OK; +} + +static UINT json_array_resize(JSON_ARRAY *array, UINT new_capacity) { + JSON_VALUE **new_items = NULL; + if (new_capacity == 0) { + return JSON_RET_ERROR; + } + new_items = (JSON_VALUE**)parson_malloc(new_capacity * sizeof(JSON_VALUE*)); + if (new_items == NULL) { + return JSON_RET_ERROR; + } + if (array->items != NULL && array->count > 0) { + memcpy(new_items, array->items, array->count * sizeof(JSON_VALUE*)); + } + parson_free(array->items); + array->items = new_items; + array->capacity = new_capacity; + return JSON_RET_OK; +} + +static void json_array_free(JSON_ARRAY *array) { + UINT i; + for (i = 0; i < array->count; i++) { + JsonFree(array->items[i]); + } + parson_free(array->items); + parson_free(array); +} + +/* JSON Value */ +static JSON_VALUE * json_value_init_string_no_copy(char *string) { + JSON_VALUE *new_value = (JSON_VALUE*)parson_malloc(sizeof(JSON_VALUE)); + if (!new_value) { + return NULL; + } + new_value->parent = NULL; + new_value->type = JSON_TYPE_STRING; + new_value->value.string = string; + return new_value; +} + +/* Parser */ +static UINT skip_quotes(char **string) { + if (**string != '\"') { + return JSON_RET_ERROR; + } + SKIP_CHAR(string); + while (**string != '\"') { + if (**string == '\0') { + return JSON_RET_ERROR; + } + else if (**string == '\\') { + SKIP_CHAR(string); + if (**string == '\0') { + return JSON_RET_ERROR; + } + } + SKIP_CHAR(string); + } + SKIP_CHAR(string); + return JSON_RET_OK; +} + +static int parse_utf16(char **unprocessed, char **processed) { + unsigned int cp, lead, trail; + int parse_succeeded = 0; + char *processed_ptr = *processed; + char *unprocessed_ptr = *unprocessed; + unprocessed_ptr++; /* skips u */ + parse_succeeded = parse_utf16_hex(unprocessed_ptr, &cp); + if (!parse_succeeded) { + return JSON_RET_ERROR; + } + if (cp < 0x80) { + processed_ptr[0] = (char)cp; /* 0xxxxxxx */ + } + else if (cp < 0x800) { + processed_ptr[0] = ((cp >> 6) & 0x1F) | 0xC0; /* 110xxxxx */ + processed_ptr[1] = ((cp) & 0x3F) | 0x80; /* 10xxxxxx */ + processed_ptr += 1; + } + else if (cp < 0xD800 || cp > 0xDFFF) { + processed_ptr[0] = ((cp >> 12) & 0x0F) | 0xE0; /* 1110xxxx */ + processed_ptr[1] = ((cp >> 6) & 0x3F) | 0x80; /* 10xxxxxx */ + processed_ptr[2] = ((cp) & 0x3F) | 0x80; /* 10xxxxxx */ + processed_ptr += 2; + } + else if (cp >= 0xD800 && cp <= 0xDBFF) { /* lead surrogate (0xD800..0xDBFF) */ + lead = cp; + unprocessed_ptr += 4; /* should always be within the buffer, otherwise previous sscanf would fail */ + if (*unprocessed_ptr++ != '\\' || *unprocessed_ptr++ != 'u') { + return JSON_RET_ERROR; + } + parse_succeeded = parse_utf16_hex(unprocessed_ptr, &trail); + if (!parse_succeeded || trail < 0xDC00 || trail > 0xDFFF) { /* valid trail surrogate? (0xDC00..0xDFFF) */ + return JSON_RET_ERROR; + } + cp = ((((lead - 0xD800) & 0x3FF) << 10) | ((trail - 0xDC00) & 0x3FF)) + 0x010000; + processed_ptr[0] = (((cp >> 18) & 0x07) | 0xF0); /* 11110xxx */ + processed_ptr[1] = (((cp >> 12) & 0x3F) | 0x80); /* 10xxxxxx */ + processed_ptr[2] = (((cp >> 6) & 0x3F) | 0x80); /* 10xxxxxx */ + processed_ptr[3] = (((cp) & 0x3F) | 0x80); /* 10xxxxxx */ + processed_ptr += 3; + } + else { /* trail surrogate before lead surrogate */ + return JSON_RET_ERROR; + } + unprocessed_ptr += 3; + *processed = processed_ptr; + *unprocessed = unprocessed_ptr; + return JSON_RET_OK; +} + + +/* Copies and processes passed string up to supplied length. +Example: "\u006Corem ipsum" -> lorem ipsum */ +static char* process_string(char *input, UINT len) { + char *input_ptr = input; + UINT initial_size = (len + 1) * sizeof(char); + UINT final_size = 0; + char *output = NULL, *output_ptr = NULL, *resized_output = NULL; + output = (char*)parson_malloc(initial_size); + if (output == NULL) { + goto error; + } + output_ptr = output; + while ((*input_ptr != '\0') && (UINT)(input_ptr - input) < len) { + if (*input_ptr == '\\') { + input_ptr++; + switch (*input_ptr) { + case '\"': *output_ptr = '\"'; break; + case '\\': *output_ptr = '\\'; break; + case '/': *output_ptr = '/'; break; + case 'b': *output_ptr = '\b'; break; + case 'f': *output_ptr = '\f'; break; + case 'n': *output_ptr = '\n'; break; + case 'r': *output_ptr = '\r'; break; + case 't': *output_ptr = '\t'; break; + case 'u': + if (parse_utf16(&input_ptr, &output_ptr) == JSON_RET_ERROR) { + goto error; + } + break; + default: + goto error; + } + } + else if ((unsigned char)*input_ptr < 0x20) { + goto error; /* 0x00-0x19 are invalid characters for json string (http://www.ietf.org/rfc/rfc4627.txt) */ + } + else { + *output_ptr = *input_ptr; + } + output_ptr++; + input_ptr++; + } + *output_ptr = '\0'; + /* resize to new length */ + final_size = (UINT)(output_ptr - output) + 1; + /* todo: don't resize if final_size == initial_size */ + resized_output = (char*)parson_malloc(final_size); + if (resized_output == NULL) { + goto error; + } + memcpy(resized_output, output, final_size); + parson_free(output); + return resized_output; +error: + parson_free(output); + return NULL; +} + +/* Return processed contents of a string between quotes and +skips passed argument to a matching quote. */ +static char * get_quoted_string(char **string) { + char *string_start = *string; + UINT string_len = 0; + UINT status = skip_quotes(string); + if (status != JSON_RET_OK) { + return NULL; + } + string_len = (UINT)(*string - string_start - 2); /* length without quotes */ + return process_string(string_start + 1, string_len); +} + +static JSON_VALUE * parse_value(char **string, UINT nesting) { + if (nesting > MAX_NESTING) { + return NULL; + } + SKIP_WHITESPACES(string); + switch (**string) { + case '{': + return parse_object_value(string, nesting + 1); + case '[': + return parse_array_value(string, nesting + 1); + case '\"': + return parse_string_value(string); + case 'f': case 't': + return parse_boolean_value(string); + case '-': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + return parse_number_value(string); + case 'n': + return parse_null_value(string); + default: + return NULL; + } +} + +static JSON_VALUE * parse_object_value(char **string, UINT nesting) { + JSON_VALUE *output_value = JsonNewObject(), *new_value = NULL; + JSON_OBJECT *output_object = JsonValueGetObject(output_value); + char *new_key = NULL; + if (output_value == NULL || **string != '{') { + return NULL; + } + SKIP_CHAR(string); + SKIP_WHITESPACES(string); + if (**string == '}') { /* empty object */ + SKIP_CHAR(string); + return output_value; + } + while (**string != '\0') { + new_key = get_quoted_string(string); + if (new_key == NULL) { + JsonFree(output_value); + return NULL; + } + SKIP_WHITESPACES(string); + if (**string != ':') { + parson_free(new_key); + JsonFree(output_value); + return NULL; + } + SKIP_CHAR(string); + new_value = parse_value(string, nesting); + if (new_value == NULL) { + parson_free(new_key); + JsonFree(output_value); + return NULL; + } + if (json_object_add(output_object, new_key, new_value) == JSON_RET_ERROR) { + parson_free(new_key); + JsonFree(new_value); + JsonFree(output_value); + return NULL; + } + parson_free(new_key); + SKIP_WHITESPACES(string); + if (**string != ',') { + break; + } + SKIP_CHAR(string); + SKIP_WHITESPACES(string); + } + SKIP_WHITESPACES(string); + if (**string != '}' || /* Trim object after parsing is over */ + json_object_resize(output_object, JsonGetCount(output_object)) == JSON_RET_ERROR) { + JsonFree(output_value); + return NULL; + } + SKIP_CHAR(string); + return output_value; +} + +static JSON_VALUE * parse_array_value(char **string, UINT nesting) { + JSON_VALUE *output_value = JsonNewArray(), *new_array_value = NULL; + JSON_ARRAY *output_array = JsonValueGetArray(output_value); + if (!output_value || **string != '[') { + return NULL; + } + SKIP_CHAR(string); + SKIP_WHITESPACES(string); + if (**string == ']') { /* empty array */ + SKIP_CHAR(string); + return output_value; + } + while (**string != '\0') { + new_array_value = parse_value(string, nesting); + if (new_array_value == NULL) { + JsonFree(output_value); + return NULL; + } + if (json_array_add(output_array, new_array_value) == JSON_RET_ERROR) { + JsonFree(new_array_value); + JsonFree(output_value); + return NULL; + } + SKIP_WHITESPACES(string); + if (**string != ',') { + break; + } + SKIP_CHAR(string); + SKIP_WHITESPACES(string); + } + SKIP_WHITESPACES(string); + if (**string != ']' || /* Trim array after parsing is over */ + json_array_resize(output_array, JsonArrayGetCount(output_array)) == JSON_RET_ERROR) { + JsonFree(output_value); + return NULL; + } + SKIP_CHAR(string); + return output_value; +} + +static JSON_VALUE * parse_string_value(char **string) { + JSON_VALUE *value = NULL; + char *new_string = get_quoted_string(string); + if (new_string == NULL) { + return NULL; + } + value = json_value_init_string_no_copy(new_string); + if (value == NULL) { + parson_free(new_string); + return NULL; + } + return value; +} + +static JSON_VALUE * parse_boolean_value(char **string) { + UINT true_token_size = SIZEOF_TOKEN("true"); + UINT false_token_size = SIZEOF_TOKEN("false"); + if (strncmp("true", *string, true_token_size) == 0) { + *string += true_token_size; + return JsonNewBool(1); + } + else if (strncmp("false", *string, false_token_size) == 0) { + *string += false_token_size; + return JsonNewBool(0); + } + return NULL; +} + +static JSON_VALUE * parse_number_value(char **string) { + char *end; + bool error = false; + UINT64 number = 0; + number = Json_ToInt64Ex(*string, &end, &error); + + if (error) + { + return NULL; + } + *string = end; + return JsonNewNumber(number); +} + +static JSON_VALUE * parse_null_value(char **string) { + UINT token_size = SIZEOF_TOKEN("null"); + if (strncmp("null", *string, token_size) == 0) { + *string += token_size; + return JsonNewNull(); + } + return NULL; +} + +/* Serialization */ +#define APPEND_STRING(str) do { written = append_string(buf, (str));\ + if (written < 0) { return -1; }\ + if (buf != NULL) { buf += written; }\ + written_total += written; } while(0) + +#define APPEND_INDENT(level) do { written = append_indent(buf, (level));\ + if (written < 0) { return -1; }\ + if (buf != NULL) { buf += written; }\ + written_total += written; } while(0) + +static int json_serialize_to_buffer_r(JSON_VALUE *value, char *buf, int level, int is_pretty, char *num_buf) +{ + char *key = NULL, *string = NULL; + JSON_VALUE *temp_value = NULL; + JSON_ARRAY *array = NULL; + JSON_OBJECT *object = NULL; + UINT i = 0, count = 0; + UINT64 num = 0; + int written = -1, written_total = 0; + char tmp[32]; + + switch (JsonValueGetType(value)) { + case JSON_TYPE_ARRAY: + array = JsonValueGetArray(value); + count = JsonArrayGetCount(array); + APPEND_STRING("["); + if (count > 0 && is_pretty) { + APPEND_STRING("\n"); + } + for (i = 0; i < count; i++) { + if (is_pretty) { + APPEND_INDENT(level + 1); + } + temp_value = JsonArrayGet(array, i); + written = json_serialize_to_buffer_r(temp_value, buf, level + 1, is_pretty, num_buf); + if (written < 0) { + return -1; + } + if (buf != NULL) { + buf += written; + } + written_total += written; + if (i < (count - 1)) { + APPEND_STRING(","); + } + if (is_pretty) { + APPEND_STRING("\n"); + } + } + if (count > 0 && is_pretty) { + APPEND_INDENT(level); + } + APPEND_STRING("]"); + return written_total; + case JSON_TYPE_OBJECT: + object = JsonValueGetObject(value); + count = JsonGetCount(object); + APPEND_STRING("{"); + if (count > 0 && is_pretty) { + APPEND_STRING("\n"); + } + for (i = 0; i < count; i++) { + key = JsonGetName(object, i); + if (key == NULL) { + return -1; + } + if (is_pretty) { + APPEND_INDENT(level + 1); + } + written = json_serialize_string(key, buf); + if (written < 0) { + return -1; + } + if (buf != NULL) { + buf += written; + } + written_total += written; + APPEND_STRING(":"); + if (is_pretty) { + APPEND_STRING(" "); + } + temp_value = JsonGet(object, key); + written = json_serialize_to_buffer_r(temp_value, buf, level + 1, is_pretty, num_buf); + if (written < 0) { + return -1; + } + if (buf != NULL) { + buf += written; + } + written_total += written; + if (i < (count - 1)) { + APPEND_STRING(","); + } + if (is_pretty) { + APPEND_STRING("\n"); + } + } + if (count > 0 && is_pretty) { + APPEND_INDENT(level); + } + APPEND_STRING("}"); + return written_total; + case JSON_TYPE_STRING: + string = JsonValueGetStr(value); + if (string == NULL) { + return -1; + } + written = json_serialize_string(string, buf); + if (written < 0) { + return -1; + } + if (buf != NULL) { + buf += written; + } + written_total += written; + return written_total; + case JSON_TYPE_BOOL: + if (JsonValueGetBool(value)) { + APPEND_STRING("true"); + } + else { + APPEND_STRING("false"); + } + return written_total; + case JSON_TYPE_NUMBER: + num = JsonValueGetNumber(value); + if (buf != NULL) { + num_buf = buf; + } + ToStr64(tmp, num); + Copy(num_buf, tmp, StrLen(tmp)); + written = StrLen(tmp); + if (buf != NULL) { + buf += written; + } + written_total += written; + return written_total; + case JSON_TYPE_NULL: + APPEND_STRING("null"); + return written_total; + case JSON_TYPE_ERROR: + return -1; + default: + return -1; + } +} + +static int json_serialize_string(char *string, char *buf) { + UINT i = 0, len = StrLen(string); + char c = '\0'; + int written = -1, written_total = 0; + APPEND_STRING("\""); + for (i = 0; i < len; i++) { + c = string[i]; + switch (c) { + case '\"': APPEND_STRING("\\\""); break; + case '\\': APPEND_STRING("\\\\"); break; + case '/': APPEND_STRING("\\/"); break; /* to make json embeddable in xml\/html */ + case '\b': APPEND_STRING("\\b"); break; + case '\f': APPEND_STRING("\\f"); break; + case '\n': APPEND_STRING("\\n"); break; + case '\r': APPEND_STRING("\\r"); break; + case '\t': APPEND_STRING("\\t"); break; + case '\x00': APPEND_STRING("\\u0000"); break; + case '\x01': APPEND_STRING("\\u0001"); break; + case '\x02': APPEND_STRING("\\u0002"); break; + case '\x03': APPEND_STRING("\\u0003"); break; + case '\x04': APPEND_STRING("\\u0004"); break; + case '\x05': APPEND_STRING("\\u0005"); break; + case '\x06': APPEND_STRING("\\u0006"); break; + case '\x07': APPEND_STRING("\\u0007"); break; + /* '\x08' duplicate: '\b' */ + /* '\x09' duplicate: '\t' */ + /* '\x0a' duplicate: '\n' */ + case '\x0b': APPEND_STRING("\\u000b"); break; + /* '\x0c' duplicate: '\f' */ + /* '\x0d' duplicate: '\r' */ + case '\x0e': APPEND_STRING("\\u000e"); break; + case '\x0f': APPEND_STRING("\\u000f"); break; + case '\x10': APPEND_STRING("\\u0010"); break; + case '\x11': APPEND_STRING("\\u0011"); break; + case '\x12': APPEND_STRING("\\u0012"); break; + case '\x13': APPEND_STRING("\\u0013"); break; + case '\x14': APPEND_STRING("\\u0014"); break; + case '\x15': APPEND_STRING("\\u0015"); break; + case '\x16': APPEND_STRING("\\u0016"); break; + case '\x17': APPEND_STRING("\\u0017"); break; + case '\x18': APPEND_STRING("\\u0018"); break; + case '\x19': APPEND_STRING("\\u0019"); break; + case '\x1a': APPEND_STRING("\\u001a"); break; + case '\x1b': APPEND_STRING("\\u001b"); break; + case '\x1c': APPEND_STRING("\\u001c"); break; + case '\x1d': APPEND_STRING("\\u001d"); break; + case '\x1e': APPEND_STRING("\\u001e"); break; + case '\x1f': APPEND_STRING("\\u001f"); break; + default: + if (buf != NULL) { + buf[0] = c; + buf += 1; + } + written_total += 1; + break; + } + } + APPEND_STRING("\""); + return written_total; +} + +static int append_indent(char *buf, int level) { + int i; + int written = -1, written_total = 0; + for (i = 0; i < level; i++) { + APPEND_STRING(" "); + } + return written_total; +} + +static int append_string(char *buf, char *string) { + if (buf == NULL) { + return (int)strlen(string); + } + return sprintf(buf, "%s", string); +} + +#undef APPEND_STRING +#undef APPEND_INDENT + +JSON_VALUE * JsonParseString(char *string) { + if (string == NULL) { + return NULL; + } + if (string[0] == '\xEF' && string[1] == '\xBB' && string[2] == '\xBF') { + string = string + 3; /* Support for UTF-8 BOM */ + } + return parse_value((char**)&string, 0); +} + +JSON_VALUE * JsonParseStringWithComments(char *string) { + JSON_VALUE *result = NULL; + char *string_mutable_copy = NULL, *string_mutable_copy_ptr = NULL; + string_mutable_copy = parson_strdup(string); + if (string_mutable_copy == NULL) { + return NULL; + } + remove_comments(string_mutable_copy, "/*", "*/"); + remove_comments(string_mutable_copy, "//", "\n"); + string_mutable_copy_ptr = string_mutable_copy; + result = parse_value((char**)&string_mutable_copy_ptr, 0); + parson_free(string_mutable_copy); + return result; +} + +/* JSON Object API */ + +JSON_VALUE * JsonGet(JSON_OBJECT *object, char *name) { + if (object == NULL || name == NULL) { + return NULL; + } + return json_object_nget_value(object, name, StrLen(name)); +} + +char * JsonGetStr(JSON_OBJECT *object, char *name) { + return JsonValueGetStr(JsonGet(object, name)); +} + +UINT64 JsonGetNumber(JSON_OBJECT *object, char *name) { + return JsonValueGetNumber(JsonGet(object, name)); +} + +JSON_OBJECT * JsonGetObj(JSON_OBJECT *object, char *name) { + return JsonValueGetObject(JsonGet(object, name)); +} + +JSON_ARRAY * JsonGetArray(JSON_OBJECT *object, char *name) { + return JsonValueGetArray(JsonGet(object, name)); +} + +bool JsonGetBool(JSON_OBJECT *object, char *name) { + return JsonValueGetBool(JsonGet(object, name)); +} + +JSON_VALUE * JsonDotGet(JSON_OBJECT *object, char *name) { + char *dot_position = strchr(name, '.'); + if (!dot_position) { + return JsonGet(object, name); + } + object = JsonValueGetObject(json_object_nget_value(object, name, (UINT)(dot_position - name))); + return JsonDotGet(object, dot_position + 1); +} + +char * JsonDotGetStr(JSON_OBJECT *object, char *name) { + return JsonValueGetStr(JsonDotGet(object, name)); +} + +UINT64 JsonDotGetNumber(JSON_OBJECT *object, char *name) { + return JsonValueGetNumber(JsonDotGet(object, name)); +} + +JSON_OBJECT * JsonDotGetObj(JSON_OBJECT *object, char *name) { + return JsonValueGetObject(JsonDotGet(object, name)); +} + +JSON_ARRAY * JsonDotGetArray(JSON_OBJECT *object, char *name) { + return JsonValueGetArray(JsonDotGet(object, name)); +} + +bool JsonDotGetBool(JSON_OBJECT *object, char *name) { + return JsonValueGetBool(JsonDotGet(object, name)); +} + +UINT JsonGetCount(JSON_OBJECT *object) { + return object ? object->count : 0; +} + +char * JsonGetName(JSON_OBJECT *object, UINT index) { + if (object == NULL || index >= JsonGetCount(object)) { + return NULL; + } + return object->names[index]; +} + +JSON_VALUE * JsonGetValueAt(JSON_OBJECT *object, UINT index) { + if (object == NULL || index >= JsonGetCount(object)) { + return NULL; + } + return object->values[index]; +} + +JSON_VALUE *JsonGetWrappingValue(JSON_OBJECT *object) { + return object->wrapping_value; +} + +int JsonIsExists(JSON_OBJECT *object, char *name) { + return JsonGet(object, name) != NULL; +} + +int JsonIsExistsWithValueType(JSON_OBJECT *object, char *name, UINT type) { + JSON_VALUE *val = JsonGet(object, name); + return val != NULL && JsonValueGetType(val) == type; +} + +int JsonDotIsExists(JSON_OBJECT *object, char *name) { + return JsonDotGet(object, name) != NULL; +} + +int JsonDotIsExistsWithValueType(JSON_OBJECT *object, char *name, UINT type) { + JSON_VALUE *val = JsonDotGet(object, name); + return val != NULL && JsonValueGetType(val) == type; +} + +/* JSON Array API */ +JSON_VALUE * JsonArrayGet(JSON_ARRAY *array, UINT index) { + if (array == NULL || index >= JsonArrayGetCount(array)) { + return NULL; + } + return array->items[index]; +} + +char * JsonArrayGetStr(JSON_ARRAY *array, UINT index) { + return JsonValueGetStr(JsonArrayGet(array, index)); +} + +UINT64 JsonArrayGetNumber(JSON_ARRAY *array, UINT index) { + return JsonValueGetNumber(JsonArrayGet(array, index)); +} + +JSON_OBJECT * JsonArrayGetObj(JSON_ARRAY *array, UINT index) { + return JsonValueGetObject(JsonArrayGet(array, index)); +} + +JSON_ARRAY * JsonArrayGetArray(JSON_ARRAY *array, UINT index) { + return JsonValueGetArray(JsonArrayGet(array, index)); +} + +bool JsonArrayGetBool(JSON_ARRAY *array, UINT index) { + return JsonValueGetBool(JsonArrayGet(array, index)); +} + +UINT JsonArrayGetCount(JSON_ARRAY *array) { + return array ? array->count : 0; +} + +JSON_VALUE * JsonArrayGetWrappingValue(JSON_ARRAY *array) { + return array->wrapping_value; +} + +/* JSON Value API */ +UINT JsonValueGetType(JSON_VALUE *value) { + return value ? value->type : JSON_TYPE_ERROR; +} + +JSON_OBJECT * JsonValueGetObject(JSON_VALUE *value) { + if (value == NULL) + { + return NULL; + } + return JsonValueGetType(value) == JSON_TYPE_OBJECT ? value->value.object : NULL; +} + +JSON_ARRAY * JsonValueGetArray(JSON_VALUE *value) { + return JsonValueGetType(value) == JSON_TYPE_ARRAY ? value->value.array : NULL; +} + +char * JsonValueGetStr(JSON_VALUE *value) { + return JsonValueGetType(value) == JSON_TYPE_STRING ? value->value.string : NULL; +} + +UINT64 JsonValueGetNumber(JSON_VALUE *value) { + return JsonValueGetType(value) == JSON_TYPE_NUMBER ? value->value.number : 0; +} + +bool JsonValueGetBool(JSON_VALUE *value) { + return JsonValueGetType(value) == JSON_TYPE_BOOL ? value->value.boolean : 0; +} + +JSON_VALUE * JsonValueGetParent(JSON_VALUE *value) { + return value ? value->parent : NULL; +} + +void JsonFree(JSON_VALUE *value) { + if (value == NULL) + { + return; + } + switch (JsonValueGetType(value)) { + case JSON_TYPE_OBJECT: + json_object_free(value->value.object); + break; + case JSON_TYPE_STRING: + parson_free(value->value.string); + break; + case JSON_TYPE_ARRAY: + json_array_free(value->value.array); + break; + default: + break; + } + parson_free(value); +} + +JSON_VALUE * JsonNewObject(void) { + JSON_VALUE *new_value = (JSON_VALUE*)parson_malloc(sizeof(JSON_VALUE)); + if (!new_value) { + return NULL; + } + new_value->parent = NULL; + new_value->type = JSON_TYPE_OBJECT; + new_value->value.object = json_object_init(new_value); + if (!new_value->value.object) { + parson_free(new_value); + return NULL; + } + return new_value; +} + +JSON_VALUE * JsonNewArray(void) { + JSON_VALUE *new_value = (JSON_VALUE*)parson_malloc(sizeof(JSON_VALUE)); + if (!new_value) { + return NULL; + } + new_value->parent = NULL; + new_value->type = JSON_TYPE_ARRAY; + new_value->value.array = json_array_init(new_value); + if (!new_value->value.array) { + parson_free(new_value); + return NULL; + } + return new_value; +} + +JSON_VALUE * JsonNewStr(char *string) { + char *copy = NULL; + JSON_VALUE *value; + UINT string_len = 0; + if (string == NULL) { + return NULL; + } + string_len = StrLen(string); + if (!is_valid_utf8(string, string_len)) { + return NULL; + } + copy = parson_strndup(string, string_len); + if (copy == NULL) { + return NULL; + } + value = json_value_init_string_no_copy(copy); + if (value == NULL) { + parson_free(copy); + } + return value; +} + +JSON_VALUE * JsonNewNumber(UINT64 number) { + JSON_VALUE *new_value = NULL; + new_value = (JSON_VALUE*)parson_malloc(sizeof(JSON_VALUE)); + if (new_value == NULL) { + return NULL; + } + new_value->parent = NULL; + new_value->type = JSON_TYPE_NUMBER; + new_value->value.number = number; + return new_value; +} + +JSON_VALUE * JsonNewBool(int boolean) { + JSON_VALUE *new_value = (JSON_VALUE*)parson_malloc(sizeof(JSON_VALUE)); + if (!new_value) { + return NULL; + } + new_value->parent = NULL; + new_value->type = JSON_TYPE_BOOL; + new_value->value.boolean = boolean ? 1 : 0; + return new_value; +} + +JSON_VALUE * JsonNewNull(void) { + JSON_VALUE *new_value = (JSON_VALUE*)parson_malloc(sizeof(JSON_VALUE)); + if (!new_value) { + return NULL; + } + new_value->parent = NULL; + new_value->type = JSON_TYPE_NULL; + return new_value; +} + +JSON_VALUE * JsonDeepCopy(JSON_VALUE *value) { + UINT i = 0; + JSON_VALUE *return_value = NULL, *temp_value_copy = NULL, *temp_value = NULL; + char *temp_string = NULL, *temp_key = NULL; + char *temp_string_copy = NULL; + JSON_ARRAY *temp_array = NULL, *temp_array_copy = NULL; + JSON_OBJECT *temp_object = NULL, *temp_object_copy = NULL; + + switch (JsonValueGetType(value)) { + case JSON_TYPE_ARRAY: + temp_array = JsonValueGetArray(value); + return_value = JsonNewArray(); + if (return_value == NULL) { + return NULL; + } + temp_array_copy = JsonValueGetArray(return_value); + for (i = 0; i < JsonArrayGetCount(temp_array); i++) { + temp_value = JsonArrayGet(temp_array, i); + temp_value_copy = JsonDeepCopy(temp_value); + if (temp_value_copy == NULL) { + JsonFree(return_value); + return NULL; + } + if (json_array_add(temp_array_copy, temp_value_copy) == JSON_RET_ERROR) { + JsonFree(return_value); + JsonFree(temp_value_copy); + return NULL; + } + } + return return_value; + case JSON_TYPE_OBJECT: + temp_object = JsonValueGetObject(value); + return_value = JsonNewObject(); + if (return_value == NULL) { + return NULL; + } + temp_object_copy = JsonValueGetObject(return_value); + for (i = 0; i < JsonGetCount(temp_object); i++) { + temp_key = JsonGetName(temp_object, i); + temp_value = JsonGet(temp_object, temp_key); + temp_value_copy = JsonDeepCopy(temp_value); + if (temp_value_copy == NULL) { + JsonFree(return_value); + return NULL; + } + if (json_object_add(temp_object_copy, temp_key, temp_value_copy) == JSON_RET_ERROR) { + JsonFree(return_value); + JsonFree(temp_value_copy); + return NULL; + } + } + return return_value; + case JSON_TYPE_BOOL: + return JsonNewBool(JsonValueGetBool(value)); + case JSON_TYPE_NUMBER: + return JsonNewNumber(JsonValueGetNumber(value)); + case JSON_TYPE_STRING: + temp_string = JsonValueGetStr(value); + if (temp_string == NULL) { + return NULL; + } + temp_string_copy = parson_strdup(temp_string); + if (temp_string_copy == NULL) { + return NULL; + } + return_value = json_value_init_string_no_copy(temp_string_copy); + if (return_value == NULL) { + parson_free(temp_string_copy); + } + return return_value; + case JSON_TYPE_NULL: + return JsonNewNull(); + case JSON_TYPE_ERROR: + return NULL; + default: + return NULL; + } +} + +UINT JsonGetSerializationSize(JSON_VALUE *value) { + char num_buf[1100]; /* recursively allocating buffer on stack is a bad idea, so let's do it only once */ + int res = json_serialize_to_buffer_r(value, NULL, 0, 0, num_buf); + return res < 0 ? 0 : (UINT)(res + 1); +} + +UINT JsonSerializeToBuffer(JSON_VALUE *value, char *buf, UINT buf_size_in_bytes) { + int written = -1; + UINT needed_size_in_bytes = JsonGetSerializationSize(value); + if (needed_size_in_bytes == 0 || buf_size_in_bytes < needed_size_in_bytes) { + return JSON_RET_ERROR; + } + written = json_serialize_to_buffer_r(value, buf, 0, 0, NULL); + if (written < 0) { + return JSON_RET_ERROR; + } + return JSON_RET_OK; +} + +char * JsonSerializeToString(JSON_VALUE *value) { + UINT serialization_result = JSON_RET_ERROR; + UINT buf_size_bytes = JsonGetSerializationSize(value); + char *buf = NULL; + if (buf_size_bytes == 0) { + return NULL; + } + buf = (char*)parson_malloc(buf_size_bytes); + if (buf == NULL) { + return NULL; + } + serialization_result = JsonSerializeToBuffer(value, buf, buf_size_bytes); + if (serialization_result == JSON_RET_ERROR) { + JsonFreeString(buf); + return NULL; + } + return buf; +} + +UINT JsonGetSerializationSizePretty(JSON_VALUE *value) { + char num_buf[1100]; /* recursively allocating buffer on stack is a bad idea, so let's do it only once */ + int res = json_serialize_to_buffer_r(value, NULL, 0, 1, num_buf); + return res < 0 ? 0 : (UINT)(res + 1); +} + +UINT JsonSerializeToBufferPretty(JSON_VALUE *value, char *buf, UINT buf_size_in_bytes) { + int written = -1; + UINT needed_size_in_bytes = JsonGetSerializationSizePretty(value); + if (needed_size_in_bytes == 0 || buf_size_in_bytes < needed_size_in_bytes) { + return JSON_RET_ERROR; + } + written = json_serialize_to_buffer_r(value, buf, 0, 1, NULL); + if (written < 0) { + return JSON_RET_ERROR; + } + return JSON_RET_OK; +} + +JSON_VALUE *StrToJson(char *str) +{ + if (str == NULL) + { + return NULL; + } + + return JsonParseString(str); +} + +char *JsonToStr(JSON_VALUE *v) +{ + return JsonSerializeToStringPretty(v); +} +char * JsonSerializeToStringPretty(JSON_VALUE *value) { + UINT serialization_result = JSON_RET_ERROR; + UINT buf_size_bytes = JsonGetSerializationSizePretty(value); + char *buf = NULL; + if (buf_size_bytes == 0) { + return NULL; + } + buf = (char*)parson_malloc(buf_size_bytes); + if (buf == NULL) { + return NULL; + } + serialization_result = JsonSerializeToBufferPretty(value, buf, buf_size_bytes); + if (serialization_result == JSON_RET_ERROR) { + JsonFreeString(buf); + return NULL; + } + return buf; +} + +void JsonFreeString(char *string) { + parson_free(string); +} + +UINT JsonArrayDelete(JSON_ARRAY *array, UINT ix) { + UINT to_move_bytes = 0; + if (array == NULL || ix >= JsonArrayGetCount(array)) { + return JSON_RET_ERROR; + } + JsonFree(JsonArrayGet(array, ix)); + to_move_bytes = (JsonArrayGetCount(array) - 1 - ix) * sizeof(JSON_VALUE*); + memmove(array->items + ix, array->items + ix + 1, to_move_bytes); + array->count -= 1; + return JSON_RET_OK; +} + +UINT JsonArrayReplace(JSON_ARRAY *array, UINT ix, JSON_VALUE *value) { + if (array == NULL || value == NULL || value->parent != NULL || ix >= JsonArrayGetCount(array)) { + return JSON_RET_ERROR; + } + JsonFree(JsonArrayGet(array, ix)); + value->parent = JsonArrayGetWrappingValue(array); + array->items[ix] = value; + return JSON_RET_OK; +} + +UINT JsonArrayReplaceStr(JSON_ARRAY *array, UINT i, char* string) { + JSON_VALUE *value = JsonNewStr(string); + if (value == NULL) { + return JSON_RET_ERROR; + } + if (JsonArrayReplace(array, i, value) == JSON_RET_ERROR) { + JsonFree(value); + return JSON_RET_ERROR; + } + return JSON_RET_OK; +} + +UINT JsonArrayReplaceNumber(JSON_ARRAY *array, UINT i, UINT64 number) { + JSON_VALUE *value = JsonNewNumber(number); + if (value == NULL) { + return JSON_RET_ERROR; + } + if (JsonArrayReplace(array, i, value) == JSON_RET_ERROR) { + JsonFree(value); + return JSON_RET_ERROR; + } + return JSON_RET_OK; +} + +UINT JsonArrayReplaceBool(JSON_ARRAY *array, UINT i, int boolean) { + JSON_VALUE *value = JsonNewBool(boolean); + if (value == NULL) { + return JSON_RET_ERROR; + } + if (JsonArrayReplace(array, i, value) == JSON_RET_ERROR) { + JsonFree(value); + return JSON_RET_ERROR; + } + return JSON_RET_OK; +} + +UINT JsonArrayReplaceNull(JSON_ARRAY *array, UINT i) { + JSON_VALUE *value = JsonNewNull(); + if (value == NULL) { + return JSON_RET_ERROR; + } + if (JsonArrayReplace(array, i, value) == JSON_RET_ERROR) { + JsonFree(value); + return JSON_RET_ERROR; + } + return JSON_RET_OK; +} + +UINT JsonArrayDeleteAll(JSON_ARRAY *array) { + UINT i = 0; + if (array == NULL) { + return JSON_RET_ERROR; + } + for (i = 0; i < JsonArrayGetCount(array); i++) { + JsonFree(JsonArrayGet(array, i)); + } + array->count = 0; + return JSON_RET_OK; +} + +UINT JsonArrayAdd(JSON_ARRAY *array, JSON_VALUE *value) { + if (array == NULL || value == NULL || value->parent != NULL) { + return JSON_RET_ERROR; + } + return json_array_add(array, value); +} + +UINT JsonArrayAddStr(JSON_ARRAY *array, char *string) { + JSON_VALUE *value = JsonNewStr(string); + if (value == NULL) { + return JSON_RET_ERROR; + } + if (JsonArrayAdd(array, value) == JSON_RET_ERROR) { + JsonFree(value); + return JSON_RET_ERROR; + } + return JSON_RET_OK; +} + +UINT JsonArrayAddUniStr(JSON_ARRAY *array, wchar_t *string) +{ + UINT ret; + char *utf8 = CopyUniToUtf(string); + + ret = JsonArrayAddStr(array, utf8); + + Free(utf8); + return ret; +} + +UINT JsonArrayAddNumber(JSON_ARRAY *array, UINT64 number) { + JSON_VALUE *value = JsonNewNumber(number); + if (value == NULL) { + return JSON_RET_ERROR; + } + if (JsonArrayAdd(array, value) == JSON_RET_ERROR) { + JsonFree(value); + return JSON_RET_ERROR; + } + return JSON_RET_OK; +} + +UINT JsonArrayAddData(JSON_ARRAY *array, void *data, UINT size) +{ + UINT ret; + char *b64 = ZeroMalloc(size * 4 + 32); + B64_Encode(b64, data, size); + + ret = JsonArrayAddStr(array, b64); + + Free(b64); + return ret; +} + +UINT JsonArrayAddBool(JSON_ARRAY *array, int boolean) { + JSON_VALUE *value = JsonNewBool(boolean); + if (value == NULL) { + return JSON_RET_ERROR; + } + if (JsonArrayAdd(array, value) == JSON_RET_ERROR) { + JsonFree(value); + return JSON_RET_ERROR; + } + return JSON_RET_OK; +} + +UINT JsonArrayAddNull(JSON_ARRAY *array) { + JSON_VALUE *value = JsonNewNull(); + if (value == NULL) { + return JSON_RET_ERROR; + } + if (JsonArrayAdd(array, value) == JSON_RET_ERROR) { + JsonFree(value); + return JSON_RET_ERROR; + } + return JSON_RET_OK; +} + +UINT JsonSet(JSON_OBJECT *object, char *name, JSON_VALUE *value) { + UINT i = 0; + JSON_VALUE *old_value; + if (object == NULL || name == NULL || value == NULL || value->parent != NULL) { + return JSON_RET_ERROR; + } + old_value = JsonGet(object, name); + if (old_value != NULL) { /* free and overwrite old value */ + JsonFree(old_value); + for (i = 0; i < JsonGetCount(object); i++) { + if (strcmp(object->names[i], name) == 0) { + value->parent = JsonGetWrappingValue(object); + object->values[i] = value; + return JSON_RET_OK; + } + } + } + /* add new key value pair */ + return json_object_add(object, name, value); +} + +UINT JsonSetData(JSON_OBJECT *object, char *name, void *data, UINT size) +{ + UINT ret; + char *b64 = ZeroMalloc(size * 4 + 32); + B64_Encode(b64, data, size); + + ret = JsonSetStr(object, name, b64); + + Free(b64); + return ret; +} + +UINT JsonSetStr(JSON_OBJECT *object, char *name, char *string) { + return JsonSet(object, name, JsonNewStr(string)); +} + +UINT JsonSetUniStr(JSON_OBJECT *object, char *name, wchar_t *string) +{ + UINT ret; + char *utf8 = CopyUniToUtf(string); + + ret = JsonSetStr(object, name, utf8); + + Free(utf8); + return ret; +} + +UINT JsonSetNumber(JSON_OBJECT *object, char *name, UINT64 number) { + return JsonSet(object, name, JsonNewNumber(number)); +} + +UINT JsonSetBool(JSON_OBJECT *object, char *name, int boolean) { + return JsonSet(object, name, JsonNewBool(boolean)); +} + +UINT JsonSetNull(JSON_OBJECT *object, char *name) { + return JsonSet(object, name, JsonNewNull()); +} + +UINT JsonDotSet(JSON_OBJECT *object, char *name, JSON_VALUE *value) { + char *dot_pos = NULL; + char *current_name = NULL; + JSON_OBJECT *temp_obj = NULL; + JSON_VALUE *new_value = NULL; + if (object == NULL || name == NULL || value == NULL) { + return JSON_RET_ERROR; + } + dot_pos = strchr(name, '.'); + if (dot_pos == NULL) { + return JsonSet(object, name, value); + } + else { + current_name = parson_strndup(name, (UINT)(dot_pos - name)); + temp_obj = JsonGetObj(object, current_name); + if (temp_obj == NULL) { + new_value = JsonNewObject(); + if (new_value == NULL) { + parson_free(current_name); + return JSON_RET_ERROR; + } + if (json_object_add(object, current_name, new_value) == JSON_RET_ERROR) { + JsonFree(new_value); + parson_free(current_name); + return JSON_RET_ERROR; + } + temp_obj = JsonGetObj(object, current_name); + } + parson_free(current_name); + return JsonDotSet(temp_obj, dot_pos + 1, value); + } +} + +UINT JsonDotSetStr(JSON_OBJECT *object, char *name, char *string) { + JSON_VALUE *value = JsonNewStr(string); + if (value == NULL) { + return JSON_RET_ERROR; + } + if (JsonDotSet(object, name, value) == JSON_RET_ERROR) { + JsonFree(value); + return JSON_RET_ERROR; + } + return JSON_RET_OK; +} + +UINT JsonDotSetNumber(JSON_OBJECT *object, char *name, UINT64 number) { + JSON_VALUE *value = JsonNewNumber(number); + if (value == NULL) { + return JSON_RET_ERROR; + } + if (JsonDotSet(object, name, value) == JSON_RET_ERROR) { + JsonFree(value); + return JSON_RET_ERROR; + } + return JSON_RET_OK; +} + +UINT JsonDotSetBool(JSON_OBJECT *object, char *name, int boolean) { + JSON_VALUE *value = JsonNewBool(boolean); + if (value == NULL) { + return JSON_RET_ERROR; + } + if (JsonDotSet(object, name, value) == JSON_RET_ERROR) { + JsonFree(value); + return JSON_RET_ERROR; + } + return JSON_RET_OK; +} + +UINT JsonDotSetNull(JSON_OBJECT *object, char *name) { + JSON_VALUE *value = JsonNewNull(); + if (value == NULL) { + return JSON_RET_ERROR; + } + if (JsonDotSet(object, name, value) == JSON_RET_ERROR) { + JsonFree(value); + return JSON_RET_ERROR; + } + return JSON_RET_OK; +} + +UINT JsonDelete(JSON_OBJECT *object, char *name) { + UINT i = 0, last_item_index = 0; + if (object == NULL || JsonGet(object, name) == NULL) { + return JSON_RET_ERROR; + } + last_item_index = JsonGetCount(object) - 1; + for (i = 0; i < JsonGetCount(object); i++) { + if (strcmp(object->names[i], name) == 0) { + parson_free(object->names[i]); + JsonFree(object->values[i]); + if (i != last_item_index) { /* Replace key value pair with one from the end */ + object->names[i] = object->names[last_item_index]; + object->values[i] = object->values[last_item_index]; + } + object->count -= 1; + return JSON_RET_OK; + } + } + return JSON_RET_ERROR; /* No execution path should end here */ +} + +UINT JsonDotDelete(JSON_OBJECT *object, char *name) { + char *dot_pos = strchr(name, '.'); + char *current_name = NULL; + JSON_OBJECT *temp_obj = NULL; + if (dot_pos == NULL) { + return JsonDelete(object, name); + } + else { + current_name = parson_strndup(name, (UINT)(dot_pos - name)); + temp_obj = JsonGetObj(object, current_name); + parson_free(current_name); + if (temp_obj == NULL) { + return JSON_RET_ERROR; + } + return JsonDotDelete(temp_obj, dot_pos + 1); + } +} + +UINT JsonDeleteAll(JSON_OBJECT *object) { + UINT i = 0; + if (object == NULL) { + return JSON_RET_ERROR; + } + for (i = 0; i < JsonGetCount(object); i++) { + parson_free(object->names[i]); + JsonFree(object->values[i]); + } + object->count = 0; + return JSON_RET_OK; +} + +UINT JsonValidate(JSON_VALUE *schema, JSON_VALUE *value) { + JSON_VALUE *temp_schema_value = NULL, *temp_value = NULL; + JSON_ARRAY *schema_array = NULL, *value_array = NULL; + JSON_OBJECT *schema_object = NULL, *value_object = NULL; + UINT schema_type = JSON_TYPE_ERROR, value_type = JSON_TYPE_ERROR; + char *key = NULL; + UINT i = 0, count = 0; + if (schema == NULL || value == NULL) { + return JSON_RET_ERROR; + } + schema_type = JsonValueGetType(schema); + value_type = JsonValueGetType(value); + if (schema_type != value_type && schema_type != JSON_TYPE_NULL) { /* null represents all values */ + return JSON_RET_ERROR; + } + switch (schema_type) { + case JSON_TYPE_ARRAY: + schema_array = JsonValueGetArray(schema); + value_array = JsonValueGetArray(value); + count = JsonArrayGetCount(schema_array); + if (count == 0) { + return JSON_RET_OK; /* Empty array allows all types */ + } + /* Get first value from array, rest is ignored */ + temp_schema_value = JsonArrayGet(schema_array, 0); + for (i = 0; i < JsonArrayGetCount(value_array); i++) { + temp_value = JsonArrayGet(value_array, i); + if (JsonValidate(temp_schema_value, temp_value) == JSON_RET_ERROR) { + return JSON_RET_ERROR; + } + } + return JSON_RET_OK; + case JSON_TYPE_OBJECT: + schema_object = JsonValueGetObject(schema); + value_object = JsonValueGetObject(value); + count = JsonGetCount(schema_object); + if (count == 0) { + return JSON_RET_OK; /* Empty object allows all objects */ + } + else if (JsonGetCount(value_object) < count) { + return JSON_RET_ERROR; /* Tested object mustn't have less name-value pairs than schema */ + } + for (i = 0; i < count; i++) { + key = JsonGetName(schema_object, i); + temp_schema_value = JsonGet(schema_object, key); + temp_value = JsonGet(value_object, key); + if (temp_value == NULL) { + return JSON_RET_ERROR; + } + if (JsonValidate(temp_schema_value, temp_value) == JSON_RET_ERROR) { + return JSON_RET_ERROR; + } + } + return JSON_RET_OK; + case JSON_TYPE_STRING: case JSON_TYPE_NUMBER: case JSON_TYPE_BOOL: case JSON_TYPE_NULL: + return JSON_RET_OK; /* equality already tested before switch */ + case JSON_TYPE_ERROR: default: + return JSON_RET_ERROR; + } +} + +int JsonCmp(JSON_VALUE *a, JSON_VALUE *b) { + JSON_OBJECT *a_object = NULL, *b_object = NULL; + JSON_ARRAY *a_array = NULL, *b_array = NULL; + char *a_string = NULL, *b_string = NULL; + char *key = NULL; + UINT a_count = 0, b_count = 0, i = 0; + UINT a_type, b_type; + UINT64 a_num, b_num; + a_type = JsonValueGetType(a); + b_type = JsonValueGetType(b); + if (a_type != b_type) { + return 0; + } + switch (a_type) { + case JSON_TYPE_ARRAY: + a_array = JsonValueGetArray(a); + b_array = JsonValueGetArray(b); + a_count = JsonArrayGetCount(a_array); + b_count = JsonArrayGetCount(b_array); + if (a_count != b_count) { + return 0; + } + for (i = 0; i < a_count; i++) { + if (!JsonCmp(JsonArrayGet(a_array, i), + JsonArrayGet(b_array, i))) { + return 0; + } + } + return 1; + case JSON_TYPE_OBJECT: + a_object = JsonValueGetObject(a); + b_object = JsonValueGetObject(b); + a_count = JsonGetCount(a_object); + b_count = JsonGetCount(b_object); + if (a_count != b_count) { + return 0; + } + for (i = 0; i < a_count; i++) { + key = JsonGetName(a_object, i); + if (!JsonCmp(JsonGet(a_object, key), + JsonGet(b_object, key))) { + return 0; + } + } + return 1; + case JSON_TYPE_STRING: + a_string = JsonValueGetStr(a); + b_string = JsonValueGetStr(b); + if (a_string == NULL || b_string == NULL) { + return 0; /* shouldn't happen */ + } + return strcmp(a_string, b_string) == 0; + case JSON_TYPE_BOOL: + return JsonValueGetBool(a) == JsonValueGetBool(b); + case JSON_TYPE_NUMBER: + a_num = JsonValueGetNumber(a); + b_num = JsonValueGetNumber(b); + return a_num == b_num; + case JSON_TYPE_ERROR: + return 1; + case JSON_TYPE_NULL: + return 1; + default: + return 1; + } +} + +UINT JsonType(JSON_VALUE *value) { + return JsonValueGetType(value); +} + +JSON_OBJECT * JsonObject(JSON_VALUE *value) { + return JsonValueGetObject(value); +} + +JSON_ARRAY * JsonArray(JSON_VALUE *value) { + return JsonValueGetArray(value); +} + +char * JsonString(JSON_VALUE *value) { + return JsonValueGetStr(value); +} + +UINT64 JsonNumber(JSON_VALUE *value) { + return JsonValueGetNumber(value); +} + +int JsonBool(JSON_VALUE *value) { + return JsonValueGetBool(value); +} + +void JsonSetAllocationFunctions(JSON_Malloc_Function malloc_fun, JSON_Free_Function free_fun) { + parson_malloc = malloc_fun; + parson_free = free_fun; +} + +// SYSTEMTIME to JSON string +void SystemTimeToJsonStr(char *dst, UINT size, SYSTEMTIME *t) +{ + if (dst == NULL) + { + return; + } + + if (t == NULL) + { + ClearStr(dst, size); + } + else + { + GetDateTimeStrRFC3339(dst, size, t, 0); + } +} + +// UINT64 System Time to JSON string +void SystemTime64ToJsonStr(char *dst, UINT size, UINT64 t) +{ + SYSTEMTIME st; + if (dst == NULL) + { + return; + } + + if (t == 0) + { + ClearStr(dst, size); + } + + UINT64ToSystem(&st, t); + + SystemTimeToJsonStr(dst, size, &st); +} + + + + diff --git a/src/Mayaqua/Str.h b/src/Mayaqua/Str.h index 6a54ece6..c5ce0532 100644 --- a/src/Mayaqua/Str.h +++ b/src/Mayaqua/Str.h @@ -182,7 +182,9 @@ void BinToStrW(wchar_t *str, UINT str_size, void *data, UINT data_size); void PrintBin(void *data, UINT size); bool StartWith(char *str, char *key); bool EndWith(char *str, char *key); +bool TrimEndWith(char *dst, UINT dst_size, char *str, char *key); UINT64 ToInt64(char *str); +UINT64 Json_ToInt64Ex(char *str, char **endptr, bool *error); void ToStr64(char *str, UINT64 value); char *ReplaceFormatStringFor64(char *fmt); TOKEN_LIST *ParseCmdLine(char *str); @@ -241,6 +243,259 @@ LIST *StrToIntList(char *str, bool sorted); void NormalizeIntListStr(char *dst, UINT dst_size, char *src, bool sorted, char *separate_str); void ClearStr(char *str, UINT str_size); void SetStrCaseAccordingToBits(char *str, UINT bits); +char *UrlDecode(char *url_str); + + +// *** JSON strings support +// Original source code from Parson ( http://kgabis.github.com/parson/ ) +// Modified by dnobori +/* +Parson ( http://kgabis.github.com/parson/ ) +Copyright (c) 2012 - 2017 Krzysztof Gabis + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + + +/* Type definitions */ +typedef union JSON_VALUE_UNION { + char *string; + UINT64 number; + JSON_OBJECT *object; + JSON_ARRAY *array; + int boolean; + int null; +} JSON_VALUE_UNION; + +struct JSON_VALUE { + JSON_VALUE *parent; + UINT type; + JSON_VALUE_UNION value; +}; + +struct JSON_OBJECT { + JSON_VALUE *wrapping_value; + char **names; + JSON_VALUE **values; + UINT count; + UINT capacity; +}; + +struct JSON_ARRAY { + JSON_VALUE *wrapping_value; + JSON_VALUE **items; + UINT count; + UINT capacity; +}; + + +enum JSON_TYPES { + JSON_TYPE_ERROR = -1, + JSON_TYPE_NULL = 1, + JSON_TYPE_STRING = 2, + JSON_TYPE_NUMBER = 3, + JSON_TYPE_OBJECT = 4, + JSON_TYPE_ARRAY = 5, + JSON_TYPE_BOOL = 6 +}; +//typedef unsigned int UINT; + +enum JSON_RETS { + JSON_RET_OK = 0, + JSON_RET_ERROR = -1 +}; + +typedef void * (*JSON_Malloc_Function)(UINT); +typedef void(*JSON_Free_Function)(void *); + +/* Call only once, before calling any other function from parson API. If not called, malloc and free +from stdlib will be used for all allocations */ +void JsonSetAllocationFunctions(JSON_Malloc_Function malloc_fun, JSON_Free_Function free_fun); + +/* Parses first JSON value in a string, returns NULL in case of error */ +JSON_VALUE * JsonParseString(char *string); + +/* Parses first JSON value in a string and ignores comments (/ * * / and //), +returns NULL in case of error */ +JSON_VALUE * JsonParseStringWithComments(char *string); + +/* Serialization */ +UINT JsonGetSerializationSize(JSON_VALUE *value); /* returns 0 on fail */ +UINT JsonSerializeToBuffer(JSON_VALUE *value, char *buf, UINT buf_size_in_bytes); +char * JsonSerializeToString(JSON_VALUE *value); + +/* Pretty serialization */ +UINT JsonGetSerializationSizePretty(JSON_VALUE *value); /* returns 0 on fail */ +UINT JsonSerializeToBufferPretty(JSON_VALUE *value, char *buf, UINT buf_size_in_bytes); +char * JsonSerializeToStringPretty(JSON_VALUE *value); +char *JsonToStr(JSON_VALUE *v); + +void JsonFreeString(char *string); /* frees string from json_serialize_to_string and json_serialize_to_string_pretty */ + + /* Comparing */ +int JsonCmp(JSON_VALUE *a, JSON_VALUE *b); + +/* Validation +This is *NOT* JSON Schema. It validates json by checking if object have identically +named fields with matching types. +For example schema {"name":"", "age":0} will validate +{"name":"Joe", "age":25} and {"name":"Joe", "age":25, "gender":"m"}, +but not {"name":"Joe"} or {"name":"Joe", "age":"Cucumber"}. +In case of arrays, only first value in schema is checked against all values in tested array. +Empty objects ({}) validate all objects, empty arrays ([]) validate all arrays, +null validates values of every type. +*/ +UINT JsonValidate(JSON_VALUE *schema, JSON_VALUE *value); + +/* +* JSON Object +*/ +JSON_VALUE * JsonGet(JSON_OBJECT *object, char *name); +char * JsonGetStr(JSON_OBJECT *object, char *name); +JSON_OBJECT * JsonGetObj(JSON_OBJECT *object, char *name); +JSON_ARRAY * JsonGetArray(JSON_OBJECT *object, char *name); +UINT64 JsonGetNumber(JSON_OBJECT *object, char *name); /* returns 0 on fail */ +bool JsonGetBool(JSON_OBJECT *object, char *name); /* returns 0 on fail */ + + /* dotget functions enable addressing values with dot notation in nested objects, + just like in structs or c++/java/c# objects (e.g. objectA.objectB.value). + Because valid names in JSON can contain dots, some values may be inaccessible + this way. */ +JSON_VALUE * JsonDotGet(JSON_OBJECT *object, char *name); +char * JsonDotGetStr(JSON_OBJECT *object, char *name); +JSON_OBJECT * JsonDotGetObj(JSON_OBJECT *object, char *name); +JSON_ARRAY * JsonDotGetArray(JSON_OBJECT *object, char *name); +UINT64 JsonDotGetNumber(JSON_OBJECT *object, char *name); /* returns 0 on fail */ +bool JsonDotGetBool(JSON_OBJECT *object, char *name); /* returns -1 on fail */ + + /* Functions to get available names */ +UINT JsonGetCount(JSON_OBJECT *object); +char * JsonGetName(JSON_OBJECT *object, UINT index); +JSON_VALUE * JsonGetValueAt(JSON_OBJECT *object, UINT index); +JSON_VALUE * JsonGetWrappingValue(JSON_OBJECT *object); + +/* Functions to check if object has a value with a specific name. Returned value is 1 if object has +* a value and 0 if it doesn't. dothas functions behave exactly like dotget functions. */ +int JsonIsExists(JSON_OBJECT *object, char *name); +int JsonIsExistsWithValueType(JSON_OBJECT *object, char *name, UINT type); + +int JsonDotIsExists(JSON_OBJECT *object, char *name); +int JsonDotIsExistsWithValueType(JSON_OBJECT *object, char *name, UINT type); + +/* Creates new name-value pair or frees and replaces old value with a new one. +* json_object_set_value does not copy passed value so it shouldn't be freed afterwards. */ +UINT JsonSet(JSON_OBJECT *object, char *name, JSON_VALUE *value); +UINT JsonSetStr(JSON_OBJECT *object, char *name, char *string); +UINT JsonSetUniStr(JSON_OBJECT *object, char *name, wchar_t *string); +UINT JsonSetNumber(JSON_OBJECT *object, char *name, UINT64 number); +UINT JsonSetBool(JSON_OBJECT *object, char *name, int boolean); +UINT JsonSetNull(JSON_OBJECT *object, char *name); +UINT JsonSetData(JSON_OBJECT *object, char *name, void *data, UINT size); + +/* Works like dotget functions, but creates whole hierarchy if necessary. +* json_object_dotset_value does not copy passed value so it shouldn't be freed afterwards. */ +UINT JsonDotSet(JSON_OBJECT *object, char *name, JSON_VALUE *value); +UINT JsonDotSetStr(JSON_OBJECT *object, char *name, char *string); +UINT JsonDotSetNumber(JSON_OBJECT *object, char *name, UINT64 number); +UINT JsonDotSetBool(JSON_OBJECT *object, char *name, int boolean); +UINT JsonDotSetNull(JSON_OBJECT *object, char *name); + +/* Frees and removes name-value pair */ +UINT JsonDelete(JSON_OBJECT *object, char *name); + +/* Works like dotget function, but removes name-value pair only on exact match. */ +UINT JsonDotDelete(JSON_OBJECT *object, char *key); + +/* Removes all name-value pairs in object */ +UINT JsonDeleteAll(JSON_OBJECT *object); + +/* +*JSON Array +*/ +JSON_VALUE * JsonArrayGet(JSON_ARRAY *array, UINT index); +char * JsonArrayGetStr(JSON_ARRAY *array, UINT index); +JSON_OBJECT * JsonArrayGetObj(JSON_ARRAY *array, UINT index); +JSON_ARRAY * JsonArrayGetArray(JSON_ARRAY *array, UINT index); +UINT64 JsonArrayGetNumber(JSON_ARRAY *array, UINT index); /* returns 0 on fail */ +bool JsonArrayGetBool(JSON_ARRAY *array, UINT index); /* returns 0 on fail */ +UINT JsonArrayGetCount(JSON_ARRAY *array); +JSON_VALUE * JsonArrayGetWrappingValue(JSON_ARRAY *array); + +/* Frees and removes value at given index, does nothing and returns JSONFailure if index doesn't exist. +* Order of values in array may change during execution. */ +UINT JsonArrayDelete(JSON_ARRAY *array, UINT i); + +/* Frees and removes from array value at given index and replaces it with given one. +* Does nothing and returns JSONFailure if index doesn't exist. +* json_array_replace_value does not copy passed value so it shouldn't be freed afterwards. */ +UINT JsonArrayReplace(JSON_ARRAY *array, UINT i, JSON_VALUE *value); +UINT JsonArrayReplaceStr(JSON_ARRAY *array, UINT i, char* string); +UINT JsonArrayReplaceNumber(JSON_ARRAY *array, UINT i, UINT64 number); +UINT JsonArrayReplaceBool(JSON_ARRAY *array, UINT i, int boolean); +UINT JsonArrayReplaceNull(JSON_ARRAY *array, UINT i); + +/* Frees and removes all values from array */ +UINT JsonArrayDeleteAll(JSON_ARRAY *array); + +/* Appends new value at the end of array. +* json_array_append_value does not copy passed value so it shouldn't be freed afterwards. */ +UINT JsonArrayAdd(JSON_ARRAY *array, JSON_VALUE *value); +UINT JsonArrayAddStr(JSON_ARRAY *array, char *string); +UINT JsonArrayAddUniStr(JSON_ARRAY *array, wchar_t *string); +UINT JsonArrayAddNumber(JSON_ARRAY *array, UINT64 number); +UINT JsonArrayAddData(JSON_ARRAY *array, void *data, UINT size); +UINT JsonArrayAddBool(JSON_ARRAY *array, int boolean); +UINT JsonArrayAddNull(JSON_ARRAY *array); + + +/* +*JSON Value +*/ +JSON_VALUE * JsonNewObject(void); +JSON_VALUE * JsonNewArray(void); +JSON_VALUE * JsonNewStr(char *string); /* copies passed string */ +JSON_VALUE * JsonNewNumber(UINT64 number); +JSON_VALUE * JsonNewBool(int boolean); +JSON_VALUE * JsonNewNull(void); +JSON_VALUE * JsonDeepCopy(JSON_VALUE *value); +void JsonFree(JSON_VALUE *value); + +UINT JsonValueGetType(JSON_VALUE *value); +JSON_OBJECT * JsonValueGetObject(JSON_VALUE *value); +JSON_ARRAY * JsonValueGetArray(JSON_VALUE *value); +char * JsonValueGetStr(JSON_VALUE *value); +UINT64 JsonValueGetNumber(JSON_VALUE *value); +bool JsonValueGetBool(JSON_VALUE *value); +JSON_VALUE * JsonValueGetParent(JSON_VALUE *value); + +/* Same as above, but shorter */ +UINT JsonType(JSON_VALUE *value); +JSON_OBJECT * JsonObject(JSON_VALUE *value); +JSON_ARRAY * JsonArray(JSON_VALUE *value); +char * JsonString(JSON_VALUE *value); +UINT64 JsonNumber(JSON_VALUE *value); +int JsonBool(JSON_VALUE *value); + +void SystemTimeToJsonStr(char *dst, UINT size, SYSTEMTIME *t); +void SystemTime64ToJsonStr(char *dst, UINT size, UINT64 t); + +JSON_VALUE *StrToJson(char *str); #endif // STR_H diff --git a/src/Mayaqua/Table.c b/src/Mayaqua/Table.c index af2a2016..089cba51 100644 --- a/src/Mayaqua/Table.c +++ b/src/Mayaqua/Table.c @@ -936,6 +936,8 @@ TABLE *ParseTableLine(char *line, char *prefix, UINT prefix_size, LIST *replace_ UniReplaceStrEx(tmp, tmp_size, tmp, (wchar_t *)r->name, r->unistr, false); } + Free(unistr); + unistr = CopyUniStr(tmp); Free(tmp); diff --git a/src/Mayaqua/Unix.c b/src/Mayaqua/Unix.c index 54677753..3a5ddf28 100644 --- a/src/Mayaqua/Unix.c +++ b/src/Mayaqua/Unix.c @@ -2508,6 +2508,23 @@ UINT UnixGetUID() return (UINT)getuid(); } +void UnixPrintVpnServerUrlInfo() +{ + IP ip; + + TryGetCurrentAcceptingIPv4Address(&ip); + + Print("\nLet's get started by accessing to the following URL from your PC:\n\n" + "https://%r:%u/\n" + " or\n" + "https://%r/\n\n" + "Note: IP address may vary. Specify your server's IP address.\n" + "A TLS certificate warning will appear because the server uses self signed certificate by default. That is natural. Continue with ignoring the TLS warning." + "\n\n", + &ip, GC_DEFAULT_PORT, &ip + ); +} + // Start the service void UnixStartService(char *name) { @@ -2547,6 +2564,12 @@ void UnixStartService(char *name) UniPrint(_UU("UNIX_SVC_NONROOT")); } + if (StrCmpi(name, "vpnserver") == 0 || StrCmpi(name, "vpnbridge") == 0) + { + // Print the IP address information + UnixPrintVpnServerUrlInfo(); + } + FreeSingleInstance(inst); // Create a child process diff --git a/src/Mayaqua/Unix.h b/src/Mayaqua/Unix.h index 68077739..b8f2351f 100644 --- a/src/Mayaqua/Unix.h +++ b/src/Mayaqua/Unix.h @@ -250,6 +250,7 @@ void UnixDeleteCtlFile(); void UnixStopThread(THREAD *t, void *param); UINT UnixGetUID(); void UnixIgnoreSignalForThread(int sig); +void UnixPrintVpnServerUrlInfo(); bool UnixIsInVmMain(); bool UnixIsInVm(); diff --git a/src/SEVPN.sln b/src/SEVPN.sln index 733a75ba..9b2c87fc 100644 --- a/src/SEVPN.sln +++ b/src/SEVPN.sln @@ -16,7 +16,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "hamcore", "hamcore", "{2349 bin\hamcore\lang.config = bin\hamcore\lang.config bin\hamcore\strtable_cn.stb = bin\hamcore\strtable_cn.stb bin\hamcore\strtable_en.stb = bin\hamcore\strtable_en.stb - bin\hamcore\strtable_ja.stb = bin\hamcore\strtable_ja.stb bin\hamcore\time.htm = bin\hamcore\time.htm bin\hamcore\vpn16.exe = bin\hamcore\vpn16.exe EndProjectSection @@ -92,7 +91,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Cedar", "Cedar\Cedar.vcproj EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Ham", "Ham\Ham.vcproj", "{1ED5782B-1734-4FC6-AA9E-F7181CDBA8A7}" ProjectSection(ProjectDependencies) = postProject - {DB2A0C4F-D685-41DD-91BA-06E9EEA381CF} = {DB2A0C4F-D685-41DD-91BA-06E9EEA381CF} {2928D768-DEC3-40D3-8E51-26E364497C9B} = {2928D768-DEC3-40D3-8E51-26E364497C9B} {384815C3-333C-4CEC-9DCD-B6AB2602EBB9} = {384815C3-333C-4CEC-9DCD-B6AB2602EBB9} EndProjectSection diff --git a/src/See/Packet.c b/src/See/Packet.c index 319cc4df..3cb3de67 100644 --- a/src/See/Packet.c +++ b/src/See/Packet.c @@ -668,6 +668,8 @@ NTSTATUS NPF_IoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) PUINT pStats; ULONG Information = 0; + BOOLEAN check_ok; + IF_LOUD(DbgPrint("NPF: IoControl\n");) IrpSp = IoGetCurrentIrpStackLocation(Irp); @@ -686,22 +688,39 @@ NTSTATUS NPF_IoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) EXIT_FAILURE(0); } - pStats = (PUINT)(Irp->UserBuffer); - - pStats[3] = 0; - pStats[0] = 0; - pStats[1] = 0; - pStats[2] = 0; // Not yet supported - - for(i = 0 ; i < NCpu ; i++) + check_ok = TRUE; + __try { - - pStats[3] += Open->CpuData[i].Accepted; - pStats[0] += Open->CpuData[i].Received; - pStats[1] += Open->CpuData[i].Dropped; - pStats[2] += 0; // Not yet supported + ProbeForWrite(Irp->UserBuffer, IrpSp->Parameters.DeviceIoControl.OutputBufferLength, 1); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + check_ok = FALSE; + } + + if (check_ok == FALSE) + { + EXIT_FAILURE(0); + } + else + { + pStats = (PUINT)(Irp->UserBuffer); + + pStats[3] = 0; + pStats[0] = 0; + pStats[1] = 0; + pStats[2] = 0; // Not yet supported + + for(i = 0 ; i < NCpu ; i++) + { + + pStats[3] += Open->CpuData[i].Accepted; + pStats[0] += Open->CpuData[i].Received; + pStats[1] += Open->CpuData[i].Dropped; + pStats[2] += 0; // Not yet supported + } + EXIT_SUCCESS(4*sizeof(UINT)); } - EXIT_SUCCESS(4*sizeof(UINT)); break; @@ -711,9 +730,26 @@ NTSTATUS NPF_IoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) EXIT_FAILURE(0); } - RtlCopyMemory(Irp->UserBuffer,(Open->ReadEventName.Buffer)+18,26); + check_ok = TRUE; + __try + { + ProbeForWrite(Irp->UserBuffer, IrpSp->Parameters.DeviceIoControl.OutputBufferLength, 1); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + check_ok = FALSE; + } - EXIT_SUCCESS(26); + if (check_ok == FALSE) + { + EXIT_FAILURE(0); + } + else + { + RtlCopyMemory(Irp->UserBuffer,(Open->ReadEventName.Buffer)+18,26); + + EXIT_SUCCESS(26); + } break; diff --git a/src/WARNING.TXT b/src/WARNING.TXT index 01c37e0a..f562dcec 100644 --- a/src/WARNING.TXT +++ b/src/WARNING.TXT @@ -104,6 +104,25 @@ be disabled anytime by setting up so on the VPN-client side. 2. VPN Software +The notes in this section are not specific to SoftEther VPN or VPN Gate, but +apply to general system software. SoftEther VPN Client, SoftEther VPN Server, +SoftEther VPN Bridge, and VPN Gate Relay Service will be installed on your +computer as system services. System services always run in the background. +System services usually do not appear on the computer display. Then your +computer system is booted, system services automatically start in the +background even before you or other users log in. To check whether +PacketiX-related system service is running, check the process list or the +background service list of your OS (called as "Services" in Windows, or +"Daemons" in UNIX.) You can activate, deactivate, start, or stop system +services using the functions of the OS anytime. PacketiX-related GUI tools for +managing system services communicate with these system services. After you +terminate these management GUI tools, PacketiX-related system services will +continue to run in the background. System services consume CPU time, computer +power, memory and disk space. Because system services consume power, your +electricity charges and amount of thermal of your computer increase as result. +In addition, there is a possibility that the mechanical parts of the life of +your computer is reduced. + 2.1. SoftEther VPN Client If you use SoftEther VPN Client on Windows, the Virtual Network Adapter device driver will be installed on Windows. The Virtual Network Adapter is diff --git a/src/bin/hamcore/DriverPackages/See/x64/See_x64.sys b/src/bin/hamcore/DriverPackages/See/x64/See_x64.sys index a68d590812479459c6e19a61ad199ca7140ac279..6377f5953c8ecc4a1687306cff11ca38983183cf 100644 GIT binary patch delta 23487 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 delta 20844 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 CVCI7W diff --git a/src/bin/hamcore/DriverPackages/See/x86/See_x86.sys b/src/bin/hamcore/DriverPackages/See/x86/See_x86.sys index 6c2d01b9deeda0081861b8bb8e5b7487032db112..b98947b913a9a5ea035127d823e6bbda647a4a53 100644 GIT binary patch delta 23997 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 delta 21577 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 p>CCP#1{_ -$CA$ - - ############################################################################### -# The client certificate file (dummy). +# Client certificate and key. # -# In some implementations of OpenVPN Client software -# (for example: OpenVPN Client for iOS), -# a pair of client certificate and private key must be included on the -# configuration file due to the limitation of the client. -# So this sample configuration file has a dummy pair of client certificate -# and private key as follows. +# A pair of client certificate and private key is required in case you want to +# use the certificate authentication. +# +# To enable it, uncomment the lines below. +# Paste your certificate in the block and the key in the one. - -$CERT$ - +; +;-----BEGIN CERTIFICATE----- +; +;-----END CERTIFICATE----- +; - -$KEY$ - +; +;-----BEGIN RSA PRIVATE KEY----- +; +;-----END RSA PRIVATE KEY----- +; diff --git a/src/bin/hamcore/strtable_cn.stb b/src/bin/hamcore/strtable_cn.stb index 2ff1b122..d7cdfa18 100644 --- a/src/bin/hamcore/strtable_cn.stb +++ b/src/bin/hamcore/strtable_cn.stb @@ -157,11 +157,11 @@ ERR_91 无法断开虚拟 3 层交换机会话。要删除会话,请停 ERR_92 具有指定名称的虚拟 3 层交换机已存在。指定一个不同的名称。 ERR_93 找不到指定的虚拟 3 层交换机。 ERR_94 指定的名称无效。检查名称是否有不能使用的字符 -ERR_95 无法添加虚拟 3 层接口。 -ERR_96 无法删除虚拟 3 层接口。 +ERR_95 无法添加虚拟 3 层接口。Please check that the parameters are valid. Also please make sure that the Virtual Layer 3 switch is stopped. Adding or deleting interfaces are unable when the Virtual Layer 3 switch is running. +ERR_96 无法删除虚拟 3 层接口。Please check that the parameters are valid. Also please make sure that the Virtual Layer 3 switch is stopped. Adding or deleting interfaces are unable when the Virtual Layer 3 switch is running. ERR_97 与指定虚拟 3 层交换接口的目标虚拟 HUB 连接的虚拟 3 层接口已在虚拟 3 层交换机中存在。不能在同一个虚拟 3 层交换机中定义超过一个连接到同一个虚拟 HUB 的虚拟 3 层接口。 -ERR_98 无法添加路由表项。 -ERR_99 无法删除路由表项。 +ERR_98 无法添加路由表项。Please check that the parameters are valid. Also please make sure that the Virtual Layer 3 switch is stopped. Adding or deleting routing table entries are unable when the Virtual Layer 3 switch is running. +ERR_99 无法删除路由表项。Please check that the parameters are valid. Also please make sure that the Virtual Layer 3 switch is stopped. Adding or deleting routing table entries are unable when the Virtual Layer 3 switch is running. ERR_100 指定的路由表项已存在。 ERR_101 客户端和服务器的时钟彼此不同步。检查时间设置。 ERR_102 无法启动此虚拟 3 层交换机。 要启动虚拟 3 层交换机,必须在虚拟 3 层交换机定义至少一个虚拟接口。 @@ -1607,6 +1607,7 @@ SM_LICENSE_NUM_BRIDGE 允许并发 Bridge SM_NO_LICENSE_COLUMN 注意: SM_NO_LICENSE 因为没有产品许可证注册,此 VPN Server 通信功能无法运行。 SM_LICENSE_DELETE_MSG 你确定要从 VPN Server 删除选定的许可证吗? +SM_LICENSE_WARNING SoftEther provides Dynamic DNS, NAT Traversal and VPN Azure as academic experiment services. Therefore, there services can be used for free of charge.\r\n\r\nThese services are provided without any warranty. The services may be suspended or discontinued by technical or operational matters. In such occasions, users will not be able to use the services. A user have to understand such risks, and to acknowledge that such risks are borne by a user-self. SoftEther will never be liable to results or damages of use or unable-to-use of the service. SM_SYSLOG_0 禁用系统日志发送功能 SM_SYSLOG_1 经由 Syslog 发送服务器端日志 SM_SYSLOG_2 经由 Syslog 发送服务器端和虚拟 HUB 安全日志 @@ -1802,6 +1803,9 @@ LS_LICENSE_NOT_VPNSERVER 连接 "%S": 许可证错误。VPN Client 尝试连接 LS_LICENSE_NOT_VPNCLUSTER 连接 "%S": 许可证错误。此 VPN Server 上注册的许可证是禁止使用当前群集功能的类型,且一个 VPN Client 已尝试在群集模式下连接。您必须重启 VPN Server。 LS_LICENSE_VIOLATION 连接 "%S": VPN Server 发生违反许可证错误,不接受连接。 LS_LICENSE_VIOLATION_DETECTED 发现许可证违反错误,一个不同的 VPN Server 与此服务端具有相同的服务端ID "%I64u"。可能是在群集中有两个或以上 VPN Server 正在使用相同的许可证。请检查每一个 VPN Server 的许可证信息。 +LS_API_AUTH_OK HTTPS API client "%r:%u" (%S): Administration mode: "%S": The embedded HTTPS web server accepted the successful login. Username: "%S", Method: "%S", Path: "%S" +LS_API_AUTH_ERROR HTTPS API client "%r:%u" (%S): The embedded HTTPS web server refused a login attempt. Username: "%S", Method: "%S", Path: "%S" +LS_API_RPC_CALL HTTPS API client "%r:%u" (%S): The client called a JSON-API. Method: "%S", Returned error code: %u (0 = success), Returned error message: "%s" # (OpenVPN Logs) @@ -1811,6 +1815,9 @@ LO_PREFIX_CHANNEL OpenVPN 会话%u (%r:%u -> %r:%u) 通道 %u: LO_NEW_CHANNEL 已创创建一个新通道。 LO_CHANNEL_ESTABLISHED_NEWKEY 通道已建立。(触发器: Re-key完成。) LO_OPTION_STR_RECV 接收到的选项字符串:"%S" +LO_CLIENT_CERT Client certificate received (subject: CN="%s"), will use certificate authentication. +LO_CLIENT_UNVERIFIED_CERT Client certificate was provided but did not pass verification (error="%S"), will use password authentication. +LO_CLIENT_NO_CERT Client certificate is not provided, will use password authentication. LO_OPTION_STR_SEND 发送选项字符串:"%S" LO_NEW_SESSION 已创建新的会话。协议:%S LO_INITIATE_REKEY re-keying 进程已开始。 @@ -1907,6 +1914,7 @@ LH_AUTH_PASSWORD 密码验证 LH_AUTH_PLAIN_PASSWORD 外部服务器身份验证 LH_AUTH_CERT 证书验证 LH_AUTH_TICKET 票证验证 +LH_AUTH_OPENVPN_CERT OpenVPN certificate authentication LH_AUTH_RADIUS_NOT_SUPPORT 连接 "%S": 用户 "%S" 身份验证方法 RADIUS 或 Active Directory (NT 域),但 VPN Server 是 "%S",因为 RADIUS 或 Active Directory (NT 域)不能使用。连接被拒绝。 LH_AUTH_RADIUS_NOT_SUPPORT_ON_OPEN_SOURCE "%S" 的连接方法: 用户 "%S" 的身份验证方法被指定为 RADIUS 身份验证或 Active Directory 身份验证 (NT 域验证)。然而,这样一个外部用户身份验证功能尚未在 SoftEther VPN 的开源版本上实施。该连接将被拒绝。 LH_AUTH_CERT_NOT_SUPPORT_ON_OPEN_SOURCE "%S" 的连接方法: 用户 "%S" 的身份验证方法被指定为证书认证。然而,证书验证功能尚未在 SoftEther VPN 的开源版本上实施。该连接将被拒绝。 @@ -7013,6 +7021,7 @@ SW_WEB2_TITLE 指定文件夹 SW_UNINSTALLINFO_URL http://selinks.org/ SW_UNINSTALLINFO_PUBLISHER SoftEther VPN Project +SW_KB3033929_REQUIRED In Windows 7 and Windows Server 2008 R2, some SoftEther VPN functions require the Microsoft's Windows Update module KB3033929 installed.\r\n\r\nIf KB3033929 is not installed in your Windows, please install it from Windows Update or Microsoft website before installing SoftEther VPN. SW_COMPONENTS_ABOUT_TAG 关于 %s SW_COMPONENTS_REQUIRE_ADMIN 安装需要管理员权限 @@ -7055,7 +7064,7 @@ SW_INSTALLER_CACHE_IS_NOT_SIGNED 目前已安装 SoftEther VPN Client 的这台 SW_FILE_NOT_FOUNT 没有找到文件 "%s" SW_WEB_FINISHED Web安装工具已创建,并保存为 "%s"。\r\n\r\n请将 ZIP 文件解压缩,并将解压后的文件上传到 Web 服务器,编辑一个HTML文件和一个 inf 文件来适当替换URL。\r\n\r\n部署 Web 安装程序的解释说明在ZIP文件中描述。 -SW_VG_CONFIRM_MSG 您想用 SoftEther VPN 客户端安装并激活 VPN Gate P2P 中继功能的插件吗 ?\r\n\r\n本插件可以规避官方防火墙的限制实现通信的稳定性。同时 VPN Gate 的通信经常会消耗一定的网络带宽。所以不推荐在移动连接上使用 VPN Gate。\r\n\r\n请注意,一些国家和地区有规定禁止加密通信绕过官方防火墙。在这种情况下,请您不要在您的计算机上使用 VPN Gate 功能。VPN Gate 主要在日本使用。VPN Gate 仅仅是一个学术研究项目。VPN Gate 受日本法律管辖。使用此软件和服务期间,请您遵守本国相关的法律法规,这是您自己的责任。您将完全承担使用此软件和服务造成的任何损失和责任,不管在日本境内还是境外。 +SW_VG_CONFIRM_MSG Do you really want to install and activate the VPN Gate P2P Relay Function plug-in module with SoftEther VPN Client?\r\n\r\nThis plug-in will realize the stability of communication to bypass the government censorship firewall. However, the communication of VPN Gate usually consumes some network bandwidth. VPN Gate is not recommended to be used in the mobile connections. \r\n\r\nPlease note that there are some countries and regions which have the regulation to forbid the encrypted communications to bypass government censorship firewalls. In such a case, you must not use the VPN Gate functions on your computer. VPN Gate is intended to be used mainly in Japan. VPN Gate is a research project for just academic purpose only. VPN Gate is governed under the Japanese laws. Other countries' laws are none of our concerns nor responsibilities. By using this software and service, you must observe all concerned laws and rules with your own responsibility. You will be completely liable to any damages and responsibilities which are results of using this software and service, regardless of either inside or outside of Japan's territory.\r\n\r\nVPN Gate Relay Service will be installed on your computer as system services. System services always run in the background. After you terminate these management GUI tools, this system service will continue to run in the background. System services consume CPU time, computer power, memory and disk space. diff --git a/src/bin/hamcore/strtable_en.stb b/src/bin/hamcore/strtable_en.stb index 14c440b1..eb1f303c 100644 --- a/src/bin/hamcore/strtable_en.stb +++ b/src/bin/hamcore/strtable_en.stb @@ -157,11 +157,11 @@ ERR_91 Unable to disconnect the Virtual Layer 3 Switch session. To delete th ERR_92 A Virtual Layer 3 Switch with the specified name already exists. Specify a different name. ERR_93 Specified Virtual Layer 3 Switch not found. ERR_94 The specified name is invalid. Check if the name contains characters that cannot be used. -ERR_95 Failed to add the Virtual Layer 3 interface. -ERR_96 Failed to delete the Virtual Layer 3 interface. +ERR_95 Failed to add the Virtual Layer 3 interface. Please check that the parameters are valid. Also please make sure that the Virtual Layer 3 switch is stopped. Adding or deleting interfaces are unable when the Virtual Layer 3 switch is running. +ERR_96 Failed to delete the Virtual Layer 3 interface. Please check that the parameters are valid. Also please make sure that the Virtual Layer 3 switch is stopped. Adding or deleting interfaces are unable when the Virtual Layer 3 switch is running. ERR_97 The Virtual Layer 3 interface that is connecting to the destination Virtual Hub of the specified Virtual Layer 3 interface already exists in the Virtual Layer 3 Switch. No more than one Virtual Layer 3 interface that connects to the same Virtual Hub can be defined in a Virtual Layer 3 Switch. -ERR_98 Failed to add routing table entry. -ERR_99 Failed to delete routing table entry. +ERR_98 Failed to add routing table entry. Please check that the parameters are valid. Also please make sure that the Virtual Layer 3 switch is stopped. Adding or deleting routing table entries are unable when the Virtual Layer 3 switch is running. +ERR_99 Failed to delete routing table entry. Please check that the parameters are valid. Also please make sure that the Virtual Layer 3 switch is stopped. Adding or deleting routing table entries are unable when the Virtual Layer 3 switch is running. ERR_100 The specified routing table entry already exists. ERR_101 The client clock and the server clock are not synchronized with each other. Check the time settings. ERR_102 Unable to start this Virtual Layer 3 Switch. \r\n\r\nTo start the Virtual Layer 3 Switch, at least 1 virtual interface must be defined in the Virtual Layer 3 Switch. @@ -1594,6 +1594,7 @@ SM_LICENSE_NUM_BRIDGE Allowed Concurrent Bridges SM_NO_LICENSE_COLUMN Caution: SM_NO_LICENSE Because there are no product licenses registered, this VPN Server's communication function doesn't operate. SM_LICENSE_DELETE_MSG Are you sure you want to delete the selected license from the VPN Server? +SM_LICENSE_WARNING SoftEther provides Dynamic DNS, NAT Traversal and VPN Azure as academic experiment services. Therefore, there services can be used for free of charge.\r\n\r\nThese services are provided without any warranty. The services may be suspended or discontinued by technical or operational matters. In such occasions, users will not be able to use the services. A user have to understand such risks, and to acknowledge that such risks are borne by a user-self. SoftEther will never be liable to results or damages of use or unable-to-use of the service. SM_SYSLOG_0 Disable Syslog Send Function SM_SYSLOG_1 Send Server Logs by Syslog SM_SYSLOG_2 Send Server and Virtual Hub Security Logs by Syslog @@ -1784,6 +1785,9 @@ LS_LICENSE_NOT_VPNSERVER Connection "%S": License error occurred. The VPN Client LS_LICENSE_NOT_VPNCLUSTER Connection "%S": License error occurred. The license registered on this VPN Server is of a type that prevents the use of the current clustering function and a VPN Client has attempted connection while operating in Cluster mode. You must restart the VPN Server. LS_LICENSE_VIOLATION Connection "%S": A license violation has occurred on the VPN Server and connections are not being received. LS_LICENSE_VIOLATION_DETECTED A license violation has been detected. A different VPN Server is operating with the same server ID "%I64u" as this VPN Server. It is possible that there are two or more VPN Servers in the cluster that are using the same license. Check the license information of each VPN Server. +LS_API_AUTH_OK HTTPS API client "%r:%u" (%S): Administration mode: "%S": The embedded HTTPS web server accepted the successful login. Username: "%S", Method: "%S", Path: "%S" +LS_API_AUTH_ERROR HTTPS API client "%r:%u" (%S): The embedded HTTPS web server refused a login attempt. Username: "%S", Method: "%S", Path: "%S" +LS_API_RPC_CALL HTTPS API client "%r:%u" (%S): The client called a JSON-API. Method: "%S", Returned error code: %u (0 = success), Returned error message: "%s" # (OpenVPN Logs) @@ -1793,6 +1797,9 @@ LO_PREFIX_CHANNEL OpenVPN Session %u (%r:%u -> %r:%u) Channel %u: LO_NEW_CHANNEL A new channel is created. LO_CHANNEL_ESTABLISHED_NEWKEY The channel is established. (Trigger: Re-key completion.) LO_OPTION_STR_RECV Option Strings Received: "%S" +LO_CLIENT_CERT Client certificate received (subject: CN="%s"), will use certificate authentication. +LO_CLIENT_UNVERIFIED_CERT Client certificate was provided but did not pass verification (error="%S"), will use password authentication. +LO_CLIENT_NO_CERT Client certificate is not provided, will use password authentication. LO_OPTION_STR_SEND Option Strings to Send: "%S" LO_NEW_SESSION A new session is created. Protocol: %S LO_INITIATE_REKEY The re-keying process is started. @@ -1889,6 +1896,7 @@ LH_AUTH_PASSWORD Password authentication LH_AUTH_PLAIN_PASSWORD External server authentication LH_AUTH_CERT Certificate authentication LH_AUTH_TICKET Ticket authentication +LH_AUTH_OPENVPN_CERT OpenVPN certificate authentication LH_AUTH_RADIUS_NOT_SUPPORT Connection "%S": The authentication method of the user "%S" has been specified as RADIUS Authentication or Active Directory Authentication (NT Domain Authentication). However, the edition of the VPN Server is "%S". This edition does not support RADIUS Authentication nor Active Directory Authentication (NT Domain Authentication). The connection will be denied. LH_AUTH_RADIUS_NOT_SUPPORT_ON_OPEN_SOURCE Connection "%S": The authentication method of the user "%S" has been specified as RADIUS Authentication or Active Directory Authentication (NT Domain Authentication). However, such an external user-authentication function hasn't been implemented on the Open-Source version of SoftEther VPN yet. The connection will be denied. LH_AUTH_CERT_NOT_SUPPORT_ON_OPEN_SOURCE Connection "%S": The authentication method of the user "%S" has been specified as Certificate Authentication. However, the Certificate Authentication function hasn't been implemented on the Open-Source version of SoftEther VPN yet. The connection will be denied. @@ -5697,7 +5705,7 @@ CMD_UserRadiusSet_Prompt_ALIAS Alias Name for Authentication (Optional): # UserNTLMSet コマンド CMD_UserNTLMSet Set NT Domain Authentication for User Auth Type -CMD_UserNTLMSet_Help Use this to set NT Domain Authentication as the auth type for a user that is registered on the security account database of the currently managed Virtual Hub. When a user connects to a Virtual Hub using a user name that is set for NT Domain authentication, the user name and the user input password is sent to the Windows NT / 2000 / Server 2003 / Server 2008 / Server 2008 R2 / Server 2012 Domain Controller or Active Directory Server where the server checks the user name and password, then if the verification is successful, that user is allowed VPN connection. \nTo use NT Domain authentication, the VPN Server must be operating on a Windows NT 4.0, Windows 2000, Windows XP, Windows Vista, Windows Server 2008, Windows Server 2008 R2 or Windows Server 2012 operating system that is connected to that domain. For details please contact the VPN Server's administrator. \nTo get the list of currently registered users, use the UserList command. \nThis command cannot be run on VPN Bridge. \nYou cannot execute this command for Virtual Hubs of VPN Servers operating as a member server on a cluster. +CMD_UserNTLMSet_Help Use this to set NT Domain Authentication as the auth type for a user that is registered on the security account database of the currently managed Virtual Hub. When a user connects to a Virtual Hub using a user name that is set for NT Domain authentication, the user name and the user input password is sent to the Windows NT / 2000 / Server 2003 / Server 2008 / Server 2008 R2 / Server 2012 / Server 2012 R2 / Server 2016 / Server 2019 Domain Controller or Active Directory Server where the server checks the user name and password, then if the verification is successful, that user is allowed VPN connection. \nTo use NT Domain authentication, the VPN Server must be operating on a Windows operating system that is connected to that domain. For details please contact the VPN Server's administrator. \nTo get the list of currently registered users, use the UserList command. \nThis command cannot be run on VPN Bridge. \nYou cannot execute this command for Virtual Hubs of VPN Servers operating as a member server on a cluster. CMD_UserNTLMSet_Args UserNTLMSet [name] [/ALIAS:alias_name] CMD_UserNTLMSet_[name] Specify the user name of the user whose setting you want to change. CMD_UserNTLMSet_ALIAS When this parameter is set, it is possible to make the user name sent to the NT Domain or Active Directory server different to the user name on the Virtual Hub. When this is not set, please specify /ALIAS:none (the user name on the Virtual Hub will be used). If the user name is "*", the /ALIAS parameter will be ignored. To read an explanation of the "*" user, please input UserCreate/HELP to display this information. @@ -7006,6 +7014,8 @@ SW_WEB2_TITLE Specify Files SW_UNINSTALLINFO_URL http://selinks.org/ SW_UNINSTALLINFO_PUBLISHER SoftEther VPN Project +SW_KB3033929_REQUIRED In Windows 7 and Windows Server 2008 R2, some SoftEther VPN functions require the Microsoft's Windows Update module KB3033929 installed.\r\n\r\nIf KB3033929 is not installed in your Windows, please install it from Windows Update or Microsoft website before installing SoftEther VPN. + SW_COMPONENTS_ABOUT_TAG About %s SW_COMPONENTS_REQUIRE_ADMIN Installation Requires Administrators Privileges @@ -7048,7 +7058,7 @@ SW_INSTALLER_CACHE_IS_NOT_SIGNED The currently installed SoftEther VPN Client SW_FILE_NOT_FOUNT The file "%s" not found. SW_WEB_FINISHED The Web Installer is created and saved as "%s".\r\n\r\nPlease extract inner files from the ZIP file, upload them into the Web server, and edit a HTML file and an inf file to replace URLs appropriately.\r\n\r\nThe explanation to deploy the Web Installer is described on the ZIP file. -SW_VG_CONFIRM_MSG Do you really want to install and activate the VPN Gate P2P Relay Function plug-in module with SoftEther VPN Client?\r\n\r\nThis plug-in will realize the stability of communication to bypass the government censorship firewall. However, the communication of VPN Gate usually consumes some network bandwidth. VPN Gate is not recommended to be used in the mobile connections. \r\n\r\nPlease note that there are some countries and regions which have the regulation to forbid the encrypted communications to bypass government censorship firewalls. In such a case, you must not use the VPN Gate functions on your computer. VPN Gate is intended to be used mainly in Japan. VPN Gate is a research project for just academic purpose only. VPN Gate is governed under the Japanese laws. Other countries' laws are none of our concerns nor responsibilities. By using this software and service, you must observe all concerned laws and rules with your own responsibility. You will be completely liable to any damages and responsibilities which are results of using this software and service, regardless of either inside or outside of Japan's territory. +SW_VG_CONFIRM_MSG Do you really want to install and activate the VPN Gate P2P Relay Function plug-in module with SoftEther VPN Client?\r\n\r\nThis plug-in will realize the stability of communication to bypass the government censorship firewall. However, the communication of VPN Gate usually consumes some network bandwidth. VPN Gate is not recommended to be used in the mobile connections. \r\n\r\nPlease note that there are some countries and regions which have the regulation to forbid the encrypted communications to bypass government censorship firewalls. In such a case, you must not use the VPN Gate functions on your computer. VPN Gate is intended to be used mainly in Japan. VPN Gate is a research project for just academic purpose only. VPN Gate is governed under the Japanese laws. Other countries' laws are none of our concerns nor responsibilities. By using this software and service, you must observe all concerned laws and rules with your own responsibility. You will be completely liable to any damages and responsibilities which are results of using this software and service, regardless of either inside or outside of Japan's territory.\r\n\r\nVPN Gate Relay Service will be installed on your computer as system services. System services always run in the background. After you terminate these management GUI tools, this system service will continue to run in the background. System services consume CPU time, computer power, memory and disk space. diff --git a/src/bin/hamcore/strtable_ja.stb b/src/bin/hamcore/strtable_ja.stb index 7c341d3f..3b937a12 100644 --- a/src/bin/hamcore/strtable_ja.stb +++ b/src/bin/hamcore/strtable_ja.stb @@ -159,11 +159,11 @@ ERR_91 仮想レイヤ 3 スイッチセッションは切断できません ERR_92 指定された名前の仮想レイヤ 3 スイッチは既に存在します。別の名前を指定してください。 ERR_93 指定された名前の仮想レイヤ 3 スイッチが見つかりません。 ERR_94 指定された名前が不正です。使用できない文字が含まれていないかどうかチェックしてください。 -ERR_95 仮想レイヤ 3 インターフェイスの追加に失敗しました。 -ERR_96 仮想レイヤ 3 インターフェイスの削除に失敗しました。 +ERR_95 仮想レイヤ 3 インターフェイスの追加に失敗しました。パラメータが正しいかどうか確認してください。また、仮想レイヤ 3 スイッチが動作中の場合は、仮想レイヤ 3 インターフェイスの追加または削除はできません。仮想レイヤ 3 スイッチを停止してください。 +ERR_96 仮想レイヤ 3 インターフェイスの削除に失敗しました。パラメータが正しいかどうか確認してください。また、仮想レイヤ 3 スイッチが動作中の場合は、仮想レイヤ 3 インターフェイスの追加または削除はできません。仮想レイヤ 3 スイッチを停止してください。 ERR_97 指定された仮想レイヤ 3 インターフェイスの接続先仮想 HUB に接続している仮想レイヤ 3 インターフェイスが仮想レイヤ 3 スイッチの中に既に存在します。1 つの仮想レイヤ 3 スイッチの中では、同一の仮想 HUB に接続する仮想レイヤ 3 インターフェイスは 1 つしか定義できません。 -ERR_98 ルーティングテーブルの追加に失敗しました。 -ERR_99 ルーティングテーブルの削除に失敗しました。 +ERR_98 ルーティングテーブルの追加に失敗しました。パラメータが正しいかどうか確認してください。また、仮想レイヤ 3 スイッチが動作中の場合は、ルーティングテーブルの追加または削除はできません。仮想レイヤ 3 スイッチを停止してください。 +ERR_99 ルーティングテーブルの削除に失敗しました。パラメータが正しいかどうか確認してください。また、仮想レイヤ 3 スイッチが動作中の場合は、ルーティングテーブルの追加または削除はできません。仮想レイヤ 3 スイッチを停止してください。 ERR_100 指定されたルーティングテーブルはすでに存在します。 ERR_101 クライアントとサーバーの間の時計がずれています。時刻設定を確認してください。 ERR_102 この仮想レイヤ 3 スイッチを開始できません。\r\n\r\n仮想レイヤ 3 スイッチを開始するには、最低でも 1 つの仮想インターフェイスが仮想レイヤ 3 スイッチ内に定義されている必要があります。 @@ -841,6 +841,7 @@ CM_ST_UDP_ACCEL_ENABLED UDP 高速化機能をサポート CM_ST_UDP_ACCEL_USING UDP 高速化機能を使用中 CM_ST_RUDP TCP over UDP (NAT Traversal) CM_ST_UNDERLAY_PROTOCOL 物理通信に使用中のプロトコル +CM_ST_PROTOCOL_DETAILS プロトコル詳細 CM_ST_COMPRESS_TRUE はい (約 %u %%) CM_ST_COMPRESS_FALSE いいえ (圧縮無し) CM_ST_SESSION_NAME セッション名 @@ -1598,6 +1599,7 @@ SM_LICENSE_NUM_BRIDGE ブリッジ同時接続可能数 SM_NO_LICENSE_COLUMN ご注意: SM_NO_LICENSE 製品ライセンスが 1 つも登録されていないため、この VPN Server の通信機能は動作しません。 SM_LICENSE_DELETE_MSG 選択されたライセンスを VPN Server から削除しますか? +SM_LICENSE_WARNING ソフトイーサはダイナミック DNS、NAT トラバーサルおよびVPN Azure を学術実験目的で研究開発し、主にオープンソース版 SoftEther VPN ユーザーの方々によって利用していただくために実験目的で運営しています。そのため、これらのサービスはすべて無料でご利用いただけます。\r\n\r\nSoftEther VPN の「重要事項説明書」(インストール時に表示、またはバイナリファイルにテキストファイルて同梱) の 3.5 節に記載されているとおり、これらのサービスはすべて無料でご利用いただけますが、これらのサービスは一切の保証がない状態で提供されるものです。実験の休止、中止や実験中の技術的問題の発生によってサービスが中断する場合があります。その場合は、ユーザーはサービスを利用できなくなります。ユーザーはこのようなリスクがあること、およびそのリスクをユーザー自身が負担することを承諾いただいた上でこれらのサービスをご利用ください。実験の休止、中止や実験中の技術的問題の発生によってサービスが中断する場合があります。その場合は、ユーザーはサービスを利用できなくなります。\r\n\r\nこれらの学術実験サービスを商業用途などの高い安定性が求められる用途に使用されることは、禁止されていませんが、学術実験サービスに障害が発生した場合、安定性上の問題が発生するなどのリスクがあります。商業用途などの高い安定性が求められる用途においては、これらの学術実験サービスを使用しないでください。\r\n\r\n仮にお客様が SoftEther VPN ソフトウェアの商用製品を購入され、SoftEther VPN ソフトウェアのライセンス料金をお客様がすでにお支払いいただいている場合であっても、当該料金にはこれらのサービスの対価は含まれていません。これらのサービスが中断したり利用不能になったりした場合であっても、SoftEther VPN ソフトウェアのライセンス料金は一切返金されず、その他の損害賠償も提供されません。 SM_SYSLOG_0 syslog 送信機能を使用しない SM_SYSLOG_1 サーバーログを syslog で送信 SM_SYSLOG_2 サーバーおよび仮想 HUB セキュリティログを syslog で送信 @@ -1788,6 +1790,10 @@ LS_LICENSE_NOT_VPNSERVER コネクション "%S": ライセンスエラーが発 LS_LICENSE_NOT_VPNCLUSTER コネクション "%S": ライセンスエラーが発生しました。この VPN Server には現在クラスタリング機能を使用できない種類のライセンスが登録されていますが、クラスタモードで動作中に VPN Client が接続しようとしました。VPN Server を再起動する必要があります。 LS_LICENSE_VIOLATION コネクション "%S": VPN Server でライセンス違反が発生しているため、接続を受け付けられません。 LS_LICENSE_VIOLATION_DETECTED ライセンス違反を検出しました。別の VPN Server が、この VPN Server と同じサーバー ID "%I64u" で動作しています。クラスタ内に同一のライセンスを使用した 2 台以上の VPN Server が存在する可能性があります。各 VPN Server のライセンス情報を確認してください。 +LS_API_AUTH_OK HTTPS API クライアント "%r:%u" (%S): 管理モード: "%S" で組み込み HTTPS Web サーバーを用いてログインに成功しました。使用されたユーザー名: "%S", メソッド: "%S", パス: "%S" +LS_API_AUTH_ERROR HTTPS API クライアント "%r:%u" (%S): 組み込み HTTPS Web サーバーを用いてログインに失敗しました。使用されたユーザー名: "%S", メソッド: "%S", パス: "%S" +LS_API_RPC_CALL HTTPS API クライアント "%r:%u" (%S): JSON-API を呼び出しました。メソッド名: "%S", 結果エラーコード: %u (0 = 成功), 結果エラーメッセージ: "%s" + # (OpenVPN ログ) @@ -1797,6 +1803,9 @@ LO_PREFIX_CHANNEL OpenVPN セッション %u (%r:%u -> %r:%u) チャネル %u: LO_NEW_CHANNEL 新しいチャネルを作成しました。 LO_CHANNEL_ESTABLISHED_NEWKEY チャネルが確立状態になりました (原因: リキーの完了)。 LO_OPTION_STR_RECV 受信したオプション文字列: "%S" +LO_CLIENT_CERT Client certificate received (subject: CN="%s"), will use certificate authentication. +LO_CLIENT_UNVERIFIED_CERT Client certificate was provided but did not pass verification (error="%S"), will use password authentication. +LO_CLIENT_NO_CERT Client certificate is not provided, will use password authentication. LO_OPTION_STR_SEND 送信するオプション文字列: "%S" LO_NEW_SESSION 新しいセッションを作成しました。プロトコル: %S LO_INITIATE_REKEY このチャネルのリキーを開始します。 @@ -1893,6 +1902,7 @@ LH_AUTH_PASSWORD パスワード認証 LH_AUTH_PLAIN_PASSWORD 外部サーバー認証 LH_AUTH_CERT 証明書認証 LH_AUTH_TICKET チケット認証 +LH_AUTH_OPENVPN_CERT OpenVPN 証明書認証 LH_AUTH_RADIUS_NOT_SUPPORT コネクション "%S": ユーザー "%S" の認証方法として RADIUS 認証または Active Directory 認証 (NT ドメイン認証) が指定されましたが、現在の VPN Server のエディションは "%S" であるため、RADIUS 認証または Active Directory 認証 (NT ドメイン認証) を使用することができません。接続は拒否されます。 LH_AUTH_RADIUS_NOT_SUPPORT_ON_OPEN_SOURCE コネクション "%S": ユーザー "%S" の認証方法として RADIUS 認証または Active Directory 認証 (NT ドメイン認証) が指定されましたが、RADIUS 認証または Active Directory 認証 (NT ドメイン認証) を使用することができません。この機能はオープンソース版 SoftEther VPN にはまだ実装されていません。接続は拒否されます。 LH_AUTH_CERT_NOT_SUPPORT_ON_OPEN_SOURCE コネクション "%S": ユーザー "%S" の認証方法として証明書認証が指定されましたが、証明書認証を使用することができません。この機能はオープンソース版 SoftEther VPN にはまだ実装されていません。接続は拒否されます。 @@ -1913,7 +1923,7 @@ LH_MAX_SESSION コネクション "%S": 仮想 HUB が設定された最大セ LH_MAX_SESSION_CLIENT コネクション "%S": 仮想 HUB が設定された最大クライアントセッション数 %u に達しています。新しいセッションは作成できません。 LH_MAX_SESSION_BRIDGE コネクション "%S": 仮想 HUB が設定された最大ブリッジセッション数 %u に達しています。新しいセッションは作成できません。 LH_MAX_SESSION_2 コネクション "%S": VPN Server 上で管理することができる最大セッション数 %u に達しています。新しいセッションは作成できません。 -LH_NEW_SESSION コネクション "%S": 新しいセッション "%S" が作成されました。(IP アドレス %S, ポート番号 %u, 物理レイヤのプロトコル: "%S") +LH_NEW_SESSION コネクション "%S": 新しいセッション "%S" が作成されました。(IP アドレス %S, ポート番号 %u, 物理レイヤのプロトコル: "%S", プロトコル詳細: "%S") LH_SET_SESSION セッション "%S": パラメータが設定されました。最大 TCP コネクション数 %u, 暗号化の使用 %s, 圧縮の使用 %s, 半二重通信の使用 %s, タイムアウト %u 秒 LH_NODE_INFO セッション "%S": VPN Client の詳細: (%s) LH_VLAN_ID セッション "%S": 割り当てられた VLAN ID: %u @@ -7010,6 +7020,8 @@ SW_WEB2_TITLE ファイルの指定 SW_UNINSTALLINFO_URL http://selinks.org/ SW_UNINSTALLINFO_PUBLISHER SoftEther VPN Project +SW_KB3033929_REQUIRED Windows 7 および Windows Server 2008 R2 では、SoftEther VPN の一部の機能を利用するためには、Microsoft 社の Windows Update プログラム KB3033929 がインストールされている必要があります。\r\n\r\nKB3033929 がインストールされていない場合は、SoftEther VPN をインストールする前に、Windows Update または Microsoft 社の Web サイトから KB3033929 をインストールをしてください。 + SW_COMPONENTS_ABOUT_TAG 「%s」とは SW_COMPONENTS_REQUIRE_ADMIN インストールには管理者権限が必要です @@ -7052,7 +7064,7 @@ SW_INSTALLER_CACHE_IS_NOT_SIGNED 現在のコンピュータにインストー SW_FILE_NOT_FOUNT ファイル "%s" が見つかりません。 SW_WEB_FINISHED 生成された Web インストーラを格納したファイル "%s" を保存しました。\r\n\r\nこの ZIP ファイルを展開し、中身のファイルを Web サーバーに設置して HTML ファイルや inf ファイル内の URL を適切に書き換えてください。\r\n\r\nWeb インストーラの配置方法に関する説明は ZIP ファイル内に記載されています。 -SW_VG_CONFIRM_MSG SoftEther VPN Client に組み込まれた VPN Gate P2P 中継機能プラグインモジュール をインストールし有効化します。よろしいですか?\r\n\r\n本プラグインは、政府の検閲用ファイアウォールを回避するための通信の安定化を実現します。しかしながら、VPN Gate のためのネットワーク帯域の消費量が増加します。したがって、モバイル回線において VPN Gate 機能を使用することは推奨されていません。\r\n\r\n政府の検閲用ファイアウォールを回避する目的で暗号化された通信を行うことは、いくつかの国および地域では禁止されています。そのような場合は、VPN Gate 機能をコンピュータで使用してはいけません。VPN Gate は専ら日本国内における使用を想定し開発されています。VPN Gate は学術目的の研究プロジェクトです。VPN Gate は日本国の法令に基づいて提供されます。その他の国の法律については、VPN Gate Project は一切関知しておりません。本ソフトウェアおよびサービスを使用するにあたり、ユーザーはユーザー自身の責任において、適用されるすべての法令を遵守しなければなりません。使用場所が日本国内または国外のいずれであるかに係わらず、本ソフトウェアおよびサービスを使用したことによるすべての損害および責任はユーザーが負うこととなります。 +SW_VG_CONFIRM_MSG SoftEther VPN Client に組み込まれた VPN Gate P2P 中継機能プラグインモジュール をインストールし有効化します。よろしいですか?\r\n\r\n本プラグインは、政府の検閲用ファイアウォールを回避するための通信の安定化を実現します。しかしながら、VPN Gate のためのネットワーク帯域の消費量が増加します。したがって、モバイル回線において VPN Gate 機能を使用することは推奨されていません。\r\n\r\n政府の検閲用ファイアウォールを回避する目的で暗号化された通信を行うことは、いくつかの国および地域では禁止されています。そのような場合は、VPN Gate 機能をコンピュータで使用してはいけません。VPN Gate は専ら日本国内における使用を想定し開発されています。VPN Gate は学術目的の研究プロジェクトです。VPN Gate は日本国の法令に基づいて提供されます。その他の国の法律については、VPN Gate Project は一切関知しておりません。本ソフトウェアおよびサービスを使用するにあたり、ユーザーはユーザー自身の責任において、適用されるすべての法令を遵守しなければなりません。使用場所が日本国内または国外のいずれであるかに係わらず、本ソフトウェアおよびサービスを使用したことによるすべての損害および責任はユーザーが負うこととなります。\r\n\r\nVPN Gate 中継サービスは、バックグラウンドで動作するシステムサービスとしてコンピュータにインストールされます。これらの管理 GUI ツールを終了しても、システムサービスは継続してバックグラウンドで動作し続けます。システムサービスは、CPU 時間、コンピュータの消費電力、メモリおよびディスクの容量を消費します。 diff --git a/src/bin/hamcore/vpnserver_api_doc.html b/src/bin/hamcore/vpnserver_api_doc.html new file mode 100644 index 00000000..64e7f10c --- /dev/null +++ b/src/bin/hamcore/vpnserver_api_doc.html @@ -0,0 +1,14648 @@ + + + + + SoftEther VPN Server JSON-RPC Suite Document + + + + + + +
+

SoftEther VPN Server JSON-RPC API Suite Document

+

This reference describes all JSON-RPC functions available on SoftEther VPN Server.

+

You can access to the latest SoftEther VPN Server JSON-RPC Document on GitHub.

+

What is SoftEther VPN Server JSON-RPC API Suite?

+

The API Suite allows you to easily develop your original SoftEther VPN Server management application to control the VPN Server (e.g. creating users, adding Virtual Hubs, disconnecting a specified VPN sessions).

+
    +
  • Almost all control APIs, which the VPN Server provides, are available as JSON-RPC API.
  • +
  • You can write your own VPN Server management application in your favorite languages (JavaScript, TypeScript, Java, Python, Ruby, C#, ... etc.)
  • +
  • If you are planning to develop your own VPN cloud service, the JSON-RPC API is the best choice to realize the automated operations for the VPN Server.
  • +
  • No need to use any specific API client library since all APIs are provided on the JSON-RPC 2.0 Specification. You can use your favorite JSON and HTTPS client library to call any of all APIs in your pure runtime environment.
  • +
  • Also, the SoftEther VPN Project provides high-quality JSON-RPC client stub libraries which define all of the API client stub codes. These libraries are written in C#, JavaScript and TypeScript. The Node.js Client Library for VPN Server RPC (vpnrpc) package is also available.
  • +
+

Principle

+

Entry point

+

The entry point URL of JSON-RPC is:

+
https://<vpn_server_hostname>:<port>/api/
+
+
    +
  • Older versions of SoftEther VPN before June 2019 don't support JSON-RPC APIs.
  • +
  • If you want to completely disable the JSON-RPC on your VPN Server, set the DisableJsonRpcWebApi variable to true on the vpn_server.config.
  • +
+

JSON-RPC specification

+

You must use HTTPS 1.1 POST method to call each of JSON-RPC APIs.
+All APIs are based on the JSON-RPC 2.0 Specification.

+
    +
  • JSON-RPC Notification is not supported.
  • +
  • JSON-RPC Batch is not supported.
  • +
+

"vpnrpc": Node.js Client Library package for VPN Server JSON-RPC

+

If you are willing to develop your original JSON-RPC client for SoftEther VPN, you can use the JavaScript Client Library for VPN Server RPC (vpnrpc).

+
    +
  • You can use the vpnrpc library in JavaScript for both web browsers (e.g. Chrome, FireFox or Edge) and Node.js.
  • +
  • As a sample code there is the sample.ts program in TypeScript. This sample calls all of available JSON-RPC APIs against the specified SoftEther VPN Server. (Note: This sample code is written in TypeScript.)
  • +
+

You can use the following command to download the vpnrpc library package with Node.js.

+
$ npm install --save-dev vpnrpc
+
+

"vpnrpc.ts": TypeScript Client Library for VPN Server JSON-RPC

+

If you are willing to develop your original JSON-RPC client for SoftEther VPN, you can use the TypeScript Client Library for VPN Server RPC (vpnrpc.ts).

+
    +
  • You can use the vpnrpc.ts library in TypeScript / JavaScript for both web browsers (e.g. Chrome, FireFox or Edge) and Node.js.
  • +
  • As a sample code there is the sample.ts program in TypeScript. This sample calls one by one all of available JSON-RPC APIs against the specified SoftEther VPN Server.
  • +
+

"vpnserver-jsonrpc-client-csharp": C# Client Library for VPN Server JSON-RPC

+

If you are willing to develop your original JSON-RPC client for SoftEther VPN, you can use the vpnserver-jsonrpc-client-csharp C# library.

+
    +
  • The client library codes for C# is written in pure C# 7.3. It works on .NET Core 2.1 or later on Windows, Linux and macOS. Very comfort with Visual Studio for both Windows or macOS.
  • +
  • As a sample code there is the VpnServerRpcTest.cs program in C#. This sample calls one by one all of available JSON-RPC APIs against the specified SoftEther VPN Server.
  • +
+

HTTPS Authentication

+

You must specify the following HTTPS custom headers for authentication on each of requests.

+ + + + + + + + + + + + + + + + + +
ValueDescription
X-VPNADMIN-HUBNAMEThe name of the Virtual Hub if you want to connect to the VPN Server as a Virtual Hub Admin Mode. Specify empty string if you want to connect to the VPN Server as the Entire VPN Server Admin Mode.
X-VPNADMIN-PASSWORDSpecify the administration password.
+
    +
  • You can omit the above HTTPS custom authentication headers if you are calling JSON-RPC APIs from the web browser which is already logged in to the VPN Server with HTTPS Basic Authentication. In such usage the credential of HTTPS Basic Authtication will be used.
  • +
+
+

Table of contents

+ +
+

+

"Test" RPC API - Test RPC function

+

Description

+

Test RPC function. Input any integer value to the IntValue_u32 field. Then the server will convert the integer to the string, and return the string in the StrValue_str field.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "Test",
+  "params": {
+    "IntValue_u32": 0
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "IntValue_u32": 0,
+    "Int64Value_u64": 0,
+    "StrValue_str": "strvalue",
+    "UniStrValue_utf": "unistrvalue"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
IntValue_u32number (uint32)A 32-bit integer field
Int64Value_u64number (uint64)A 64-bit integer field
StrValue_strstring (ASCII)An Ascii string field
UniStrValue_utfstring (UTF8)An UTF-8 string field
+
+

+

"GetServerInfo" RPC API - Get server information

+

Description

+

Get server information. This allows you to obtain the server information of the currently connected VPN Server or VPN Bridge. Included in the server information are the version number, build number and build information. You can also obtain information on the current server operation mode and the information of operating system that the server is operating on.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetServerInfo",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "ServerProductName_str": "serverproductname",
+    "ServerVersionString_str": "serverversionstring",
+    "ServerBuildInfoString_str": "serverbuildinfostring",
+    "ServerVerInt_u32": 0,
+    "ServerBuildInt_u32": 0,
+    "ServerHostName_str": "serverhostname",
+    "ServerType_u32": 0,
+    "ServerBuildDate_dt": "2020-08-01T12:24:36.123",
+    "ServerFamilyName_str": "serverfamilyname",
+    "OsType_u32": 0,
+    "OsServicePack_u32": 0,
+    "OsSystemName_str": "ossystemname",
+    "OsProductName_str": "osproductname",
+    "OsVendorName_str": "osvendorname",
+    "OsVersion_str": "osversion",
+    "KernelName_str": "kernelname",
+    "KernelVersion_str": "kernelversion"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
ServerProductName_strstring (ASCII)Server product name
ServerVersionString_strstring (ASCII)Server version string
ServerBuildInfoString_strstring (ASCII)Server build information string
ServerVerInt_u32number (uint32)Server version integer value
ServerBuildInt_u32number (uint32)Server build number integer value
ServerHostName_strstring (ASCII)Server host name
ServerType_u32number (enum)Type of server
Values:
0: Stand-alone server
1: Farm controller server
2: Farm member server
ServerBuildDate_dtDateBuild date and time of the server
ServerFamilyName_strstring (ASCII)Family name
OsType_u32number (enum)OS type
Values:
1100: Windows 95
1200: Windows 98
1300: Windows Me
1400: Windows (unknown)
2100: Windows NT 4.0 Workstation
2110: Windows NT 4.0 Server
2111: Windows NT 4.0 Server, Enterprise Edition
2112: Windows NT 4.0 Terminal Server
2113: BackOffice Server 4.5
2114: Small Business Server 4.5
2200: Windows 2000 Professional
2211: Windows 2000 Server
2212: Windows 2000 Advanced Server
2213: Windows 2000 Datacenter Server
2214: BackOffice Server 2000
2215: Small Business Server 2000
2300: Windows XP Home Edition
2301: Windows XP Professional
2410: Windows Server 2003 Web Edition
2411: Windows Server 2003 Standard Edition
2412: Windows Server 2003 Enterprise Edition
2413: Windows Server 2003 DataCenter Edition
2414: BackOffice Server 2003
2415: Small Business Server 2003
2500: Windows Vista
2510: Windows Server 2008
2600: Windows 7
2610: Windows Server 2008 R2
2700: Windows 8
2710: Windows Server 2012
2701: Windows 8.1
2711: Windows Server 2012 R2
2702: Windows 10
2712: Windows Server 10
2800: Windows 11 or later
2810: Windows Server 11 or later
3000: Unknown UNIX
3100: Linux
3200: Solaris
3300: Cygwin
3400: BSD
3500: MacOS X
OsServicePack_u32number (uint32)Service pack number
OsSystemName_strstring (ASCII)OS system name
OsProductName_strstring (ASCII)OS product name
OsVendorName_strstring (ASCII)OS vendor name
OsVersion_strstring (ASCII)OS version
KernelName_strstring (ASCII)Kernel name
KernelVersion_strstring (ASCII)Kernel version
+
+

+

"GetServerStatus" RPC API - Get Current Server Status

+

Description

+

Get Current Server Status. This allows you to obtain in real-time the current status of the currently connected VPN Server or VPN Bridge. You can get statistical information on data communication and the number of different kinds of objects that exist on the server. You can get information on how much memory is being used on the current computer by the OS.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetServerStatus",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "ServerType_u32": 0,
+    "NumTcpConnections_u32": 0,
+    "NumTcpConnectionsLocal_u32": 0,
+    "NumTcpConnectionsRemote_u32": 0,
+    "NumHubTotal_u32": 0,
+    "NumHubStandalone_u32": 0,
+    "NumHubStatic_u32": 0,
+    "NumHubDynamic_u32": 0,
+    "NumSessionsTotal_u32": 0,
+    "NumSessionsLocal_u32": 0,
+    "NumSessionsRemote_u32": 0,
+    "NumMacTables_u32": 0,
+    "NumIpTables_u32": 0,
+    "NumUsers_u32": 0,
+    "NumGroups_u32": 0,
+    "AssignedBridgeLicenses_u32": 0,
+    "AssignedClientLicenses_u32": 0,
+    "AssignedBridgeLicensesTotal_u32": 0,
+    "AssignedClientLicensesTotal_u32": 0,
+    "Recv.BroadcastBytes_u64": 0,
+    "Recv.BroadcastCount_u64": 0,
+    "Recv.UnicastBytes_u64": 0,
+    "Recv.UnicastCount_u64": 0,
+    "Send.BroadcastBytes_u64": 0,
+    "Send.BroadcastCount_u64": 0,
+    "Send.UnicastBytes_u64": 0,
+    "Send.UnicastCount_u64": 0,
+    "CurrentTime_dt": "2020-08-01T12:24:36.123",
+    "CurrentTick_u64": 0,
+    "StartTime_dt": "2020-08-01T12:24:36.123",
+    "TotalMemory_u64": 0,
+    "UsedMemory_u64": 0,
+    "FreeMemory_u64": 0,
+    "TotalPhys_u64": 0,
+    "UsedPhys_u64": 0,
+    "FreePhys_u64": 0
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
ServerType_u32number (enum)Type of server
Values:
0: Stand-alone server
1: Farm controller server
2: Farm member server
NumTcpConnections_u32number (uint32)Total number of TCP connections
NumTcpConnectionsLocal_u32number (uint32)Number of Local TCP connections
NumTcpConnectionsRemote_u32number (uint32)Number of remote TCP connections
NumHubTotal_u32number (uint32)Total number of HUBs
NumHubStandalone_u32number (uint32)Nymber of stand-alone HUB
NumHubStatic_u32number (uint32)Number of static HUBs
NumHubDynamic_u32number (uint32)Number of Dynamic HUBs
NumSessionsTotal_u32number (uint32)Total number of sessions
NumSessionsLocal_u32number (uint32)Number of local VPN sessions
NumSessionsRemote_u32number (uint32)The number of remote sessions
NumMacTables_u32number (uint32)Number of MAC table entries (total sum of all Virtual Hubs)
NumIpTables_u32number (uint32)Number of IP table entries (total sum of all Virtual Hubs)
NumUsers_u32number (uint32)Number of users (total sum of all Virtual Hubs)
NumGroups_u32number (uint32)Number of groups (total sum of all Virtual Hubs)
AssignedBridgeLicenses_u32number (uint32)Number of assigned bridge licenses (Useful to make a commercial version)
AssignedClientLicenses_u32number (uint32)Number of assigned client licenses (Useful to make a commercial version)
AssignedBridgeLicensesTotal_u32number (uint32)Number of Assigned bridge license (cluster-wide), useful to make a commercial version
AssignedClientLicensesTotal_u32number (uint32)Number of assigned client licenses (cluster-wide), useful to make a commercial version
Recv.BroadcastBytes_u64number (uint64)Number of broadcast packets (Recv)
Recv.BroadcastCount_u64number (uint64)Broadcast bytes (Recv)
Recv.UnicastBytes_u64number (uint64)Unicast count (Recv)
Recv.UnicastCount_u64number (uint64)Unicast bytes (Recv)
Send.BroadcastBytes_u64number (uint64)Number of broadcast packets (Send)
Send.BroadcastCount_u64number (uint64)Broadcast bytes (Send)
Send.UnicastBytes_u64number (uint64)Unicast bytes (Send)
Send.UnicastCount_u64number (uint64)Unicast bytes (Send)
CurrentTime_dtDateCurrent time
CurrentTick_u64number (uint64)64 bit High-Precision Logical System Clock
StartTime_dtDateVPN Server Start-up time
TotalMemory_u64number (uint64)Memory information: Total Memory
UsedMemory_u64number (uint64)Memory information: Used Memory
FreeMemory_u64number (uint64)Memory information: Free Memory
TotalPhys_u64number (uint64)Memory information: Total Phys
UsedPhys_u64number (uint64)Memory information: Used Phys
FreePhys_u64number (uint64)Memory information: Free Phys
+
+

+

"CreateListener" RPC API - Create New TCP Listener

+

Description

+

Create New TCP Listener. This allows you to create a new TCP Listener on the server. By creating the TCP Listener the server starts listening for a connection from clients at the specified TCP/IP port number. A TCP Listener that has been created can be deleted by the DeleteListener API. You can also get a list of TCP Listeners currently registered by using the EnumListener API. To execute this API, you must have VPN Server administrator privileges.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "CreateListener",
+  "params": {
+    "Port_u32": 0,
+    "Enable_bool": false
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "Port_u32": 0,
+    "Enable_bool": false
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
Port_u32number (uint32)Port number (Range: 1 - 65535)
Enable_boolbooleanActive state
+
+

+

"EnumListener" RPC API - Get List of TCP Listeners

+

Description

+

Get List of TCP Listeners. This allows you to get a list of TCP listeners registered on the current server. You can obtain information on whether the various TCP listeners have a status of operating or error. To call this API, you must have VPN Server administrator privileges.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "EnumListener",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "ListenerList": [
+      {
+        "Ports_u32": 0,
+        "Enables_bool": false,
+        "Errors_bool": false
+      },
+      {
+        "Ports_u32": 0,
+        "Enables_bool": false,
+        "Errors_bool": false
+      },
+      {
+        "Ports_u32": 0,
+        "Enables_bool": false,
+        "Errors_bool": false
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
ListenerListArray objectList of listener items
Ports_u32number (uint32)TCP port number (range: 1 - 65535)
Enables_boolbooleanActive state
Errors_boolbooleanThe flag to indicate if the error occurred on the listener port
+
+

+

"DeleteListener" RPC API - Delete TCP Listener

+

Description

+

Delete TCP Listener. This allows you to delete a TCP Listener that's registered on the server. When the TCP Listener is in a state of operation, the listener will automatically be deleted when its operation stops. You can also get a list of TCP Listeners currently registered by using the EnumListener API. To call this API, you must have VPN Server administrator privileges.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "DeleteListener",
+  "params": {
+    "Port_u32": 0
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "Port_u32": 0,
+    "Enable_bool": false
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
Port_u32number (uint32)Port number (Range: 1 - 65535)
Enable_boolbooleanActive state
+
+

+

"EnableListener" RPC API - Enable / Disable TCP Listener

+

Description

+

Enable / Disable TCP Listener. This starts or stops the operation of TCP Listeners registered on the current server. You can also get a list of TCP Listeners currently registered by using the EnumListener API. To call this API, you must have VPN Server administrator privileges.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "EnableListener",
+  "params": {
+    "Port_u32": 0,
+    "Enable_bool": false
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "Port_u32": 0,
+    "Enable_bool": false
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
Port_u32number (uint32)Port number (Range: 1 - 65535)
Enable_boolbooleanActive state
+
+

+

"SetServerPassword" RPC API - Set VPN Server Administrator Password

+

Description

+

Set VPN Server Administrator Password. This sets the VPN Server administrator password. You can specify the password as a parameter. To call this API, you must have VPN Server administrator privileges.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetServerPassword",
+  "params": {
+    "PlainTextPassword_str": "plaintextpassword"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "PlainTextPassword_str": "plaintextpassword"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + +
NameTypeDescrption
PlainTextPassword_strstring (ASCII)The plaintext password
+
+

+

"SetFarmSetting" RPC API - Set the VPN Server clustering configuration

+

Description

+

Set the VPN Server clustering configuration. Use this to set the VPN Server type as Standalone Server, Cluster Controller Server or Cluster Member Server. Standalone server means a VPN Server that does not belong to any cluster in its current state. When VPN Server is installed, by default it will be in standalone server mode. Unless you have particular plans to configure a cluster, we recommend the VPN Server be operated in standalone mode. A cluster controller is the central computer of all member servers of a cluster in the case where a clustering environment is made up of multiple VPN Servers. Multiple cluster members can be added to the cluster as required. A cluster requires one computer to serve this role. The other cluster member servers that are configured in the same cluster begin operation as a cluster member by connecting to the cluster controller. To call this API, you must have VPN Server administrator privileges. Also, when this API is executed, VPN Server will automatically restart. This API cannot be called on VPN Bridge.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetFarmSetting",
+  "params": {
+    "ServerType_u32": 0,
+    "NumPort_u32": 0,
+    "Ports_u32": [
+      1,
+      2,
+      3
+    ],
+    "PublicIp_ip": "192.168.0.1",
+    "ControllerName_str": "controllername",
+    "ControllerPort_u32": 0,
+    "MemberPasswordPlaintext_str": "memberpasswordplaintext",
+    "Weight_u32": 0,
+    "ControllerOnly_bool": false
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "ServerType_u32": 0,
+    "NumPort_u32": 0,
+    "Ports_u32": [
+      1,
+      2,
+      3
+    ],
+    "PublicIp_ip": "192.168.0.1",
+    "ControllerName_str": "controllername",
+    "ControllerPort_u32": 0,
+    "MemberPasswordPlaintext_str": "memberpasswordplaintext",
+    "Weight_u32": 0,
+    "ControllerOnly_bool": false
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
ServerType_u32number (enum)Type of server
Values:
0: Stand-alone server
1: Farm controller server
2: Farm member server
NumPort_u32number (uint32)Valid only for Cluster Member servers. Number of the Ports_u32 element.
Ports_u32number[] (uint32)Valid only for Cluster Member servers. Specify the list of public port numbers on this server. The list must have at least one public port number set, and it is also possible to set multiple public port numbers.
PublicIp_ipstring (IP address)Valid only for Cluster Member servers. Specify the public IP address of this server. If you wish to leave public IP address unspecified, specify the empty string. When a public IP address is not specified, the IP address of the network interface used when connecting to the cluster controller will be automatically used.
ControllerName_strstring (ASCII)Valid only for Cluster Member servers. Specify the host name or IP address of the destination cluster controller.
ControllerPort_u32number (uint32)Valid only for Cluster Member servers. Specify the TCP port number of the destination cluster controller.
MemberPasswordPlaintext_strstring (ASCII)Valid only for Cluster Member servers. Specify the password required to connect to the destination controller. It needs to be the same as an administrator password on the destination controller.
Weight_u32number (uint32)This sets a value for the performance standard ratio of this VPN Server. This is the standard value for when load balancing is performed in the cluster. For example, making only one machine 200 while the other members have a status of 100, will regulate that machine to receive twice as many connections as the other members. Specify 1 or higher for the value. If this parameter is left unspecified, 100 will be used.
ControllerOnly_boolbooleanValid only for Cluster Controller server. By specifying true, the VPN Server will operate only as a controller on the cluster and it will always distribute general VPN Client connections to members other than itself. This function is used in high-load environments.
+
+

+

"GetFarmSetting" RPC API - Get Clustering Configuration of Current VPN Server

+

Description

+

Get Clustering Configuration of Current VPN Server. You can use this to acquire the clustering configuration of the current VPN Server. To call this API, you must have VPN Server administrator privileges.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetFarmSetting",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "ServerType_u32": 0,
+    "NumPort_u32": 0,
+    "Ports_u32": [
+      1,
+      2,
+      3
+    ],
+    "PublicIp_ip": "192.168.0.1",
+    "ControllerName_str": "controllername",
+    "ControllerPort_u32": 0,
+    "MemberPasswordPlaintext_str": "memberpasswordplaintext",
+    "Weight_u32": 0,
+    "ControllerOnly_bool": false
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
ServerType_u32number (enum)Type of server
Values:
0: Stand-alone server
1: Farm controller server
2: Farm member server
NumPort_u32number (uint32)Valid only for Cluster Member servers. Number of the Ports_u32 element.
Ports_u32number[] (uint32)Valid only for Cluster Member servers. Specify the list of public port numbers on this server. The list must have at least one public port number set, and it is also possible to set multiple public port numbers.
PublicIp_ipstring (IP address)Valid only for Cluster Member servers. Specify the public IP address of this server. If you wish to leave public IP address unspecified, specify the empty string. When a public IP address is not specified, the IP address of the network interface used when connecting to the cluster controller will be automatically used.
ControllerName_strstring (ASCII)Valid only for Cluster Member servers. Specify the host name or IP address of the destination cluster controller.
ControllerPort_u32number (uint32)Valid only for Cluster Member servers. Specify the TCP port number of the destination cluster controller.
MemberPasswordPlaintext_strstring (ASCII)Valid only for Cluster Member servers. Specify the password required to connect to the destination controller. It needs to be the same as an administrator password on the destination controller.
Weight_u32number (uint32)This sets a value for the performance standard ratio of this VPN Server. This is the standard value for when load balancing is performed in the cluster. For example, making only one machine 200 while the other members have a status of 100, will regulate that machine to receive twice as many connections as the other members. Specify 1 or higher for the value. If this parameter is left unspecified, 100 will be used.
ControllerOnly_boolbooleanValid only for Cluster Controller server. By specifying true, the VPN Server will operate only as a controller on the cluster and it will always distribute general VPN Client connections to members other than itself. This function is used in high-load environments.
+
+

+

"GetFarmInfo" RPC API - Get Cluster Member Information

+

Description

+

Get Cluster Member Information. When the VPN Server is operating as a cluster controller, you can get information on cluster member servers on that cluster by specifying the IDs of the member servers. You can get the following information about the specified cluster member server: Server Type, Time Connection has been Established, IP Address, Host Name, Points, Public Port List, Number of Operating Virtual Hubs, First Virtual Hub, Number of Sessions and Number of TCP Connections. This API cannot be invoked on VPN Bridge.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetFarmInfo",
+  "params": {
+    "Id_u32": 0
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "Id_u32": 0,
+    "Controller_bool": false,
+    "ConnectedTime_dt": "2020-08-01T12:24:36.123",
+    "Ip_ip": "192.168.0.1",
+    "Hostname_str": "hostname",
+    "Point_u32": 0,
+    "NumPort_u32": 0,
+    "Ports_u32": [
+      1,
+      2,
+      3
+    ],
+    "ServerCert_bin": "SGVsbG8gV29ybGQ=",
+    "NumFarmHub_u32": 0,
+    "HubsList": [
+      {
+        "HubName_str": "hubname",
+        "DynamicHub_bool": false
+      },
+      {
+        "HubName_str": "hubname",
+        "DynamicHub_bool": false
+      },
+      {
+        "HubName_str": "hubname",
+        "DynamicHub_bool": false
+      }
+    ],
+    "NumSessions_u32": 0,
+    "NumTcpConnections_u32": 0,
+    "Weight_u32": 0
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
Id_u32number (uint32)ID
Controller_boolbooleanThe flag if the server is Cluster Controller (false: Cluster Member servers)
ConnectedTime_dtDateConnection Established Time
Ip_ipstring (IP address)IP address
Hostname_strstring (ASCII)Host name
Point_u32number (uint32)Point
NumPort_u32number (uint32)Number of Public Ports
Ports_u32number[] (uint32)Public Ports
ServerCert_binstring (Base64 binary)Server certificate
NumFarmHub_u32number (uint32)Number of farm HUB
HubsListArray objectThe hosted Virtual Hub list
NumSessions_u32number (uint32)Number of hosted VPN sessions
NumTcpConnections_u32number (uint32)Number of TCP connections
Weight_u32number (uint32)Performance Standard Ratio
HubName_strstring (ASCII)The Virtual Hub name
DynamicHub_boolbooleanDynamic HUB
+
+

+

"EnumFarmMember" RPC API - Get List of Cluster Members

+

Description

+

Get List of Cluster Members. Use this API when the VPN Server is operating as a cluster controller to get a list of the cluster member servers on the same cluster, including the cluster controller itself. For each member, the following information is also listed: Type, Connection Start, Host Name, Points, Number of Session, Number of TCP Connections, Number of Operating Virtual Hubs, Using Client Connection License and Using Bridge Connection License. This API cannot be invoked on VPN Bridge.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "EnumFarmMember",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "NumFarm_u32": 0,
+    "FarmMemberList": [
+      {
+        "Id_u32": 0,
+        "Controller_bool": false,
+        "ConnectedTime_dt": "2020-08-01T12:24:36.123",
+        "Ip_ip": "192.168.0.1",
+        "Hostname_str": "hostname",
+        "Point_u32": 0,
+        "NumSessions_u32": 0,
+        "NumTcpConnections_u32": 0,
+        "NumHubs_u32": 0,
+        "AssignedClientLicense_u32": 0,
+        "AssignedBridgeLicense_u32": 0
+      },
+      {
+        "Id_u32": 0,
+        "Controller_bool": false,
+        "ConnectedTime_dt": "2020-08-01T12:24:36.123",
+        "Ip_ip": "192.168.0.1",
+        "Hostname_str": "hostname",
+        "Point_u32": 0,
+        "NumSessions_u32": 0,
+        "NumTcpConnections_u32": 0,
+        "NumHubs_u32": 0,
+        "AssignedClientLicense_u32": 0,
+        "AssignedBridgeLicense_u32": 0
+      },
+      {
+        "Id_u32": 0,
+        "Controller_bool": false,
+        "ConnectedTime_dt": "2020-08-01T12:24:36.123",
+        "Ip_ip": "192.168.0.1",
+        "Hostname_str": "hostname",
+        "Point_u32": 0,
+        "NumSessions_u32": 0,
+        "NumTcpConnections_u32": 0,
+        "NumHubs_u32": 0,
+        "AssignedClientLicense_u32": 0,
+        "AssignedBridgeLicense_u32": 0
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
NumFarm_u32number (uint32)Number of Cluster Members
FarmMemberListArray objectCluster Members list
Id_u32number (uint32)ID
Controller_boolbooleanController
ConnectedTime_dtDateConnection time
Ip_ipstring (IP address)IP address
Hostname_strstring (ASCII)Host name
Point_u32number (uint32)Point
NumSessions_u32number (uint32)Number of sessions
NumTcpConnections_u32number (uint32)Number of TCP connections
NumHubs_u32number (uint32)Number of HUBs
AssignedClientLicense_u32number (uint32)Number of assigned client licenses
AssignedBridgeLicense_u32number (uint32)Number of assigned bridge licenses
+
+

+

"GetFarmConnectionStatus" RPC API - Get Connection Status to Cluster Controller

+

Description

+

Get Connection Status to Cluster Controller. Use this API when the VPN Server is operating as a cluster controller to get the status of connection to the cluster controller. You can get the following information: Controller IP Address, Port Number, Connection Status, Connection Start Time, First Connection Established Time, Current Connection Established Time, Number of Connection Attempts, Number of Successful Connections, Number of Failed Connections. This API cannot be invoked on VPN Bridge.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetFarmConnectionStatus",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "Ip_ip": "192.168.0.1",
+    "Port_u32": 0,
+    "Online_bool": false,
+    "LastError_u32": 0,
+    "StartedTime_dt": "2020-08-01T12:24:36.123",
+    "FirstConnectedTime_dt": "2020-08-01T12:24:36.123",
+    "CurrentConnectedTime_dt": "2020-08-01T12:24:36.123",
+    "NumTry_u32": 0,
+    "NumConnected_u32": 0,
+    "NumFailed_u32": 0
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
Ip_ipstring (IP address)IP address
Port_u32number (uint32)Port number
Online_boolbooleanOnline state
LastError_u32number (uint32)Last error code
StartedTime_dtDateConnection start time
FirstConnectedTime_dtDateFirst connection time
CurrentConnectedTime_dtDateConnection time of this time
NumTry_u32number (uint32)Number of retries
NumConnected_u32number (uint32)Number of connection count
NumFailed_u32number (uint32)Connection failure count
+
+

+

"SetServerCert" RPC API - Set SSL Certificate and Private Key of VPN Server

+

Description

+

Set SSL Certificate and Private Key of VPN Server. You can set the SSL certificate that the VPN Server provides to the connected client and the private key for that certificate. The certificate must be in X.509 format and the private key must be Base 64 encoded format. To call this API, you must have VPN Server administrator privileges.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetServerCert",
+  "params": {
+    "Cert_bin": "SGVsbG8gV29ybGQ=",
+    "Key_bin": "SGVsbG8gV29ybGQ="
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "Cert_bin": "SGVsbG8gV29ybGQ=",
+    "Key_bin": "SGVsbG8gV29ybGQ="
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
Cert_binstring (Base64 binary)The body of the certificate
Key_binstring (Base64 binary)The body of the private key
+
+

+

"GetServerCert" RPC API - Get SSL Certificate and Private Key of VPN Server

+

Description

+

Get SSL Certificate and Private Key of VPN Server. Use this to get the SSL certificate private key that the VPN Server provides to the connected client. To call this API, you must have VPN Server administrator privileges.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetServerCert",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "Cert_bin": "SGVsbG8gV29ybGQ=",
+    "Key_bin": "SGVsbG8gV29ybGQ="
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
Cert_binstring (Base64 binary)The body of the certificate
Key_binstring (Base64 binary)The body of the private key
+
+

+

"GetServerCipher" RPC API - Get the Encrypted Algorithm Used for VPN Communication

+

Description

+

Get the Encrypted Algorithm Used for VPN Communication. Use this API to get the current setting of the algorithm used for the electronic signature and encrypted for SSL connection to be used for communication between the VPN Server and the connected client and the list of algorithms that can be used on the VPN Server.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetServerCipher",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "String_str": "string"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + +
NameTypeDescrption
String_strstring (ASCII)A string value
+
+

+

"SetServerCipher" RPC API - Set the Encrypted Algorithm Used for VPN Communication

+

Description

+

Set the Encrypted Algorithm Used for VPN Communication. Use this API to set the algorithm used for the electronic signature and encrypted for SSL connections to be used for communication between the VPN Server and the connected client. By specifying the algorithm name, the specified algorithm will be used later between the VPN Client and VPN Bridge connected to this server and the data will be encrypted. To call this API, you must have VPN Server administrator privileges.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetServerCipher",
+  "params": {
+    "String_str": "string"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "String_str": "string"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + +
NameTypeDescrption
String_strstring (ASCII)A string value
+
+

+

"CreateHub" RPC API - Create New Virtual Hub

+

Description

+

Create New Virtual Hub. Use this to create a new Virtual Hub on the VPN Server. The created Virtual Hub will begin operation immediately. When the VPN Server is operating on a cluster, this API is only valid for the cluster controller. Also, the new Virtual Hub will operate as a dynamic Virtual Hub. You can change it to a static Virtual Hub by using the SetHub API. To get a list of Virtual Hubs that are already on the VPN Server, use the EnumHub API. To call this API, you must have VPN Server administrator privileges. Also, this API does not operate on VPN Servers that are operating as a VPN Bridge or cluster member.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "CreateHub",
+  "params": {
+    "HubName_str": "hubname",
+    "AdminPasswordPlainText_str": "adminpasswordplaintext",
+    "Online_bool": false,
+    "MaxSession_u32": 0,
+    "NoEnum_bool": false,
+    "HubType_u32": 0
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "AdminPasswordPlainText_str": "adminpasswordplaintext",
+    "Online_bool": false,
+    "MaxSession_u32": 0,
+    "NoEnum_bool": false,
+    "HubType_u32": 0
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)Specify the name of the Virtual Hub to create / update.
AdminPasswordPlainText_strstring (ASCII)Specify an administrator password when the administrator password is going to be set for the Virtual Hub. On the update, leave it to empty string if you don't want to change the password.
Online_boolbooleanOnline flag
MaxSession_u32number (uint32)Maximum number of VPN sessions
NoEnum_boolbooleanNo Enum flag. By enabling this option, the VPN Client user will be unable to enumerate this Virtual Hub even if they send a Virtual Hub enumeration request to the VPN Server.
HubType_u32number (enum)Type of the Virtual Hub (Valid only for Clustered VPN Servers)
Values:
0: Stand-alone HUB
1: Static HUB
2: Dynamic HUB
+
+

+

"SetHub" RPC API - Set the Virtual Hub configuration

+

Description

+

Set the Virtual Hub configuration. You can call this API to change the configuration of the specified Virtual Hub. You can set the Virtual Hub online or offline. You can set the maximum number of sessions that can be concurrently connected to the Virtual Hub that is currently being managed. You can set the Virtual Hub administrator password. You can set other parameters for the Virtual Hub. Before call this API, you need to obtain the latest state of the Virtual Hub by using the GetHub API.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetHub",
+  "params": {
+    "HubName_str": "hubname",
+    "AdminPasswordPlainText_str": "adminpasswordplaintext",
+    "Online_bool": false,
+    "MaxSession_u32": 0,
+    "NoEnum_bool": false,
+    "HubType_u32": 0
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "AdminPasswordPlainText_str": "adminpasswordplaintext",
+    "Online_bool": false,
+    "MaxSession_u32": 0,
+    "NoEnum_bool": false,
+    "HubType_u32": 0
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)Specify the name of the Virtual Hub to create / update.
AdminPasswordPlainText_strstring (ASCII)Specify an administrator password when the administrator password is going to be set for the Virtual Hub. On the update, leave it to empty string if you don't want to change the password.
Online_boolbooleanOnline flag
MaxSession_u32number (uint32)Maximum number of VPN sessions
NoEnum_boolbooleanNo Enum flag. By enabling this option, the VPN Client user will be unable to enumerate this Virtual Hub even if they send a Virtual Hub enumeration request to the VPN Server.
HubType_u32number (enum)Type of the Virtual Hub (Valid only for Clustered VPN Servers)
Values:
0: Stand-alone HUB
1: Static HUB
2: Dynamic HUB
+
+

+

"GetHub" RPC API - Get the Virtual Hub configuration

+

Description

+

Get the Virtual Hub configuration. You can call this API to get the current configuration of the specified Virtual Hub. To change the configuration of the Virtual Hub, call the SetHub API.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetHub",
+  "params": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "AdminPasswordPlainText_str": "adminpasswordplaintext",
+    "Online_bool": false,
+    "MaxSession_u32": 0,
+    "NoEnum_bool": false,
+    "HubType_u32": 0
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)Specify the name of the Virtual Hub to create / update.
AdminPasswordPlainText_strstring (ASCII)Specify an administrator password when the administrator password is going to be set for the Virtual Hub. On the update, leave it to empty string if you don't want to change the password.
Online_boolbooleanOnline flag
MaxSession_u32number (uint32)Maximum number of VPN sessions
NoEnum_boolbooleanNo Enum flag. By enabling this option, the VPN Client user will be unable to enumerate this Virtual Hub even if they send a Virtual Hub enumeration request to the VPN Server.
HubType_u32number (enum)Type of the Virtual Hub (Valid only for Clustered VPN Servers)
Values:
0: Stand-alone HUB
1: Static HUB
2: Dynamic HUB
+
+

+

"EnumHub" RPC API - Get List of Virtual Hubs

+

Description

+

Get List of Virtual Hubs. Use this to get a list of existing Virtual Hubs on the VPN Server. For each Virtual Hub, you can get the following information: Virtual Hub Name, Status, Type, Number of Users, Number of Groups, Number of Sessions, Number of MAC Tables, Number of IP Tables, Number of Logins, Last Login, and Last Communication. Note that when connecting in Virtual Hub Admin Mode, if in the options of a Virtual Hub that you do not have administrator privileges for, the option Don't Enumerate this Virtual Hub for Anonymous Users is enabled then that Virtual Hub will not be enumerated. If you are connected in Server Admin Mode, then the list of all Virtual Hubs will be displayed. When connecting to and managing a non-cluster-controller cluster member of a clustering environment, only the Virtual Hub currently being hosted by that VPN Server will be displayed. When connecting to a cluster controller for administration purposes, all the Virtual Hubs will be displayed.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "EnumHub",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "NumHub_u32": 0,
+    "HubList": [
+      {
+        "HubName_str": "hubname",
+        "Online_bool": false,
+        "HubType_u32": 0,
+        "NumUsers_u32": 0,
+        "NumGroups_u32": 0,
+        "NumSessions_u32": 0,
+        "NumMacTables_u32": 0,
+        "NumIpTables_u32": 0,
+        "LastCommTime_dt": "2020-08-01T12:24:36.123",
+        "LastLoginTime_dt": "2020-08-01T12:24:36.123",
+        "CreatedTime_dt": "2020-08-01T12:24:36.123",
+        "NumLogin_u32": 0,
+        "IsTrafficFilled_bool": false,
+        "Ex.Recv.BroadcastBytes_u64": 0,
+        "Ex.Recv.BroadcastCount_u64": 0,
+        "Ex.Recv.UnicastBytes_u64": 0,
+        "Ex.Recv.UnicastCount_u64": 0,
+        "Ex.Send.BroadcastBytes_u64": 0,
+        "Ex.Send.BroadcastCount_u64": 0,
+        "Ex.Send.UnicastBytes_u64": 0,
+        "Ex.Send.UnicastCount_u64": 0
+      },
+      {
+        "HubName_str": "hubname",
+        "Online_bool": false,
+        "HubType_u32": 0,
+        "NumUsers_u32": 0,
+        "NumGroups_u32": 0,
+        "NumSessions_u32": 0,
+        "NumMacTables_u32": 0,
+        "NumIpTables_u32": 0,
+        "LastCommTime_dt": "2020-08-01T12:24:36.123",
+        "LastLoginTime_dt": "2020-08-01T12:24:36.123",
+        "CreatedTime_dt": "2020-08-01T12:24:36.123",
+        "NumLogin_u32": 0,
+        "IsTrafficFilled_bool": false,
+        "Ex.Recv.BroadcastBytes_u64": 0,
+        "Ex.Recv.BroadcastCount_u64": 0,
+        "Ex.Recv.UnicastBytes_u64": 0,
+        "Ex.Recv.UnicastCount_u64": 0,
+        "Ex.Send.BroadcastBytes_u64": 0,
+        "Ex.Send.BroadcastCount_u64": 0,
+        "Ex.Send.UnicastBytes_u64": 0,
+        "Ex.Send.UnicastCount_u64": 0
+      },
+      {
+        "HubName_str": "hubname",
+        "Online_bool": false,
+        "HubType_u32": 0,
+        "NumUsers_u32": 0,
+        "NumGroups_u32": 0,
+        "NumSessions_u32": 0,
+        "NumMacTables_u32": 0,
+        "NumIpTables_u32": 0,
+        "LastCommTime_dt": "2020-08-01T12:24:36.123",
+        "LastLoginTime_dt": "2020-08-01T12:24:36.123",
+        "CreatedTime_dt": "2020-08-01T12:24:36.123",
+        "NumLogin_u32": 0,
+        "IsTrafficFilled_bool": false,
+        "Ex.Recv.BroadcastBytes_u64": 0,
+        "Ex.Recv.BroadcastCount_u64": 0,
+        "Ex.Recv.UnicastBytes_u64": 0,
+        "Ex.Recv.UnicastCount_u64": 0,
+        "Ex.Send.BroadcastBytes_u64": 0,
+        "Ex.Send.BroadcastCount_u64": 0,
+        "Ex.Send.UnicastBytes_u64": 0,
+        "Ex.Send.UnicastCount_u64": 0
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
NumHub_u32number (uint32)Number of Virtual Hubs
HubListArray objectVirtual Hubs
HubName_strstring (ASCII)The name of the Virtual Hub
Online_boolbooleanOnline state
HubType_u32number (enum)Type of HUB (Valid only for Clustered VPN Servers)
Values:
0: Stand-alone HUB
1: Static HUB
2: Dynamic HUB
NumUsers_u32number (uint32)Number of users
NumGroups_u32number (uint32)Number of registered groups
NumSessions_u32number (uint32)Number of registered sessions
NumMacTables_u32number (uint32)Number of current MAC table entries
NumIpTables_u32number (uint32)Number of current IP table entries
LastCommTime_dtDateLast communication date and time
LastLoginTime_dtDateLast login date and time
CreatedTime_dtDateCreation date and time
NumLogin_u32number (uint32)Number of accumulated logins
IsTrafficFilled_boolbooleanWhether the traffic information is provided
Ex.Recv.BroadcastBytes_u64number (uint64)Number of broadcast packets (Recv)
Ex.Recv.BroadcastCount_u64number (uint64)Broadcast bytes (Recv)
Ex.Recv.UnicastBytes_u64number (uint64)Unicast count (Recv)
Ex.Recv.UnicastCount_u64number (uint64)Unicast bytes (Recv)
Ex.Send.BroadcastBytes_u64number (uint64)Number of broadcast packets (Send)
Ex.Send.BroadcastCount_u64number (uint64)Broadcast bytes (Send)
Ex.Send.UnicastBytes_u64number (uint64)Unicast bytes (Send)
Ex.Send.UnicastCount_u64number (uint64)Unicast bytes (Send)
+
+

+

"DeleteHub" RPC API - Delete Virtual Hub

+

Description

+

Delete Virtual Hub. Use this to delete an existing Virtual Hub on the VPN Server. If you delete the Virtual Hub, all sessions that are currently connected to the Virtual Hub will be disconnected and new sessions will be unable to connect to the Virtual Hub. Also, this will also delete all the Hub settings, user objects, group objects, certificates and Cascade Connections. Once you delete the Virtual Hub, it cannot be recovered. To call this API, you must have VPN Server administrator privileges. Also, this API does not operate on VPN Servers that are operating as a VPN Bridge or cluster member.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "DeleteHub",
+  "params": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
+
+

+

"GetHubRadius" RPC API - Get Setting of RADIUS Server Used for User Authentication

+

Description

+

Get Setting of RADIUS Server Used for User Authentication. Use this to get the current settings for the RADIUS server used when a user connects to the currently managed Virtual Hub using RADIUS Server Authentication Mode. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetHubRadius",
+  "params": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "RadiusServerName_str": "radiusservername",
+    "RadiusPort_u32": 0,
+    "RadiusSecret_str": "radiussecret",
+    "RadiusRetryInterval_u32": 0
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
RadiusServerName_strstring (ASCII)RADIUS server name
RadiusPort_u32number (uint32)RADIUS port number
RadiusSecret_strstring (ASCII)Secret key
RadiusRetryInterval_u32number (uint32)Radius retry interval
+
+

+

"SetHubRadius" RPC API - Set RADIUS Server to use for User Authentication

+

Description

+

Set RADIUS Server to use for User Authentication. To accept users to the currently managed Virtual Hub in RADIUS server authentication mode, you can specify an external RADIUS server that confirms the user name and password. (You can specify multiple hostname by splitting with comma or semicolon.) The RADIUS server must be set to receive requests from IP addresses of this VPN Server. Also, authentication by Password Authentication Protocol (PAP) must be enabled. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetHubRadius",
+  "params": {
+    "HubName_str": "hubname",
+    "RadiusServerName_str": "radiusservername",
+    "RadiusPort_u32": 0,
+    "RadiusSecret_str": "radiussecret",
+    "RadiusRetryInterval_u32": 0
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "RadiusServerName_str": "radiusservername",
+    "RadiusPort_u32": 0,
+    "RadiusSecret_str": "radiussecret",
+    "RadiusRetryInterval_u32": 0
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
RadiusServerName_strstring (ASCII)RADIUS server name
RadiusPort_u32number (uint32)RADIUS port number
RadiusSecret_strstring (ASCII)Secret key
RadiusRetryInterval_u32number (uint32)Radius retry interval
+
+

+

"EnumConnection" RPC API - Get List of TCP Connections Connecting to the VPN Server

+

Description

+

Get List of TCP Connections Connecting to the VPN Server. Use this to get a list of TCP/IP connections that are currently connecting to the VPN Server. It does not display the TCP connections that have been established as VPN sessions. To get the list of TCP/IP connections that have been established as VPN sessions, you can use the EnumSession API. You can get the following: Connection Name, Connection Source, Connection Start and Type. To call this API, you must have VPN Server administrator privileges.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "EnumConnection",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "NumConnection_u32": 0,
+    "ConnectionList": [
+      {
+        "Name_str": "name",
+        "Hostname_str": "hostname",
+        "Ip_ip": "192.168.0.1",
+        "Port_u32": 0,
+        "ConnectedTime_dt": "2020-08-01T12:24:36.123",
+        "Type_u32": 0
+      },
+      {
+        "Name_str": "name",
+        "Hostname_str": "hostname",
+        "Ip_ip": "192.168.0.1",
+        "Port_u32": 0,
+        "ConnectedTime_dt": "2020-08-01T12:24:36.123",
+        "Type_u32": 0
+      },
+      {
+        "Name_str": "name",
+        "Hostname_str": "hostname",
+        "Ip_ip": "192.168.0.1",
+        "Port_u32": 0,
+        "ConnectedTime_dt": "2020-08-01T12:24:36.123",
+        "Type_u32": 0
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
NumConnection_u32number (uint32)Number of connections
ConnectionListArray objectConnection list
Name_strstring (ASCII)Connection name
Hostname_strstring (ASCII)Host name
Ip_ipstring (IP address)IP address
Port_u32number (uint32)Port number
ConnectedTime_dtDateConnected time
Type_u32number (enum)Connection type
Values:
0: VPN Client
1: During initialization
2: Login connection
3: Additional connection
4: RPC for server farm
5: RPC for Management
6: HUB enumeration
7: Password change
8: SSTP
9: OpenVPN
+
+

+

"DisconnectConnection" RPC API - Disconnect TCP Connections Connecting to the VPN Server

+

Description

+

Disconnect TCP Connections Connecting to the VPN Server. Use this to forcefully disconnect specific TCP/IP connections that are connecting to the VPN Server. To call this API, you must have VPN Server administrator privileges.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "DisconnectConnection",
+  "params": {
+    "Name_str": "name"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "Name_str": "name"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + +
NameTypeDescrption
Name_strstring (ASCII)Connection name
+
+

+

"GetConnectionInfo" RPC API - Get Information of TCP Connections Connecting to the VPN Server

+

Description

+

Get Information of TCP Connections Connecting to the VPN Server. Use this to get detailed information of a specific TCP/IP connection that is connecting to the VPN Server. You can get the following information: Connection Name, Connection Type, Source Hostname, Source IP Address, Source Port Number (TCP), Connection Start, Server Product Name, Server Version, Server Build Number, Client Product Name, Client Version, and Client Build Number. To call this API, you must have VPN Server administrator privileges.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetConnectionInfo",
+  "params": {
+    "Name_str": "name"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "Name_str": "name",
+    "Type_u32": 0,
+    "Hostname_str": "hostname",
+    "Ip_ip": "192.168.0.1",
+    "Port_u32": 0,
+    "ConnectedTime_dt": "2020-08-01T12:24:36.123",
+    "ServerStr_str": "serverstr",
+    "ServerVer_u32": 0,
+    "ServerBuild_u32": 0,
+    "ClientStr_str": "clientstr",
+    "ClientVer_u32": 0,
+    "ClientBuild_u32": 0
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
Name_strstring (ASCII)Connection name
Type_u32number (enum)Type
Values:
0: VPN Client
1: During initialization
2: Login connection
3: Additional connection
4: RPC for server farm
5: RPC for Management
6: HUB enumeration
7: Password change
8: SSTP
9: OpenVPN
Hostname_strstring (ASCII)Host name
Ip_ipstring (IP address)IP address
Port_u32number (uint32)Port number
ConnectedTime_dtDateConnected time
ServerStr_strstring (ASCII)Server string
ServerVer_u32number (uint32)Server version
ServerBuild_u32number (uint32)Server build number
ClientStr_strstring (ASCII)Client string
ClientVer_u32number (uint32)Client version
ClientBuild_u32number (uint32)Client build number
+
+

+

"SetHubOnline" RPC API - Switch Virtual Hub to Online or Offline

+

Description

+

Switch Virtual Hub to Online or Offline. Use this to set the Virtual Hub to online or offline. A Virtual Hub with an offline status cannot receive VPN connections from clients. When you set the Virtual Hub offline, all sessions will be disconnected. A Virtual Hub with an offline status cannot receive VPN connections from clients. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetHubOnline",
+  "params": {
+    "HubName_str": "hubname",
+    "Online_bool": false
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "Online_bool": false
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
Online_boolbooleanOnline / offline flag
+
+

+

"GetHubStatus" RPC API - Get Current Status of Virtual Hub

+

Description

+

Get Current Status of Virtual Hub. Use this to get the current status of the Virtual Hub currently being managed. You can get the following information: Virtual Hub Type, Number of Sessions, Number of Each Type of Object, Number of Logins, Last Login, Last Communication, and Communication Statistical Data.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetHubStatus",
+  "params": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "Online_bool": false,
+    "HubType_u32": 0,
+    "NumSessions_u32": 0,
+    "NumSessionsClient_u32": 0,
+    "NumSessionsBridge_u32": 0,
+    "NumAccessLists_u32": 0,
+    "NumUsers_u32": 0,
+    "NumGroups_u32": 0,
+    "NumMacTables_u32": 0,
+    "NumIpTables_u32": 0,
+    "Recv.BroadcastBytes_u64": 0,
+    "Recv.BroadcastCount_u64": 0,
+    "Recv.UnicastBytes_u64": 0,
+    "Recv.UnicastCount_u64": 0,
+    "Send.BroadcastBytes_u64": 0,
+    "Send.BroadcastCount_u64": 0,
+    "Send.UnicastBytes_u64": 0,
+    "Send.UnicastCount_u64": 0,
+    "SecureNATEnabled_bool": false,
+    "LastCommTime_dt": "2020-08-01T12:24:36.123",
+    "LastLoginTime_dt": "2020-08-01T12:24:36.123",
+    "CreatedTime_dt": "2020-08-01T12:24:36.123",
+    "NumLogin_u32": 0
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
Online_boolbooleanOnline
HubType_u32number (enum)Type of HUB
Values:
0: Stand-alone HUB
1: Static HUB
2: Dynamic HUB
NumSessions_u32number (uint32)Number of sessions
NumSessionsClient_u32number (uint32)Number of sessions (client mode)
NumSessionsBridge_u32number (uint32)Number of sessions (bridge mode)
NumAccessLists_u32number (uint32)Number of Access list entries
NumUsers_u32number (uint32)Number of users
NumGroups_u32number (uint32)Number of groups
NumMacTables_u32number (uint32)Number of MAC table entries
NumIpTables_u32number (uint32)Number of IP table entries
Recv.BroadcastBytes_u64number (uint64)Number of broadcast packets (Recv)
Recv.BroadcastCount_u64number (uint64)Broadcast bytes (Recv)
Recv.UnicastBytes_u64number (uint64)Unicast count (Recv)
Recv.UnicastCount_u64number (uint64)Unicast bytes (Recv)
Send.BroadcastBytes_u64number (uint64)Number of broadcast packets (Send)
Send.BroadcastCount_u64number (uint64)Broadcast bytes (Send)
Send.UnicastBytes_u64number (uint64)Unicast bytes (Send)
Send.UnicastCount_u64number (uint64)Unicast bytes (Send)
SecureNATEnabled_boolbooleanWhether SecureNAT is enabled
LastCommTime_dtDateLast communication date and time
LastLoginTime_dtDateLast login date and time
CreatedTime_dtDateCreation date and time
NumLogin_u32number (uint32)Number of logins
+
+

+

"SetHubLog" RPC API - Set the logging configuration of the Virtual Hub

+

Description

+

Set the logging configuration of the Virtual Hub. Use this to enable or disable a security log or packet logs of the Virtual Hub currently being managed, set the save contents of the packet log for each type of packet to be saved, and set the log file switch cycle for the security log or packet log that the currently managed Virtual Hub saves. There are the following packet types: TCP Connection Log, TCP Packet Log, DHCP Packet Log, UDP Packet Log, ICMP Packet Log, IP Packet Log, ARP Packet Log, and Ethernet Packet Log. To get the current setting, you can use the LogGet API. The log file switch cycle can be changed to switch in every second, every minute, every hour, every day, every month or not switch. To get the current setting, you can use the GetHubLog API.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetHubLog",
+  "params": {
+    "HubName_str": "hubname",
+    "SaveSecurityLog_bool": false,
+    "SecurityLogSwitchType_u32": 0,
+    "SavePacketLog_bool": false,
+    "PacketLogSwitchType_u32": 0,
+    "PacketLogConfig_u32": [
+      1,
+      2,
+      3
+    ]
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "SaveSecurityLog_bool": false,
+    "SecurityLogSwitchType_u32": 0,
+    "SavePacketLog_bool": false,
+    "PacketLogSwitchType_u32": 0,
+    "PacketLogConfig_u32": [
+      1,
+      2,
+      3
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
SaveSecurityLog_boolbooleanThe flag to enable / disable saving the security log
SecurityLogSwitchType_u32number (enum)The log filename switching setting of the security log
Values:
0: No switching
1: Secondly basis
2: Minutely basis
3: Hourly basis
4: Daily basis
5: Monthly basis
SavePacketLog_boolbooleanThe flag to enable / disable saving the security log
PacketLogSwitchType_u32number (enum)The log filename switching settings of the packet logs
Values:
0: No switching
1: Secondly basis
2: Minutely basis
3: Hourly basis
4: Daily basis
5: Monthly basis
PacketLogConfig_u32number (enum)Specify the save contents of the packet logs (uint * 16 array). The index numbers: TcpConnection = 0, TcpAll = 1, DHCP = 2, UDP = 3, ICMP = 4, IP = 5, ARP = 6, Ethernet = 7.
Values:
0: Not save
1: Only header
2: All payloads
+
+

+

"GetHubLog" RPC API - Get the logging configuration of the Virtual Hub

+

Description

+

Get the logging configuration of the Virtual Hub. Use this to get the configuration for a security log or packet logs of the Virtual Hub currently being managed, get the setting for save contents of the packet log for each type of packet to be saved, and get the log file switch cycle for the security log or packet log that the currently managed Virtual Hub saves. To set the current setting, you can use the SetHubLog API.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetHubLog",
+  "params": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "SaveSecurityLog_bool": false,
+    "SecurityLogSwitchType_u32": 0,
+    "SavePacketLog_bool": false,
+    "PacketLogSwitchType_u32": 0,
+    "PacketLogConfig_u32": [
+      1,
+      2,
+      3
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
SaveSecurityLog_boolbooleanThe flag to enable / disable saving the security log
SecurityLogSwitchType_u32number (enum)The log filename switching setting of the security log
Values:
0: No switching
1: Secondly basis
2: Minutely basis
3: Hourly basis
4: Daily basis
5: Monthly basis
SavePacketLog_boolbooleanThe flag to enable / disable saving the security log
PacketLogSwitchType_u32number (enum)The log filename switching settings of the packet logs
Values:
0: No switching
1: Secondly basis
2: Minutely basis
3: Hourly basis
4: Daily basis
5: Monthly basis
PacketLogConfig_u32number (enum)Specify the save contents of the packet logs (uint * 16 array). The index numbers: TcpConnection = 0, TcpAll = 1, DHCP = 2, UDP = 3, ICMP = 4, IP = 5, ARP = 6, Ethernet = 7.
Values:
0: Not save
1: Only header
2: All payloads
+
+

+

"AddCa" RPC API - Add Trusted CA Certificate

+

Description

+

Add Trusted CA Certificate. Use this to add a new certificate to a list of CA certificates trusted by the currently managed Virtual Hub. The list of certificate authority certificates that are registered is used to verify certificates when a VPN Client is connected in signed certificate authentication mode. To get a list of the current certificates you can use the EnumCa API. The certificate you add must be saved in the X.509 file format. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a member server on a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "AddCa",
+  "params": {
+    "HubName_str": "hubname",
+    "Cert_bin": "SGVsbG8gV29ybGQ="
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "Cert_bin": "SGVsbG8gV29ybGQ="
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
Cert_binstring (Base64 binary)The body of the X.509 certificate
+
+

+

"EnumCa" RPC API - Get List of Trusted CA Certificates

+

Description

+

Get List of Trusted CA Certificates. Here you can manage the certificate authority certificates that are trusted by this currently managed Virtual Hub. The list of certificate authority certificates that are registered is used to verify certificates when a VPN Client is connected in signed certificate authentication mode. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a member server on a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "EnumCa",
+  "params": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "CAList": [
+      {
+        "Key_u32": 0,
+        "SubjectName_utf": "subjectname",
+        "IssuerName_utf": "issuername",
+        "Expires_dt": "2020-08-01T12:24:36.123"
+      },
+      {
+        "Key_u32": 0,
+        "SubjectName_utf": "subjectname",
+        "IssuerName_utf": "issuername",
+        "Expires_dt": "2020-08-01T12:24:36.123"
+      },
+      {
+        "Key_u32": 0,
+        "SubjectName_utf": "subjectname",
+        "IssuerName_utf": "issuername",
+        "Expires_dt": "2020-08-01T12:24:36.123"
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
CAListArray objectThe list of CA
Key_u32number (uint32)The key id of the item
SubjectName_utfstring (UTF8)Subject
IssuerName_utfstring (UTF8)Issuer
Expires_dtDateExpiration date
+
+

+

"GetCa" RPC API - Get Trusted CA Certificate

+

Description

+

Get Trusted CA Certificate. Use this to get an existing certificate from the list of CA certificates trusted by the currently managed Virtual Hub and save it as a file in X.509 format. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a member server on a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetCa",
+  "params": {
+    "HubName_str": "hubname",
+    "Key_u32": 0
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "Key_u32": 0,
+    "Cert_bin": "SGVsbG8gV29ybGQ="
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
Key_u32number (uint32)The key id of the certificate
Cert_binstring (Base64 binary)The body of the X.509 certificate
+
+

+

"DeleteCa" RPC API - Delete Trusted CA Certificate

+

Description

+

Delete Trusted CA Certificate. Use this to delete an existing certificate from the list of CA certificates trusted by the currently managed Virtual Hub. To get a list of the current certificates you can use the EnumCa API. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a member server on a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "DeleteCa",
+  "params": {
+    "HubName_str": "hubname",
+    "Key_u32": 0
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "Key_u32": 0
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
Key_u32number (uint32)Certificate key id to be deleted
+
+

+ +

Description

+

Create New Cascade Connection. Use this to create a new Cascade Connection on the currently managed Virtual Hub. By using a Cascade Connection, you can connect this Virtual Hub by Cascade Connection to another Virtual Hub that is operating on the same or a different computer. To create a Cascade Connection, you must specify the name of the Cascade Connection, destination server and destination Virtual Hub and user name. When a new Cascade Connection is created, the type of user authentication is initially set as Anonymous Authentication and the proxy server setting and the verification options of the server certificate is not set. To change these settings and other advanced settings after a Cascade Connection has been created, use the other APIs that include the name "Link". [Warning About Cascade Connections] By connecting using a Cascade Connection you can create a Layer 2 bridge between multiple Virtual Hubs but if the connection is incorrectly configured, a loopback Cascade Connection could inadvertently be created. When using a Cascade Connection function please design the network topology with care. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "CreateLink",
+  "params": {
+    "HubName_Ex_str": "hubname_ex",
+    "CheckServerCert_bool": false,
+    "AccountName_utf": "clientoption_accountname",
+    "Hostname_str": "clientoption_hostname",
+    "Port_u32": 0,
+    "ProxyType_u32": 0,
+    "HubName_str": "clientoption_hubname",
+    "MaxConnection_u32": 0,
+    "UseEncrypt_bool": false,
+    "UseCompress_bool": false,
+    "HalfConnection_bool": false,
+    "AdditionalConnectionInterval_u32": 0,
+    "ConnectionDisconnectSpan_u32": 0,
+    "AuthType_u32": 0,
+    "Username_str": "clientauth_username",
+    "HashedPassword_bin": "SGVsbG8gV29ybGQ=",
+    "PlainPassword_str": "clientauth_plainpassword",
+    "ClientX_bin": "SGVsbG8gV29ybGQ=",
+    "ClientK_bin": "SGVsbG8gV29ybGQ=",
+    "policy:DHCPFilter_bool": false,
+    "policy:DHCPNoServer_bool": false,
+    "policy:DHCPForce_bool": false,
+    "SecPol_CheckMac_bool": false,
+    "SecPol_CheckIP_bool": false,
+    "policy:ArpDhcpOnly_bool": false,
+    "policy:PrivacyFilter_bool": false,
+    "policy:NoServer_bool": false,
+    "policy:NoBroadcastLimiter_bool": false,
+    "policy:MaxMac_u32": 0,
+    "policy:MaxIP_u32": 0,
+    "policy:MaxUpload_u32": 0,
+    "policy:MaxDownload_u32": 0,
+    "policy:RSandRAFilter_bool": false,
+    "SecPol_RAFilter_bool": false,
+    "policy:DHCPv6Filter_bool": false,
+    "policy:DHCPv6NoServer_bool": false,
+    "SecPol_CheckIPv6_bool": false,
+    "policy:NoServerV6_bool": false,
+    "policy:MaxIPv6_u32": 0,
+    "policy:FilterIPv4_bool": false,
+    "policy:FilterIPv6_bool": false,
+    "policy:FilterNonIP_bool": false,
+    "policy:NoIPv6DefaultRouterInRA_bool": false,
+    "policy:VLanId_u32": 0,
+    "policy:Ver3_bool": false
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_Ex_str": "hubname_ex",
+    "Online_bool": false,
+    "CheckServerCert_bool": false,
+    "ServerCert_bin": "SGVsbG8gV29ybGQ=",
+    "AccountName_utf": "clientoption_accountname",
+    "Hostname_str": "clientoption_hostname",
+    "Port_u32": 0,
+    "ProxyType_u32": 0,
+    "ProxyName_str": "clientoption_proxyname",
+    "ProxyPort_u32": 0,
+    "ProxyUsername_str": "clientoption_proxyusername",
+    "ProxyPassword_str": "clientoption_proxypassword",
+    "HubName_str": "clientoption_hubname",
+    "MaxConnection_u32": 0,
+    "UseEncrypt_bool": false,
+    "UseCompress_bool": false,
+    "HalfConnection_bool": false,
+    "AdditionalConnectionInterval_u32": 0,
+    "ConnectionDisconnectSpan_u32": 0,
+    "DisableQoS_bool": false,
+    "NoTls1_bool": false,
+    "NoUdpAcceleration_bool": false,
+    "AuthType_u32": 0,
+    "Username_str": "clientauth_username",
+    "HashedPassword_bin": "SGVsbG8gV29ybGQ=",
+    "PlainPassword_str": "clientauth_plainpassword",
+    "ClientX_bin": "SGVsbG8gV29ybGQ=",
+    "ClientK_bin": "SGVsbG8gV29ybGQ=",
+    "policy:DHCPFilter_bool": false,
+    "policy:DHCPNoServer_bool": false,
+    "policy:DHCPForce_bool": false,
+    "SecPol_CheckMac_bool": false,
+    "SecPol_CheckIP_bool": false,
+    "policy:ArpDhcpOnly_bool": false,
+    "policy:PrivacyFilter_bool": false,
+    "policy:NoServer_bool": false,
+    "policy:NoBroadcastLimiter_bool": false,
+    "policy:MaxMac_u32": 0,
+    "policy:MaxIP_u32": 0,
+    "policy:MaxUpload_u32": 0,
+    "policy:MaxDownload_u32": 0,
+    "policy:RSandRAFilter_bool": false,
+    "SecPol_RAFilter_bool": false,
+    "policy:DHCPv6Filter_bool": false,
+    "policy:DHCPv6NoServer_bool": false,
+    "SecPol_CheckIPv6_bool": false,
+    "policy:NoServerV6_bool": false,
+    "policy:MaxIPv6_u32": 0,
+    "policy:FilterIPv4_bool": false,
+    "policy:FilterIPv6_bool": false,
+    "policy:FilterNonIP_bool": false,
+    "policy:NoIPv6DefaultRouterInRA_bool": false,
+    "policy:VLanId_u32": 0,
+    "policy:Ver3_bool": false
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_Ex_strstring (ASCII)The Virtual Hub name
Online_boolbooleanOnline flag
CheckServerCert_boolbooleanThe flag to enable validation for the server certificate
ServerCert_binstring (Base64 binary)The body of server X.509 certificate to compare. Valid only if the CheckServerCert_bool flag is true.
AccountName_utfstring (UTF8)Client Option Parameters: Specify the name of the Cascade Connection
Hostname_strstring (ASCII)Client Option Parameters: Specify the hostname of the destination VPN Server. You can also specify by IP address.
Port_u32number (uint32)Client Option Parameters: Specify the port number of the destination VPN Server.
ProxyType_u32number (enum)Client Option Parameters: The type of the proxy server
Values:
0: Direct TCP connection
1: Connection via HTTP proxy server
2: Connection via SOCKS proxy server
ProxyName_strstring (ASCII)Client Option Parameters: The hostname or IP address of the proxy server name
ProxyPort_u32number (uint32)Client Option Parameters: The port number of the proxy server
ProxyUsername_strstring (ASCII)Client Option Parameters: The username to connect to the proxy server
ProxyPassword_strstring (ASCII)Client Option Parameters: The password to connect to the proxy server
HubName_strstring (ASCII)Client Option Parameters: The Virtual Hub on the destination VPN Server
MaxConnection_u32number (uint32)Client Option Parameters: Number of TCP Connections to Use in VPN Communication
UseEncrypt_boolbooleanClient Option Parameters: The flag to enable the encryption on the communication
UseCompress_boolbooleanClient Option Parameters: Enable / Disable Data Compression when Communicating by Cascade Connection
HalfConnection_boolbooleanClient Option Parameters: Specify true when enabling half duplex mode. When using two or more TCP connections for VPN communication, it is possible to use Half Duplex Mode. By enabling half duplex mode it is possible to automatically fix data transmission direction as half and half for each TCP connection. In the case where a VPN using 8 TCP connections is established, for example, when half-duplex is enabled, communication can be fixes so that 4 TCP connections are dedicated to the upload direction and the other 4 connections are dedicated to the download direction.
AdditionalConnectionInterval_u32number (uint32)Client Option Parameters: Connection attempt interval when additional connection will be established
ConnectionDisconnectSpan_u32number (uint32)Client Option Parameters: Connection Life of Each TCP Connection (0 for no keep-alive)
DisableQoS_boolbooleanClient Option Parameters: Disable QoS Control Function if the value is true
NoTls1_boolbooleanClient Option Parameters: Do not use TLS 1.x of the value is true
NoUdpAcceleration_boolbooleanClient Option Parameters: Do not use UDP acceleration mode if the value is true
AuthType_u32number (enum)Authentication type
Values:
0: Anonymous authentication
1: SHA-0 hashed password authentication
2: Plain password authentication
3: Certificate authentication
Username_strstring (ASCII)User name
HashedPassword_binstring (Base64 binary)SHA-0 Hashed password. Valid only if ClientAuth_AuthType_u32 == SHA0_Hashed_Password (1). The SHA-0 hashed password must be caluclated by the SHA0(UpperCase(username_ascii_string) + password_ascii_string).
PlainPassword_strstring (ASCII)Plaintext Password. Valid only if ClientAuth_AuthType_u32 == PlainPassword (2).
ClientX_binstring (Base64 binary)Client certificate. Valid only if ClientAuth_AuthType_u32 == Cert (3).
ClientK_binstring (Base64 binary)Client private key of the certificate. Valid only if ClientAuth_AuthType_u32 == Cert (3).
policy:DHCPFilter_boolbooleanSecurity policy: Filter DHCP Packets (IPv4). All IPv4 DHCP packets in sessions defined this policy will be filtered.
policy:DHCPNoServer_boolbooleanSecurity policy: Disallow DHCP Server Operation (IPv4). Computers connected to sessions that have this policy setting will not be allowed to become a DHCP server and distribute IPv4 addresses to DHCP clients.
policy:DHCPForce_boolbooleanSecurity policy: Enforce DHCP Allocated IP Addresses (IPv4). Computers in sessions that have this policy setting will only be able to use IPv4 addresses allocated by a DHCP server on the virtual network side.
SecPol_CheckMac_boolbooleanSecurity policy: Prohibit the duplicate MAC address
SecPol_CheckIP_boolbooleanSecurity policy: Prohibit a duplicate IP address (IPv4)
policy:ArpDhcpOnly_boolbooleanSecurity policy: Deny Non-ARP / Non-DHCP / Non-ICMPv6 broadcasts. The sending or receiving of broadcast packets that are not ARP protocol, DHCP protocol, nor ICMPv6 on the virtual network will not be allowed for sessions with this policy setting.
policy:PrivacyFilter_boolbooleanSecurity policy: Privacy Filter Mode. All direct communication between sessions with the privacy filter mode policy setting will be filtered.
policy:NoServer_boolbooleanSecurity policy: Deny Operation as TCP/IP Server (IPv4). Computers of sessions with this policy setting can't listen and accept TCP/IP connections in IPv4.
policy:NoBroadcastLimiter_boolbooleanSecurity policy: Unlimited Number of Broadcasts. If a computer of a session with this policy setting sends broadcast packets of a number unusually larger than what would be considered normal on the virtual network, there will be no automatic limiting.
policy:MaxMac_u32number (uint32)Security policy: Maximum Number of MAC Addresses. For sessions with this policy setting, this limits the number of MAC addresses per session.
policy:MaxIP_u32number (uint32)Security policy: Maximum Number of IP Addresses (IPv4). For sessions with this policy setting, this specifies the number of IPv4 addresses that can be registered for a single session.
policy:MaxUpload_u32number (uint32)Security policy: Upload Bandwidth. For sessions with this policy setting, this limits the traffic bandwidth that is in the inwards direction from outside to inside the Virtual Hub.
policy:MaxDownload_u32number (uint32)Security policy: Download Bandwidth. For sessions with this policy setting, this limits the traffic bandwidth that is in the outwards direction from inside the Virtual Hub to outside the Virtual Hub.
policy:RSandRAFilter_boolbooleanSecurity policy: Filter RS / RA Packets (IPv6). All ICMPv6 packets which the message-type is 133 (Router Solicitation) or 134 (Router Advertisement) in sessions defined this policy will be filtered. As a result, an IPv6 client will be unable to use IPv6 address prefix auto detection and IPv6 default gateway auto detection.
SecPol_RAFilter_boolbooleanSecurity policy: Filter the router advertisement packet (IPv6)
policy:DHCPv6Filter_boolbooleanSecurity policy: Filter DHCP Packets (IPv6). All IPv6 DHCP packets in sessions defined this policy will be filtered.
policy:DHCPv6NoServer_boolbooleanSecurity policy: Disallow DHCP Server Operation (IPv6). Computers connected to sessions that have this policy setting will not be allowed to become a DHCP server and distribute IPv6 addresses to DHCP clients.
SecPol_CheckIPv6_boolbooleanSecurity policy: Prohibit the duplicate IP address (IPv6)
policy:NoServerV6_boolbooleanSecurity policy: Deny Operation as TCP/IP Server (IPv6). Computers of sessions with this policy setting can't listen and accept TCP/IP connections in IPv6.
policy:MaxIPv6_u32number (uint32)Security policy: Maximum Number of IP Addresses (IPv6). For sessions with this policy setting, this specifies the number of IPv6 addresses that can be registered for a single session.
policy:FilterIPv4_boolbooleanSecurity policy: Filter All IPv4 Packets. All IPv4 and ARP packets in sessions defined this policy will be filtered.
policy:FilterIPv6_boolbooleanSecurity policy: Filter All IPv6 Packets. All IPv6 packets in sessions defined this policy will be filtered.
policy:FilterNonIP_boolbooleanSecurity policy: Filter All Non-IP Packets. All non-IP packets in sessions defined this policy will be filtered. "Non-IP packet" mean a packet which is not IPv4, ARP nor IPv6. Any tagged-VLAN packets via the Virtual Hub will be regarded as non-IP packets.
policy:NoIPv6DefaultRouterInRA_boolbooleanSecurity policy: No Default-Router on IPv6 RA. In all VPN Sessions defines this policy, any IPv6 RA (Router Advertisement) packet with non-zero value in the router-lifetime will set to zero-value. This is effective to avoid the horrible behavior from the IPv6 routing confusion which is caused by the VPN client's attempts to use the remote-side IPv6 router as its local IPv6 router.
policy:VLanId_u32number (uint32)Security policy: VLAN ID (IEEE802.1Q). You can specify the VLAN ID on the security policy. All VPN Sessions defines this policy, all Ethernet packets toward the Virtual Hub from the user will be inserted a VLAN tag (IEEE 802.1Q) with the VLAN ID. The user can also receive only packets with a VLAN tag which has the same VLAN ID. (Receiving process removes the VLAN tag automatically.) Any Ethernet packets with any other VLAN IDs or non-VLAN packets will not be received. All VPN Sessions without this policy definition can send / receive any kinds of Ethernet packets regardless of VLAN tags, and VLAN tags are not inserted or removed automatically. Any tagged-VLAN packets via the Virtual Hub will be regarded as non-IP packets. Therefore, tagged-VLAN packets are not subjects for IPv4 / IPv6 security policies, access lists nor other IPv4 / IPv6 specific deep processing.
policy:Ver3_boolbooleanSecurity policy: Whether version 3.0 (must be true)
+
+

+ +

Description

+

Get the Cascade Connection Setting. Use this to get the Connection Setting of a Cascade Connection that is registered on the currently managed Virtual Hub. To change the Connection Setting contents of the Cascade Connection, use the APIs that include the name "Link" after creating the Cascade Connection. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetLink",
+  "params": {
+    "HubName_Ex_str": "hubname_ex",
+    "AccountName_utf": "clientoption_accountname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_Ex_str": "hubname_ex",
+    "Online_bool": false,
+    "CheckServerCert_bool": false,
+    "ServerCert_bin": "SGVsbG8gV29ybGQ=",
+    "AccountName_utf": "clientoption_accountname",
+    "Hostname_str": "clientoption_hostname",
+    "Port_u32": 0,
+    "ProxyType_u32": 0,
+    "ProxyName_str": "clientoption_proxyname",
+    "ProxyPort_u32": 0,
+    "ProxyUsername_str": "clientoption_proxyusername",
+    "ProxyPassword_str": "clientoption_proxypassword",
+    "HubName_str": "clientoption_hubname",
+    "MaxConnection_u32": 0,
+    "UseEncrypt_bool": false,
+    "UseCompress_bool": false,
+    "HalfConnection_bool": false,
+    "AdditionalConnectionInterval_u32": 0,
+    "ConnectionDisconnectSpan_u32": 0,
+    "DisableQoS_bool": false,
+    "NoTls1_bool": false,
+    "NoUdpAcceleration_bool": false,
+    "AuthType_u32": 0,
+    "Username_str": "clientauth_username",
+    "HashedPassword_bin": "SGVsbG8gV29ybGQ=",
+    "PlainPassword_str": "clientauth_plainpassword",
+    "ClientX_bin": "SGVsbG8gV29ybGQ=",
+    "ClientK_bin": "SGVsbG8gV29ybGQ=",
+    "policy:DHCPFilter_bool": false,
+    "policy:DHCPNoServer_bool": false,
+    "policy:DHCPForce_bool": false,
+    "SecPol_CheckMac_bool": false,
+    "SecPol_CheckIP_bool": false,
+    "policy:ArpDhcpOnly_bool": false,
+    "policy:PrivacyFilter_bool": false,
+    "policy:NoServer_bool": false,
+    "policy:NoBroadcastLimiter_bool": false,
+    "policy:MaxMac_u32": 0,
+    "policy:MaxIP_u32": 0,
+    "policy:MaxUpload_u32": 0,
+    "policy:MaxDownload_u32": 0,
+    "policy:RSandRAFilter_bool": false,
+    "SecPol_RAFilter_bool": false,
+    "policy:DHCPv6Filter_bool": false,
+    "policy:DHCPv6NoServer_bool": false,
+    "SecPol_CheckIPv6_bool": false,
+    "policy:NoServerV6_bool": false,
+    "policy:MaxIPv6_u32": 0,
+    "policy:FilterIPv4_bool": false,
+    "policy:FilterIPv6_bool": false,
+    "policy:FilterNonIP_bool": false,
+    "policy:NoIPv6DefaultRouterInRA_bool": false,
+    "policy:VLanId_u32": 0,
+    "policy:Ver3_bool": false
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_Ex_strstring (ASCII)The Virtual Hub name
Online_boolbooleanOnline flag
CheckServerCert_boolbooleanThe flag to enable validation for the server certificate
ServerCert_binstring (Base64 binary)The body of server X.509 certificate to compare. Valid only if the CheckServerCert_bool flag is true.
AccountName_utfstring (UTF8)Client Option Parameters: Specify the name of the Cascade Connection
Hostname_strstring (ASCII)Client Option Parameters: Specify the hostname of the destination VPN Server. You can also specify by IP address.
Port_u32number (uint32)Client Option Parameters: Specify the port number of the destination VPN Server.
ProxyType_u32number (enum)Client Option Parameters: The type of the proxy server
Values:
0: Direct TCP connection
1: Connection via HTTP proxy server
2: Connection via SOCKS proxy server
ProxyName_strstring (ASCII)Client Option Parameters: The hostname or IP address of the proxy server name
ProxyPort_u32number (uint32)Client Option Parameters: The port number of the proxy server
ProxyUsername_strstring (ASCII)Client Option Parameters: The username to connect to the proxy server
ProxyPassword_strstring (ASCII)Client Option Parameters: The password to connect to the proxy server
HubName_strstring (ASCII)Client Option Parameters: The Virtual Hub on the destination VPN Server
MaxConnection_u32number (uint32)Client Option Parameters: Number of TCP Connections to Use in VPN Communication
UseEncrypt_boolbooleanClient Option Parameters: The flag to enable the encryption on the communication
UseCompress_boolbooleanClient Option Parameters: Enable / Disable Data Compression when Communicating by Cascade Connection
HalfConnection_boolbooleanClient Option Parameters: Specify true when enabling half duplex mode. When using two or more TCP connections for VPN communication, it is possible to use Half Duplex Mode. By enabling half duplex mode it is possible to automatically fix data transmission direction as half and half for each TCP connection. In the case where a VPN using 8 TCP connections is established, for example, when half-duplex is enabled, communication can be fixes so that 4 TCP connections are dedicated to the upload direction and the other 4 connections are dedicated to the download direction.
AdditionalConnectionInterval_u32number (uint32)Client Option Parameters: Connection attempt interval when additional connection will be established
ConnectionDisconnectSpan_u32number (uint32)Client Option Parameters: Connection Life of Each TCP Connection (0 for no keep-alive)
DisableQoS_boolbooleanClient Option Parameters: Disable QoS Control Function if the value is true
NoTls1_boolbooleanClient Option Parameters: Do not use TLS 1.x of the value is true
NoUdpAcceleration_boolbooleanClient Option Parameters: Do not use UDP acceleration mode if the value is true
AuthType_u32number (enum)Authentication type
Values:
0: Anonymous authentication
1: SHA-0 hashed password authentication
2: Plain password authentication
3: Certificate authentication
Username_strstring (ASCII)User name
HashedPassword_binstring (Base64 binary)SHA-0 Hashed password. Valid only if ClientAuth_AuthType_u32 == SHA0_Hashed_Password (1). The SHA-0 hashed password must be caluclated by the SHA0(UpperCase(username_ascii_string) + password_ascii_string).
PlainPassword_strstring (ASCII)Plaintext Password. Valid only if ClientAuth_AuthType_u32 == PlainPassword (2).
ClientX_binstring (Base64 binary)Client certificate. Valid only if ClientAuth_AuthType_u32 == Cert (3).
ClientK_binstring (Base64 binary)Client private key of the certificate. Valid only if ClientAuth_AuthType_u32 == Cert (3).
policy:DHCPFilter_boolbooleanSecurity policy: Filter DHCP Packets (IPv4). All IPv4 DHCP packets in sessions defined this policy will be filtered.
policy:DHCPNoServer_boolbooleanSecurity policy: Disallow DHCP Server Operation (IPv4). Computers connected to sessions that have this policy setting will not be allowed to become a DHCP server and distribute IPv4 addresses to DHCP clients.
policy:DHCPForce_boolbooleanSecurity policy: Enforce DHCP Allocated IP Addresses (IPv4). Computers in sessions that have this policy setting will only be able to use IPv4 addresses allocated by a DHCP server on the virtual network side.
SecPol_CheckMac_boolbooleanSecurity policy: Prohibit the duplicate MAC address
SecPol_CheckIP_boolbooleanSecurity policy: Prohibit a duplicate IP address (IPv4)
policy:ArpDhcpOnly_boolbooleanSecurity policy: Deny Non-ARP / Non-DHCP / Non-ICMPv6 broadcasts. The sending or receiving of broadcast packets that are not ARP protocol, DHCP protocol, nor ICMPv6 on the virtual network will not be allowed for sessions with this policy setting.
policy:PrivacyFilter_boolbooleanSecurity policy: Privacy Filter Mode. All direct communication between sessions with the privacy filter mode policy setting will be filtered.
policy:NoServer_boolbooleanSecurity policy: Deny Operation as TCP/IP Server (IPv4). Computers of sessions with this policy setting can't listen and accept TCP/IP connections in IPv4.
policy:NoBroadcastLimiter_boolbooleanSecurity policy: Unlimited Number of Broadcasts. If a computer of a session with this policy setting sends broadcast packets of a number unusually larger than what would be considered normal on the virtual network, there will be no automatic limiting.
policy:MaxMac_u32number (uint32)Security policy: Maximum Number of MAC Addresses. For sessions with this policy setting, this limits the number of MAC addresses per session.
policy:MaxIP_u32number (uint32)Security policy: Maximum Number of IP Addresses (IPv4). For sessions with this policy setting, this specifies the number of IPv4 addresses that can be registered for a single session.
policy:MaxUpload_u32number (uint32)Security policy: Upload Bandwidth. For sessions with this policy setting, this limits the traffic bandwidth that is in the inwards direction from outside to inside the Virtual Hub.
policy:MaxDownload_u32number (uint32)Security policy: Download Bandwidth. For sessions with this policy setting, this limits the traffic bandwidth that is in the outwards direction from inside the Virtual Hub to outside the Virtual Hub.
policy:RSandRAFilter_boolbooleanSecurity policy: Filter RS / RA Packets (IPv6). All ICMPv6 packets which the message-type is 133 (Router Solicitation) or 134 (Router Advertisement) in sessions defined this policy will be filtered. As a result, an IPv6 client will be unable to use IPv6 address prefix auto detection and IPv6 default gateway auto detection.
SecPol_RAFilter_boolbooleanSecurity policy: Filter the router advertisement packet (IPv6)
policy:DHCPv6Filter_boolbooleanSecurity policy: Filter DHCP Packets (IPv6). All IPv6 DHCP packets in sessions defined this policy will be filtered.
policy:DHCPv6NoServer_boolbooleanSecurity policy: Disallow DHCP Server Operation (IPv6). Computers connected to sessions that have this policy setting will not be allowed to become a DHCP server and distribute IPv6 addresses to DHCP clients.
SecPol_CheckIPv6_boolbooleanSecurity policy: Prohibit the duplicate IP address (IPv6)
policy:NoServerV6_boolbooleanSecurity policy: Deny Operation as TCP/IP Server (IPv6). Computers of sessions with this policy setting can't listen and accept TCP/IP connections in IPv6.
policy:MaxIPv6_u32number (uint32)Security policy: Maximum Number of IP Addresses (IPv6). For sessions with this policy setting, this specifies the number of IPv6 addresses that can be registered for a single session.
policy:FilterIPv4_boolbooleanSecurity policy: Filter All IPv4 Packets. All IPv4 and ARP packets in sessions defined this policy will be filtered.
policy:FilterIPv6_boolbooleanSecurity policy: Filter All IPv6 Packets. All IPv6 packets in sessions defined this policy will be filtered.
policy:FilterNonIP_boolbooleanSecurity policy: Filter All Non-IP Packets. All non-IP packets in sessions defined this policy will be filtered. "Non-IP packet" mean a packet which is not IPv4, ARP nor IPv6. Any tagged-VLAN packets via the Virtual Hub will be regarded as non-IP packets.
policy:NoIPv6DefaultRouterInRA_boolbooleanSecurity policy: No Default-Router on IPv6 RA. In all VPN Sessions defines this policy, any IPv6 RA (Router Advertisement) packet with non-zero value in the router-lifetime will set to zero-value. This is effective to avoid the horrible behavior from the IPv6 routing confusion which is caused by the VPN client's attempts to use the remote-side IPv6 router as its local IPv6 router.
policy:VLanId_u32number (uint32)Security policy: VLAN ID (IEEE802.1Q). You can specify the VLAN ID on the security policy. All VPN Sessions defines this policy, all Ethernet packets toward the Virtual Hub from the user will be inserted a VLAN tag (IEEE 802.1Q) with the VLAN ID. The user can also receive only packets with a VLAN tag which has the same VLAN ID. (Receiving process removes the VLAN tag automatically.) Any Ethernet packets with any other VLAN IDs or non-VLAN packets will not be received. All VPN Sessions without this policy definition can send / receive any kinds of Ethernet packets regardless of VLAN tags, and VLAN tags are not inserted or removed automatically. Any tagged-VLAN packets via the Virtual Hub will be regarded as non-IP packets. Therefore, tagged-VLAN packets are not subjects for IPv4 / IPv6 security policies, access lists nor other IPv4 / IPv6 specific deep processing.
policy:Ver3_boolbooleanSecurity policy: Whether version 3.0 (must be true)
+
+

+ +

Description

+

Change Existing Cascade Connection. Use this to alter the setting of an existing Cascade Connection on the currently managed Virtual Hub.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetLink",
+  "params": {
+    "HubName_Ex_str": "hubname_ex",
+    "CheckServerCert_bool": false,
+    "AccountName_utf": "clientoption_accountname",
+    "Hostname_str": "clientoption_hostname",
+    "Port_u32": 0,
+    "ProxyType_u32": 0,
+    "HubName_str": "clientoption_hubname",
+    "MaxConnection_u32": 0,
+    "UseEncrypt_bool": false,
+    "UseCompress_bool": false,
+    "HalfConnection_bool": false,
+    "AdditionalConnectionInterval_u32": 0,
+    "ConnectionDisconnectSpan_u32": 0,
+    "AuthType_u32": 0,
+    "Username_str": "clientauth_username",
+    "HashedPassword_bin": "SGVsbG8gV29ybGQ=",
+    "PlainPassword_str": "clientauth_plainpassword",
+    "ClientX_bin": "SGVsbG8gV29ybGQ=",
+    "ClientK_bin": "SGVsbG8gV29ybGQ=",
+    "policy:DHCPFilter_bool": false,
+    "policy:DHCPNoServer_bool": false,
+    "policy:DHCPForce_bool": false,
+    "SecPol_CheckMac_bool": false,
+    "SecPol_CheckIP_bool": false,
+    "policy:ArpDhcpOnly_bool": false,
+    "policy:PrivacyFilter_bool": false,
+    "policy:NoServer_bool": false,
+    "policy:NoBroadcastLimiter_bool": false,
+    "policy:MaxMac_u32": 0,
+    "policy:MaxIP_u32": 0,
+    "policy:MaxUpload_u32": 0,
+    "policy:MaxDownload_u32": 0,
+    "policy:RSandRAFilter_bool": false,
+    "SecPol_RAFilter_bool": false,
+    "policy:DHCPv6Filter_bool": false,
+    "policy:DHCPv6NoServer_bool": false,
+    "SecPol_CheckIPv6_bool": false,
+    "policy:NoServerV6_bool": false,
+    "policy:MaxIPv6_u32": 0,
+    "policy:FilterIPv4_bool": false,
+    "policy:FilterIPv6_bool": false,
+    "policy:FilterNonIP_bool": false,
+    "policy:NoIPv6DefaultRouterInRA_bool": false,
+    "policy:VLanId_u32": 0,
+    "policy:Ver3_bool": false
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_Ex_str": "hubname_ex",
+    "Online_bool": false,
+    "CheckServerCert_bool": false,
+    "ServerCert_bin": "SGVsbG8gV29ybGQ=",
+    "AccountName_utf": "clientoption_accountname",
+    "Hostname_str": "clientoption_hostname",
+    "Port_u32": 0,
+    "ProxyType_u32": 0,
+    "ProxyName_str": "clientoption_proxyname",
+    "ProxyPort_u32": 0,
+    "ProxyUsername_str": "clientoption_proxyusername",
+    "ProxyPassword_str": "clientoption_proxypassword",
+    "HubName_str": "clientoption_hubname",
+    "MaxConnection_u32": 0,
+    "UseEncrypt_bool": false,
+    "UseCompress_bool": false,
+    "HalfConnection_bool": false,
+    "AdditionalConnectionInterval_u32": 0,
+    "ConnectionDisconnectSpan_u32": 0,
+    "DisableQoS_bool": false,
+    "NoTls1_bool": false,
+    "NoUdpAcceleration_bool": false,
+    "AuthType_u32": 0,
+    "Username_str": "clientauth_username",
+    "HashedPassword_bin": "SGVsbG8gV29ybGQ=",
+    "PlainPassword_str": "clientauth_plainpassword",
+    "ClientX_bin": "SGVsbG8gV29ybGQ=",
+    "ClientK_bin": "SGVsbG8gV29ybGQ=",
+    "policy:DHCPFilter_bool": false,
+    "policy:DHCPNoServer_bool": false,
+    "policy:DHCPForce_bool": false,
+    "SecPol_CheckMac_bool": false,
+    "SecPol_CheckIP_bool": false,
+    "policy:ArpDhcpOnly_bool": false,
+    "policy:PrivacyFilter_bool": false,
+    "policy:NoServer_bool": false,
+    "policy:NoBroadcastLimiter_bool": false,
+    "policy:MaxMac_u32": 0,
+    "policy:MaxIP_u32": 0,
+    "policy:MaxUpload_u32": 0,
+    "policy:MaxDownload_u32": 0,
+    "policy:RSandRAFilter_bool": false,
+    "SecPol_RAFilter_bool": false,
+    "policy:DHCPv6Filter_bool": false,
+    "policy:DHCPv6NoServer_bool": false,
+    "SecPol_CheckIPv6_bool": false,
+    "policy:NoServerV6_bool": false,
+    "policy:MaxIPv6_u32": 0,
+    "policy:FilterIPv4_bool": false,
+    "policy:FilterIPv6_bool": false,
+    "policy:FilterNonIP_bool": false,
+    "policy:NoIPv6DefaultRouterInRA_bool": false,
+    "policy:VLanId_u32": 0,
+    "policy:Ver3_bool": false
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_Ex_strstring (ASCII)The Virtual Hub name
Online_boolbooleanOnline flag
CheckServerCert_boolbooleanThe flag to enable validation for the server certificate
ServerCert_binstring (Base64 binary)The body of server X.509 certificate to compare. Valid only if the CheckServerCert_bool flag is true.
AccountName_utfstring (UTF8)Client Option Parameters: Specify the name of the Cascade Connection
Hostname_strstring (ASCII)Client Option Parameters: Specify the hostname of the destination VPN Server. You can also specify by IP address.
Port_u32number (uint32)Client Option Parameters: Specify the port number of the destination VPN Server.
ProxyType_u32number (enum)Client Option Parameters: The type of the proxy server
Values:
0: Direct TCP connection
1: Connection via HTTP proxy server
2: Connection via SOCKS proxy server
ProxyName_strstring (ASCII)Client Option Parameters: The hostname or IP address of the proxy server name
ProxyPort_u32number (uint32)Client Option Parameters: The port number of the proxy server
ProxyUsername_strstring (ASCII)Client Option Parameters: The username to connect to the proxy server
ProxyPassword_strstring (ASCII)Client Option Parameters: The password to connect to the proxy server
HubName_strstring (ASCII)Client Option Parameters: The Virtual Hub on the destination VPN Server
MaxConnection_u32number (uint32)Client Option Parameters: Number of TCP Connections to Use in VPN Communication
UseEncrypt_boolbooleanClient Option Parameters: The flag to enable the encryption on the communication
UseCompress_boolbooleanClient Option Parameters: Enable / Disable Data Compression when Communicating by Cascade Connection
HalfConnection_boolbooleanClient Option Parameters: Specify true when enabling half duplex mode. When using two or more TCP connections for VPN communication, it is possible to use Half Duplex Mode. By enabling half duplex mode it is possible to automatically fix data transmission direction as half and half for each TCP connection. In the case where a VPN using 8 TCP connections is established, for example, when half-duplex is enabled, communication can be fixes so that 4 TCP connections are dedicated to the upload direction and the other 4 connections are dedicated to the download direction.
AdditionalConnectionInterval_u32number (uint32)Client Option Parameters: Connection attempt interval when additional connection will be established
ConnectionDisconnectSpan_u32number (uint32)Client Option Parameters: Connection Life of Each TCP Connection (0 for no keep-alive)
DisableQoS_boolbooleanClient Option Parameters: Disable QoS Control Function if the value is true
NoTls1_boolbooleanClient Option Parameters: Do not use TLS 1.x of the value is true
NoUdpAcceleration_boolbooleanClient Option Parameters: Do not use UDP acceleration mode if the value is true
AuthType_u32number (enum)Authentication type
Values:
0: Anonymous authentication
1: SHA-0 hashed password authentication
2: Plain password authentication
3: Certificate authentication
Username_strstring (ASCII)User name
HashedPassword_binstring (Base64 binary)SHA-0 Hashed password. Valid only if ClientAuth_AuthType_u32 == SHA0_Hashed_Password (1). The SHA-0 hashed password must be caluclated by the SHA0(UpperCase(username_ascii_string) + password_ascii_string).
PlainPassword_strstring (ASCII)Plaintext Password. Valid only if ClientAuth_AuthType_u32 == PlainPassword (2).
ClientX_binstring (Base64 binary)Client certificate. Valid only if ClientAuth_AuthType_u32 == Cert (3).
ClientK_binstring (Base64 binary)Client private key of the certificate. Valid only if ClientAuth_AuthType_u32 == Cert (3).
policy:DHCPFilter_boolbooleanSecurity policy: Filter DHCP Packets (IPv4). All IPv4 DHCP packets in sessions defined this policy will be filtered.
policy:DHCPNoServer_boolbooleanSecurity policy: Disallow DHCP Server Operation (IPv4). Computers connected to sessions that have this policy setting will not be allowed to become a DHCP server and distribute IPv4 addresses to DHCP clients.
policy:DHCPForce_boolbooleanSecurity policy: Enforce DHCP Allocated IP Addresses (IPv4). Computers in sessions that have this policy setting will only be able to use IPv4 addresses allocated by a DHCP server on the virtual network side.
SecPol_CheckMac_boolbooleanSecurity policy: Prohibit the duplicate MAC address
SecPol_CheckIP_boolbooleanSecurity policy: Prohibit a duplicate IP address (IPv4)
policy:ArpDhcpOnly_boolbooleanSecurity policy: Deny Non-ARP / Non-DHCP / Non-ICMPv6 broadcasts. The sending or receiving of broadcast packets that are not ARP protocol, DHCP protocol, nor ICMPv6 on the virtual network will not be allowed for sessions with this policy setting.
policy:PrivacyFilter_boolbooleanSecurity policy: Privacy Filter Mode. All direct communication between sessions with the privacy filter mode policy setting will be filtered.
policy:NoServer_boolbooleanSecurity policy: Deny Operation as TCP/IP Server (IPv4). Computers of sessions with this policy setting can't listen and accept TCP/IP connections in IPv4.
policy:NoBroadcastLimiter_boolbooleanSecurity policy: Unlimited Number of Broadcasts. If a computer of a session with this policy setting sends broadcast packets of a number unusually larger than what would be considered normal on the virtual network, there will be no automatic limiting.
policy:MaxMac_u32number (uint32)Security policy: Maximum Number of MAC Addresses. For sessions with this policy setting, this limits the number of MAC addresses per session.
policy:MaxIP_u32number (uint32)Security policy: Maximum Number of IP Addresses (IPv4). For sessions with this policy setting, this specifies the number of IPv4 addresses that can be registered for a single session.
policy:MaxUpload_u32number (uint32)Security policy: Upload Bandwidth. For sessions with this policy setting, this limits the traffic bandwidth that is in the inwards direction from outside to inside the Virtual Hub.
policy:MaxDownload_u32number (uint32)Security policy: Download Bandwidth. For sessions with this policy setting, this limits the traffic bandwidth that is in the outwards direction from inside the Virtual Hub to outside the Virtual Hub.
policy:RSandRAFilter_boolbooleanSecurity policy: Filter RS / RA Packets (IPv6). All ICMPv6 packets which the message-type is 133 (Router Solicitation) or 134 (Router Advertisement) in sessions defined this policy will be filtered. As a result, an IPv6 client will be unable to use IPv6 address prefix auto detection and IPv6 default gateway auto detection.
SecPol_RAFilter_boolbooleanSecurity policy: Filter the router advertisement packet (IPv6)
policy:DHCPv6Filter_boolbooleanSecurity policy: Filter DHCP Packets (IPv6). All IPv6 DHCP packets in sessions defined this policy will be filtered.
policy:DHCPv6NoServer_boolbooleanSecurity policy: Disallow DHCP Server Operation (IPv6). Computers connected to sessions that have this policy setting will not be allowed to become a DHCP server and distribute IPv6 addresses to DHCP clients.
SecPol_CheckIPv6_boolbooleanSecurity policy: Prohibit the duplicate IP address (IPv6)
policy:NoServerV6_boolbooleanSecurity policy: Deny Operation as TCP/IP Server (IPv6). Computers of sessions with this policy setting can't listen and accept TCP/IP connections in IPv6.
policy:MaxIPv6_u32number (uint32)Security policy: Maximum Number of IP Addresses (IPv6). For sessions with this policy setting, this specifies the number of IPv6 addresses that can be registered for a single session.
policy:FilterIPv4_boolbooleanSecurity policy: Filter All IPv4 Packets. All IPv4 and ARP packets in sessions defined this policy will be filtered.
policy:FilterIPv6_boolbooleanSecurity policy: Filter All IPv6 Packets. All IPv6 packets in sessions defined this policy will be filtered.
policy:FilterNonIP_boolbooleanSecurity policy: Filter All Non-IP Packets. All non-IP packets in sessions defined this policy will be filtered. "Non-IP packet" mean a packet which is not IPv4, ARP nor IPv6. Any tagged-VLAN packets via the Virtual Hub will be regarded as non-IP packets.
policy:NoIPv6DefaultRouterInRA_boolbooleanSecurity policy: No Default-Router on IPv6 RA. In all VPN Sessions defines this policy, any IPv6 RA (Router Advertisement) packet with non-zero value in the router-lifetime will set to zero-value. This is effective to avoid the horrible behavior from the IPv6 routing confusion which is caused by the VPN client's attempts to use the remote-side IPv6 router as its local IPv6 router.
policy:VLanId_u32number (uint32)Security policy: VLAN ID (IEEE802.1Q). You can specify the VLAN ID on the security policy. All VPN Sessions defines this policy, all Ethernet packets toward the Virtual Hub from the user will be inserted a VLAN tag (IEEE 802.1Q) with the VLAN ID. The user can also receive only packets with a VLAN tag which has the same VLAN ID. (Receiving process removes the VLAN tag automatically.) Any Ethernet packets with any other VLAN IDs or non-VLAN packets will not be received. All VPN Sessions without this policy definition can send / receive any kinds of Ethernet packets regardless of VLAN tags, and VLAN tags are not inserted or removed automatically. Any tagged-VLAN packets via the Virtual Hub will be regarded as non-IP packets. Therefore, tagged-VLAN packets are not subjects for IPv4 / IPv6 security policies, access lists nor other IPv4 / IPv6 specific deep processing.
policy:Ver3_boolbooleanSecurity policy: Whether version 3.0 (must be true)
+
+

+ +

Description

+

Get List of Cascade Connections. Use this to get a list of Cascade Connections that are registered on the currently managed Virtual Hub. By using a Cascade Connection, you can connect this Virtual Hub by Layer 2 Cascade Connection to another Virtual Hub that is operating on the same or a different computer. [Warning About Cascade Connections] By connecting using a Cascade Connection you can create a Layer 2 bridge between multiple Virtual Hubs but if the connection is incorrectly configured, a loopback Cascade Connection could inadvertently be created. When using a Cascade Connection function please design the network topology with care. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "EnumLink",
+  "params": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "NumLink_u32": 0,
+    "LinkList": [
+      {
+        "AccountName_utf": "accountname",
+        "Online_bool": false,
+        "Connected_bool": false,
+        "LastError_u32": 0,
+        "ConnectedTime_dt": "2020-08-01T12:24:36.123",
+        "Hostname_str": "hostname",
+        "TargetHubName_str": "targethubname"
+      },
+      {
+        "AccountName_utf": "accountname",
+        "Online_bool": false,
+        "Connected_bool": false,
+        "LastError_u32": 0,
+        "ConnectedTime_dt": "2020-08-01T12:24:36.123",
+        "Hostname_str": "hostname",
+        "TargetHubName_str": "targethubname"
+      },
+      {
+        "AccountName_utf": "accountname",
+        "Online_bool": false,
+        "Connected_bool": false,
+        "LastError_u32": 0,
+        "ConnectedTime_dt": "2020-08-01T12:24:36.123",
+        "Hostname_str": "hostname",
+        "TargetHubName_str": "targethubname"
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
NumLink_u32number (uint32)Number of cascade connections
LinkListArray objectThe list of cascade connections
AccountName_utfstring (UTF8)The name of cascade connection
Online_boolbooleanOnline flag
Connected_boolbooleanThe flag indicates whether the cascade connection is established
LastError_u32number (uint32)The error last occurred if the cascade connection is in the fail state
ConnectedTime_dtDateConnection completion time
Hostname_strstring (ASCII)Host name of the destination VPN server
TargetHubName_strstring (ASCII)The Virtual Hub name
+
+

+

"SetLinkOnline" RPC API - Switch Cascade Connection to Online Status

+

Description

+

Switch Cascade Connection to Online Status. When a Cascade Connection registered on the currently managed Virtual Hub is specified, use this to switch that Cascade Connection to online status. The Cascade Connection that is switched to online status begins the process of connecting to the destination VPN Server in accordance with the Connection Setting. The Cascade Connection that is switched to online status will establish normal connection to the VPN Server or continue to attempt connection until it is switched to offline status. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetLinkOnline",
+  "params": {
+    "HubName_str": "hubname",
+    "AccountName_utf": "accountname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "AccountName_utf": "accountname"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
AccountName_utfstring (UTF8)The name of the cascade connection
+
+

+

"SetLinkOffline" RPC API - Switch Cascade Connection to Offline Status

+

Description

+

Switch Cascade Connection to Offline Status. When a Cascade Connection registered on the currently managed Virtual Hub is specified, use this to switch that Cascade Connection to offline status. The Cascade Connection that is switched to offline will not connect to the VPN Server until next time it is switched to the online status using the SetLinkOnline API You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetLinkOffline",
+  "params": {
+    "HubName_str": "hubname",
+    "AccountName_utf": "accountname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "AccountName_utf": "accountname"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
AccountName_utfstring (UTF8)The name of the cascade connection
+
+

+ +

Description

+

Delete Cascade Connection Setting. Use this to delete a Cascade Connection that is registered on the currently managed Virtual Hub. If the specified Cascade Connection has a status of online, the connections will be automatically disconnected and then the Cascade Connection will be deleted. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "DeleteLink",
+  "params": {
+    "HubName_str": "hubname",
+    "AccountName_utf": "accountname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "AccountName_utf": "accountname"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
AccountName_utfstring (UTF8)The name of the cascade connection
+
+

+ +

Description

+

Change Name of Cascade Connection. When a Cascade Connection registered on the currently managed Virtual Hub is specified, use this to change the name of that Cascade Connection. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "RenameLink",
+  "params": {
+    "HubName_str": "hubname",
+    "OldAccountName_utf": "oldaccountname",
+    "NewAccountName_utf": "newaccountname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "OldAccountName_utf": "oldaccountname",
+    "NewAccountName_utf": "newaccountname"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
OldAccountName_utfstring (UTF8)The old name of the cascade connection
NewAccountName_utfstring (UTF8)The new name of the cascade connection
+
+

+

"GetLinkStatus" RPC API - Get Current Cascade Connection Status

+

Description

+

Get Current Cascade Connection Status. When a Cascade Connection registered on the currently managed Virtual Hub is specified and that Cascade Connection is currently online, use this to get its connection status and other information. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetLinkStatus",
+  "params": {
+    "HubName_Ex_str": "hubname_ex",
+    "AccountName_utf": "accountname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_Ex_str": "hubname_ex",
+    "AccountName_utf": "accountname",
+    "Active_bool": false,
+    "Connected_bool": false,
+    "SessionStatus_u32": 0,
+    "ServerName_str": "servername",
+    "ServerPort_u32": 0,
+    "ServerProductName_str": "serverproductname",
+    "ServerProductVer_u32": 0,
+    "ServerProductBuild_u32": 0,
+    "ServerX_bin": "SGVsbG8gV29ybGQ=",
+    "ClientX_bin": "SGVsbG8gV29ybGQ=",
+    "StartTime_dt": "2020-08-01T12:24:36.123",
+    "FirstConnectionEstablisiedTime_dt": "2020-08-01T12:24:36.123",
+    "CurrentConnectionEstablishTime_dt": "2020-08-01T12:24:36.123",
+    "NumConnectionsEatablished_u32": 0,
+    "HalfConnection_bool": false,
+    "QoS_bool": false,
+    "MaxTcpConnections_u32": 0,
+    "NumTcpConnections_u32": 0,
+    "NumTcpConnectionsUpload_u32": 0,
+    "NumTcpConnectionsDownload_u32": 0,
+    "UseEncrypt_bool": false,
+    "CipherName_str": "ciphername",
+    "UseCompress_bool": false,
+    "IsRUDPSession_bool": false,
+    "UnderlayProtocol_str": "underlayprotocol",
+    "IsUdpAccelerationEnabled_bool": false,
+    "IsUsingUdpAcceleration_bool": false,
+    "SessionName_str": "sessionname",
+    "ConnectionName_str": "connectionname",
+    "SessionKey_bin": "SGVsbG8gV29ybGQ=",
+    "TotalSendSize_u64": 0,
+    "TotalRecvSize_u64": 0,
+    "TotalSendSizeReal_u64": 0,
+    "TotalRecvSizeReal_u64": 0,
+    "IsBridgeMode_bool": false,
+    "IsMonitorMode_bool": false,
+    "VLanId_u32": 0
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_Ex_strstring (ASCII)The Virtual Hub name
AccountName_utfstring (UTF8)The name of the cascade connection
Active_boolbooleanThe flag whether the cascade connection is enabled
Connected_boolbooleanThe flag whether the cascade connection is established
SessionStatus_u32number (enum)The session status
Values:
0: Connecting
1: Negotiating
2: During user authentication
3: Connection complete
4: Wait to retry
5: Idle state
ServerName_strstring (ASCII)The destination VPN server name
ServerPort_u32number (uint32)The port number of the server
ServerProductName_strstring (ASCII)Server product name
ServerProductVer_u32number (uint32)Server product version
ServerProductBuild_u32number (uint32)Server product build number
ServerX_binstring (Base64 binary)Server's X.509 certificate
ClientX_binstring (Base64 binary)Client certificate
StartTime_dtDateConnection start time
FirstConnectionEstablisiedTime_dtDateConnection completion time of the first connection
CurrentConnectionEstablishTime_dtDateConnection completion time of this connection
NumConnectionsEatablished_u32number (uint32)Number of connections have been established so far
HalfConnection_boolbooleanHalf-connection
QoS_boolbooleanVoIP / QoS
MaxTcpConnections_u32number (uint32)Maximum number of the underlying TCP connections
NumTcpConnections_u32number (uint32)Number of current underlying TCP connections
NumTcpConnectionsUpload_u32number (uint32)Number of underlying inbound TCP connections
NumTcpConnectionsDownload_u32number (uint32)Number of underlying outbound TCP connections
UseEncrypt_boolbooleanUse of encryption
CipherName_strstring (ASCII)Cipher algorithm name
UseCompress_boolbooleanUse of compression
IsRUDPSession_boolbooleanThe flag whether this is a R-UDP session
UnderlayProtocol_strstring (ASCII)Underlying physical communication protocol
IsUdpAccelerationEnabled_boolbooleanThe UDP acceleration is enabled
IsUsingUdpAcceleration_boolbooleanThe UDP acceleration is being actually used
SessionName_strstring (ASCII)Session name
ConnectionName_strstring (ASCII)Connection name
SessionKey_binstring (Base64 binary)Session key
TotalSendSize_u64number (uint64)Total transmitted data size
TotalRecvSize_u64number (uint64)Total received data size
TotalSendSizeReal_u64number (uint64)Total transmitted data size (no compression)
TotalRecvSizeReal_u64number (uint64)Total received data size (no compression)
IsBridgeMode_boolbooleanThe flag whether the VPN session is Bridge Mode
IsMonitorMode_boolbooleanThe flag whether the VPN session is Monitor mode
VLanId_u32number (uint32)VLAN ID
+
+

+

"AddAccess" RPC API - Add Access List Rule

+

Description

+

Add Access List Rule. Use this to add a new rule to the access list of the currently managed Virtual Hub. The access list is a set of packet file rules that are applied to packets that flow through the Virtual Hub. You can register multiple rules in an access list and you can also define an priority for each rule. All packets are checked for the conditions specified by the rules registered in the access list and based on the operation that is stipulated by the first matching rule, they either pass or are discarded. Packets that do not match any rule are implicitly allowed to pass. You can also use the access list to generate delays, jitters and packet losses. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a member server on a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "AddAccess",
+  "params": {
+    "HubName_str": "hubname",
+    "AccessListSingle": [
+      {
+        "Id_u32": 0,
+        "Note_utf": "note",
+        "Active_bool": false,
+        "Priority_u32": 0,
+        "Discard_bool": false,
+        "IsIPv6_bool": false,
+        "SrcIpAddress_ip": "192.168.0.1",
+        "SrcSubnetMask_ip": "255.255.255.255",
+        "DestIpAddress_ip": "192.168.0.1",
+        "DestSubnetMask_ip": "255.255.255.255",
+        "SrcIpAddress6_bin": "SGVsbG8gV29ybGQ=",
+        "SrcSubnetMask6_bin": "SGVsbG8gV29ybGQ=",
+        "DestIpAddress6_bin": "SGVsbG8gV29ybGQ=",
+        "DestSubnetMask6_bin": "SGVsbG8gV29ybGQ=",
+        "Protocol_u32": 0,
+        "SrcPortStart_u32": 0,
+        "SrcPortEnd_u32": 0,
+        "DestPortStart_u32": 0,
+        "DestPortEnd_u32": 0,
+        "SrcUsername_str": "srcusername",
+        "DestUsername_str": "destusername",
+        "CheckSrcMac_bool": false,
+        "SrcMacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "SrcMacMask_bin": "SGVsbG8gV29ybGQ=",
+        "CheckDstMac_bool": false,
+        "DstMacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "DstMacMask_bin": "SGVsbG8gV29ybGQ=",
+        "CheckTcpState_bool": false,
+        "Established_bool": false,
+        "Delay_u32": 0,
+        "Jitter_u32": 0,
+        "Loss_u32": 0,
+        "RedirectUrl_str": "redirecturl"
+      }
+    ]
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "AccessListSingle": [
+      {
+        "Id_u32": 0,
+        "Note_utf": "note",
+        "Active_bool": false,
+        "Priority_u32": 0,
+        "Discard_bool": false,
+        "IsIPv6_bool": false,
+        "SrcIpAddress_ip": "192.168.0.1",
+        "SrcSubnetMask_ip": "255.255.255.255",
+        "DestIpAddress_ip": "192.168.0.1",
+        "DestSubnetMask_ip": "255.255.255.255",
+        "SrcIpAddress6_bin": "SGVsbG8gV29ybGQ=",
+        "SrcSubnetMask6_bin": "SGVsbG8gV29ybGQ=",
+        "DestIpAddress6_bin": "SGVsbG8gV29ybGQ=",
+        "DestSubnetMask6_bin": "SGVsbG8gV29ybGQ=",
+        "Protocol_u32": 0,
+        "SrcPortStart_u32": 0,
+        "SrcPortEnd_u32": 0,
+        "DestPortStart_u32": 0,
+        "DestPortEnd_u32": 0,
+        "SrcUsername_str": "srcusername",
+        "DestUsername_str": "destusername",
+        "CheckSrcMac_bool": false,
+        "SrcMacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "SrcMacMask_bin": "SGVsbG8gV29ybGQ=",
+        "CheckDstMac_bool": false,
+        "DstMacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "DstMacMask_bin": "SGVsbG8gV29ybGQ=",
+        "CheckTcpState_bool": false,
+        "Established_bool": false,
+        "Delay_u32": 0,
+        "Jitter_u32": 0,
+        "Loss_u32": 0,
+        "RedirectUrl_str": "redirecturl"
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
AccessListSingleArray objectAccess list (Must be a single item)
Id_u32number (uint32)ID
Note_utfstring (UTF8)Specify a description (note) for this rule
Active_boolbooleanEnabled flag (true: enabled, false: disabled)
Priority_u32number (uint32)Specify an integer of 1 or higher to indicate the priority of the rule. Higher priority is given to rules with the lower priority values.
Discard_boolbooleanThe flag if the rule is DISCARD operation or PASS operation. When a packet matches this rule condition, this operation is decided. When the operation of the rule is PASS, the packet is allowed to pass, otherwise the packet will be discarded.
IsIPv6_boolbooleanThe flag if the rule is for IPv6. Specify false for IPv4, or specify true for IPv6.
SrcIpAddress_ipstring (IP address)Valid only if the rule is IPv4 mode (IsIPv6_bool == false). Specify a source IPv4 address as a rule condition. You must also specify the SrcSubnetMask_ip field.
SrcSubnetMask_ipstring (IP address)Valid only if the rule is IPv4 mode (IsIPv6_bool == false). Specify a source IPv4 subnet mask as a rule condition. "0.0.0.0" means all hosts. "255.255.255.255" means one single host.
DestIpAddress_ipstring (IP address)Valid only if the rule is IPv4 mode (IsIPv6_bool == false). Specify a destination IPv4 address as a rule condition. You must also specify the DestSubnetMask_ip field.
DestSubnetMask_ipstring (IP address)Valid only if the rule is IPv4 mode (IsIPv6_bool == false). Specify a destination IPv4 subnet mask as a rule condition. "0.0.0.0" means all hosts. "255.255.255.255" means one single host.
SrcIpAddress6_binstring (Base64 binary)Valid only if the rule is IPv6 mode (IsIPv6_bool == true). Specify a source IPv6 address as a rule condition. The field must be a byte array of 16 bytes (128 bits) to contain the IPv6 address in binary form. You must also specify the SrcSubnetMask6_bin field.
SrcSubnetMask6_binstring (Base64 binary)Valid only if the rule is IPv6 mode (IsIPv6_bool == true). Specify a source IPv6 subnet mask as a rule condition. The field must be a byte array of 16 bytes (128 bits) to contain the IPv6 subnet mask in binary form.
DestIpAddress6_binstring (Base64 binary)Valid only if the rule is IPv6 mode (IsIPv6_bool == true). Specify a destination IPv6 address as a rule condition. The field must be a byte array of 16 bytes (128 bits) to contain the IPv6 address in binary form. You must also specify the DestSubnetMask6_bin field.
DestSubnetMask6_binstring (Base64 binary)Valid only if the rule is IPv6 mode (IsIPv6_bool == true). Specify a destination IPv6 subnet mask as a rule condition. The field must be a byte array of 16 bytes (128 bits) to contain the IPv6 subnet mask in binary form.
Protocol_u32number (enum)The IP protocol number
Values:
1: ICMP for IPv4
6: TCP
17: UDP
58: ICMP for IPv6
SrcPortStart_u32number (uint32)The Start Value of the Source Port Number Range. If the specified protocol is TCP/IP or UDP/IP, specify the source port number as the rule condition. Protocols other than this will be ignored. When this parameter is not specified, the rules will apply to all port numbers.
SrcPortEnd_u32number (uint32)The End Value of the Source Port Number Range. If the specified protocol is TCP/IP or UDP/IP, specify the source port number as the rule condition. Protocols other than this will be ignored. When this parameter is not specified, the rules will apply to all port numbers.
DestPortStart_u32number (uint32)The Start Value of the Destination Port Number Range. If the specified protocol is TCP/IP or UDP/IP, specify the destination port number as the rule condition. Protocols other than this will be ignored. When this parameter is not specified, the rules will apply to all port numbers.
DestPortEnd_u32number (uint32)The End Value of the Destination Port Number Range. If the specified protocol is TCP/IP or UDP/IP, specify the destination port number as the rule condition. Protocols other than this will be ignored. When this parameter is not specified, the rules will apply to all port numbers.
SrcUsername_strstring (ASCII)Source user name. You can apply this rule to only the packets sent by a user session of a user name that has been specified as a rule condition. In this case, specify the user name.
DestUsername_strstring (ASCII)Destination user name. You can apply this rule to only the packets received by a user session of a user name that has been specified as a rule condition. In this case, specify the user name.
CheckSrcMac_boolbooleanSpecify true if you want to check the source MAC address.
SrcMacAddress_binstring (Base64 binary)Source MAC address (6 bytes), valid only if CheckSrcMac_bool == true.
SrcMacMask_binstring (Base64 binary)Source MAC address mask (6 bytes), valid only if CheckSrcMac_bool == true.
CheckDstMac_boolbooleanSpecify true if you want to check the destination MAC address.
DstMacAddress_binstring (Base64 binary)Destination MAC address (6 bytes), valid only if CheckSrcMac_bool == true.
DstMacMask_binstring (Base64 binary)Destination MAC address mask (6 bytes), valid only if CheckSrcMac_bool == true.
CheckTcpState_boolbooleanSpecify true if you want to check the state of the TCP connection.
Established_boolbooleanValid only if CheckTcpState_bool == true. Set this field true to match only TCP-established packets. Set this field false to match only TCP-non established packets.
Delay_u32number (uint32)Set this value to generate delays when packets is passing. Specify the delay period in milliseconds. Specify 0 means no delays to generate. The delays must be 10000 milliseconds at most.
Jitter_u32number (uint32)Set this value to generate jitters when packets is passing. Specify the ratio of fluctuation of jitters within 0% to 100% range. Specify 0 means no jitters to generate.
Loss_u32number (uint32)Set this value to generate packet losses when packets is passing. Specify the ratio of packet losses within 0% to 100% range. Specify 0 means no packet losses to generate.
RedirectUrl_strstring (ASCII)The specified URL will be mandatory replied to the client as a response for TCP connecting request packets which matches the conditions of this access list entry via this Virtual Hub. To use this setting, you can enforce the web browser of the VPN Client computer to show the specified web site when that web browser tries to access the specific IP address.
+
+

+

"DeleteAccess" RPC API - Delete Rule from Access List

+

Description

+

Delete Rule from Access List. Use this to specify a packet filter rule registered on the access list of the currently managed Virtual Hub and delete it. To delete a rule, you must specify that rule's ID. You can display the ID by using the EnumAccess API. If you wish not to delete the rule but to only temporarily disable it, use the SetAccessList API to set the rule status to disable. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a member server on a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "DeleteAccess",
+  "params": {
+    "HubName_str": "hubname",
+    "Id_u32": 0
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "Id_u32": 0
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
Id_u32number (uint32)ID
+
+

+

"EnumAccess" RPC API - Get Access List Rule List

+

Description

+

Get Access List Rule List. Use this to get a list of packet filter rules that are registered on access list of the currently managed Virtual Hub. The access list is a set of packet file rules that are applied to packets that flow through the Virtual Hub. You can register multiple rules in an access list and you can also define a priority for each rule. All packets are checked for the conditions specified by the rules registered in the access list and based on the operation that is stipulated by the first matching rule, they either pass or are discarded. Packets that do not match any rule are implicitly allowed to pass. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a member server on a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "EnumAccess",
+  "params": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "AccessList": [
+      {
+        "Id_u32": 0,
+        "Note_utf": "note",
+        "Active_bool": false,
+        "Priority_u32": 0,
+        "Discard_bool": false,
+        "IsIPv6_bool": false,
+        "SrcIpAddress_ip": "192.168.0.1",
+        "SrcSubnetMask_ip": "255.255.255.255",
+        "DestIpAddress_ip": "192.168.0.1",
+        "DestSubnetMask_ip": "255.255.255.255",
+        "SrcIpAddress6_bin": "SGVsbG8gV29ybGQ=",
+        "SrcSubnetMask6_bin": "SGVsbG8gV29ybGQ=",
+        "DestIpAddress6_bin": "SGVsbG8gV29ybGQ=",
+        "DestSubnetMask6_bin": "SGVsbG8gV29ybGQ=",
+        "Protocol_u32": 0,
+        "SrcPortStart_u32": 0,
+        "SrcPortEnd_u32": 0,
+        "DestPortStart_u32": 0,
+        "DestPortEnd_u32": 0,
+        "SrcUsername_str": "srcusername",
+        "DestUsername_str": "destusername",
+        "CheckSrcMac_bool": false,
+        "SrcMacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "SrcMacMask_bin": "SGVsbG8gV29ybGQ=",
+        "CheckDstMac_bool": false,
+        "DstMacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "DstMacMask_bin": "SGVsbG8gV29ybGQ=",
+        "CheckTcpState_bool": false,
+        "Established_bool": false,
+        "Delay_u32": 0,
+        "Jitter_u32": 0,
+        "Loss_u32": 0,
+        "RedirectUrl_str": "redirecturl"
+      },
+      {
+        "Id_u32": 0,
+        "Note_utf": "note",
+        "Active_bool": false,
+        "Priority_u32": 0,
+        "Discard_bool": false,
+        "IsIPv6_bool": false,
+        "SrcIpAddress_ip": "192.168.0.1",
+        "SrcSubnetMask_ip": "255.255.255.255",
+        "DestIpAddress_ip": "192.168.0.1",
+        "DestSubnetMask_ip": "255.255.255.255",
+        "SrcIpAddress6_bin": "SGVsbG8gV29ybGQ=",
+        "SrcSubnetMask6_bin": "SGVsbG8gV29ybGQ=",
+        "DestIpAddress6_bin": "SGVsbG8gV29ybGQ=",
+        "DestSubnetMask6_bin": "SGVsbG8gV29ybGQ=",
+        "Protocol_u32": 0,
+        "SrcPortStart_u32": 0,
+        "SrcPortEnd_u32": 0,
+        "DestPortStart_u32": 0,
+        "DestPortEnd_u32": 0,
+        "SrcUsername_str": "srcusername",
+        "DestUsername_str": "destusername",
+        "CheckSrcMac_bool": false,
+        "SrcMacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "SrcMacMask_bin": "SGVsbG8gV29ybGQ=",
+        "CheckDstMac_bool": false,
+        "DstMacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "DstMacMask_bin": "SGVsbG8gV29ybGQ=",
+        "CheckTcpState_bool": false,
+        "Established_bool": false,
+        "Delay_u32": 0,
+        "Jitter_u32": 0,
+        "Loss_u32": 0,
+        "RedirectUrl_str": "redirecturl"
+      },
+      {
+        "Id_u32": 0,
+        "Note_utf": "note",
+        "Active_bool": false,
+        "Priority_u32": 0,
+        "Discard_bool": false,
+        "IsIPv6_bool": false,
+        "SrcIpAddress_ip": "192.168.0.1",
+        "SrcSubnetMask_ip": "255.255.255.255",
+        "DestIpAddress_ip": "192.168.0.1",
+        "DestSubnetMask_ip": "255.255.255.255",
+        "SrcIpAddress6_bin": "SGVsbG8gV29ybGQ=",
+        "SrcSubnetMask6_bin": "SGVsbG8gV29ybGQ=",
+        "DestIpAddress6_bin": "SGVsbG8gV29ybGQ=",
+        "DestSubnetMask6_bin": "SGVsbG8gV29ybGQ=",
+        "Protocol_u32": 0,
+        "SrcPortStart_u32": 0,
+        "SrcPortEnd_u32": 0,
+        "DestPortStart_u32": 0,
+        "DestPortEnd_u32": 0,
+        "SrcUsername_str": "srcusername",
+        "DestUsername_str": "destusername",
+        "CheckSrcMac_bool": false,
+        "SrcMacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "SrcMacMask_bin": "SGVsbG8gV29ybGQ=",
+        "CheckDstMac_bool": false,
+        "DstMacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "DstMacMask_bin": "SGVsbG8gV29ybGQ=",
+        "CheckTcpState_bool": false,
+        "Established_bool": false,
+        "Delay_u32": 0,
+        "Jitter_u32": 0,
+        "Loss_u32": 0,
+        "RedirectUrl_str": "redirecturl"
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
AccessListArray objectAccess list
Id_u32number (uint32)ID
Note_utfstring (UTF8)Specify a description (note) for this rule
Active_boolbooleanEnabled flag (true: enabled, false: disabled)
Priority_u32number (uint32)Specify an integer of 1 or higher to indicate the priority of the rule. Higher priority is given to rules with the lower priority values.
Discard_boolbooleanThe flag if the rule is DISCARD operation or PASS operation. When a packet matches this rule condition, this operation is decided. When the operation of the rule is PASS, the packet is allowed to pass, otherwise the packet will be discarded.
IsIPv6_boolbooleanThe flag if the rule is for IPv6. Specify false for IPv4, or specify true for IPv6.
SrcIpAddress_ipstring (IP address)Valid only if the rule is IPv4 mode (IsIPv6_bool == false). Specify a source IPv4 address as a rule condition. You must also specify the SrcSubnetMask_ip field.
SrcSubnetMask_ipstring (IP address)Valid only if the rule is IPv4 mode (IsIPv6_bool == false). Specify a source IPv4 subnet mask as a rule condition. "0.0.0.0" means all hosts. "255.255.255.255" means one single host.
DestIpAddress_ipstring (IP address)Valid only if the rule is IPv4 mode (IsIPv6_bool == false). Specify a destination IPv4 address as a rule condition. You must also specify the DestSubnetMask_ip field.
DestSubnetMask_ipstring (IP address)Valid only if the rule is IPv4 mode (IsIPv6_bool == false). Specify a destination IPv4 subnet mask as a rule condition. "0.0.0.0" means all hosts. "255.255.255.255" means one single host.
SrcIpAddress6_binstring (Base64 binary)Valid only if the rule is IPv6 mode (IsIPv6_bool == true). Specify a source IPv6 address as a rule condition. The field must be a byte array of 16 bytes (128 bits) to contain the IPv6 address in binary form. You must also specify the SrcSubnetMask6_bin field.
SrcSubnetMask6_binstring (Base64 binary)Valid only if the rule is IPv6 mode (IsIPv6_bool == true). Specify a source IPv6 subnet mask as a rule condition. The field must be a byte array of 16 bytes (128 bits) to contain the IPv6 subnet mask in binary form.
DestIpAddress6_binstring (Base64 binary)Valid only if the rule is IPv6 mode (IsIPv6_bool == true). Specify a destination IPv6 address as a rule condition. The field must be a byte array of 16 bytes (128 bits) to contain the IPv6 address in binary form. You must also specify the DestSubnetMask6_bin field.
DestSubnetMask6_binstring (Base64 binary)Valid only if the rule is IPv6 mode (IsIPv6_bool == true). Specify a destination IPv6 subnet mask as a rule condition. The field must be a byte array of 16 bytes (128 bits) to contain the IPv6 subnet mask in binary form.
Protocol_u32number (enum)The IP protocol number
Values:
1: ICMP for IPv4
6: TCP
17: UDP
58: ICMP for IPv6
SrcPortStart_u32number (uint32)The Start Value of the Source Port Number Range. If the specified protocol is TCP/IP or UDP/IP, specify the source port number as the rule condition. Protocols other than this will be ignored. When this parameter is not specified, the rules will apply to all port numbers.
SrcPortEnd_u32number (uint32)The End Value of the Source Port Number Range. If the specified protocol is TCP/IP or UDP/IP, specify the source port number as the rule condition. Protocols other than this will be ignored. When this parameter is not specified, the rules will apply to all port numbers.
DestPortStart_u32number (uint32)The Start Value of the Destination Port Number Range. If the specified protocol is TCP/IP or UDP/IP, specify the destination port number as the rule condition. Protocols other than this will be ignored. When this parameter is not specified, the rules will apply to all port numbers.
DestPortEnd_u32number (uint32)The End Value of the Destination Port Number Range. If the specified protocol is TCP/IP or UDP/IP, specify the destination port number as the rule condition. Protocols other than this will be ignored. When this parameter is not specified, the rules will apply to all port numbers.
SrcUsername_strstring (ASCII)Source user name. You can apply this rule to only the packets sent by a user session of a user name that has been specified as a rule condition. In this case, specify the user name.
DestUsername_strstring (ASCII)Destination user name. You can apply this rule to only the packets received by a user session of a user name that has been specified as a rule condition. In this case, specify the user name.
CheckSrcMac_boolbooleanSpecify true if you want to check the source MAC address.
SrcMacAddress_binstring (Base64 binary)Source MAC address (6 bytes), valid only if CheckSrcMac_bool == true.
SrcMacMask_binstring (Base64 binary)Source MAC address mask (6 bytes), valid only if CheckSrcMac_bool == true.
CheckDstMac_boolbooleanSpecify true if you want to check the destination MAC address.
DstMacAddress_binstring (Base64 binary)Destination MAC address (6 bytes), valid only if CheckSrcMac_bool == true.
DstMacMask_binstring (Base64 binary)Destination MAC address mask (6 bytes), valid only if CheckSrcMac_bool == true.
CheckTcpState_boolbooleanSpecify true if you want to check the state of the TCP connection.
Established_boolbooleanValid only if CheckTcpState_bool == true. Set this field true to match only TCP-established packets. Set this field false to match only TCP-non established packets.
Delay_u32number (uint32)Set this value to generate delays when packets is passing. Specify the delay period in milliseconds. Specify 0 means no delays to generate. The delays must be 10000 milliseconds at most.
Jitter_u32number (uint32)Set this value to generate jitters when packets is passing. Specify the ratio of fluctuation of jitters within 0% to 100% range. Specify 0 means no jitters to generate.
Loss_u32number (uint32)Set this value to generate packet losses when packets is passing. Specify the ratio of packet losses within 0% to 100% range. Specify 0 means no packet losses to generate.
RedirectUrl_strstring (ASCII)The specified URL will be mandatory replied to the client as a response for TCP connecting request packets which matches the conditions of this access list entry via this Virtual Hub. To use this setting, you can enforce the web browser of the VPN Client computer to show the specified web site when that web browser tries to access the specific IP address.
+
+

+

"SetAccessList" RPC API - Replace all access lists on a single bulk API call

+

Description

+

Replace all access lists on a single bulk API call. This API removes all existing access list rules on the Virtual Hub, and replace them by new access list rules specified by the parameter.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetAccessList",
+  "params": {
+    "HubName_str": "hubname",
+    "AccessList": [
+      {
+        "Id_u32": 0,
+        "Note_utf": "note",
+        "Active_bool": false,
+        "Priority_u32": 0,
+        "Discard_bool": false,
+        "IsIPv6_bool": false,
+        "SrcIpAddress_ip": "192.168.0.1",
+        "SrcSubnetMask_ip": "255.255.255.255",
+        "DestIpAddress_ip": "192.168.0.1",
+        "DestSubnetMask_ip": "255.255.255.255",
+        "SrcIpAddress6_bin": "SGVsbG8gV29ybGQ=",
+        "SrcSubnetMask6_bin": "SGVsbG8gV29ybGQ=",
+        "DestIpAddress6_bin": "SGVsbG8gV29ybGQ=",
+        "DestSubnetMask6_bin": "SGVsbG8gV29ybGQ=",
+        "Protocol_u32": 0,
+        "SrcPortStart_u32": 0,
+        "SrcPortEnd_u32": 0,
+        "DestPortStart_u32": 0,
+        "DestPortEnd_u32": 0,
+        "SrcUsername_str": "srcusername",
+        "DestUsername_str": "destusername",
+        "CheckSrcMac_bool": false,
+        "SrcMacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "SrcMacMask_bin": "SGVsbG8gV29ybGQ=",
+        "CheckDstMac_bool": false,
+        "DstMacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "DstMacMask_bin": "SGVsbG8gV29ybGQ=",
+        "CheckTcpState_bool": false,
+        "Established_bool": false,
+        "Delay_u32": 0,
+        "Jitter_u32": 0,
+        "Loss_u32": 0,
+        "RedirectUrl_str": "redirecturl"
+      },
+      {
+        "Id_u32": 0,
+        "Note_utf": "note",
+        "Active_bool": false,
+        "Priority_u32": 0,
+        "Discard_bool": false,
+        "IsIPv6_bool": false,
+        "SrcIpAddress_ip": "192.168.0.1",
+        "SrcSubnetMask_ip": "255.255.255.255",
+        "DestIpAddress_ip": "192.168.0.1",
+        "DestSubnetMask_ip": "255.255.255.255",
+        "SrcIpAddress6_bin": "SGVsbG8gV29ybGQ=",
+        "SrcSubnetMask6_bin": "SGVsbG8gV29ybGQ=",
+        "DestIpAddress6_bin": "SGVsbG8gV29ybGQ=",
+        "DestSubnetMask6_bin": "SGVsbG8gV29ybGQ=",
+        "Protocol_u32": 0,
+        "SrcPortStart_u32": 0,
+        "SrcPortEnd_u32": 0,
+        "DestPortStart_u32": 0,
+        "DestPortEnd_u32": 0,
+        "SrcUsername_str": "srcusername",
+        "DestUsername_str": "destusername",
+        "CheckSrcMac_bool": false,
+        "SrcMacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "SrcMacMask_bin": "SGVsbG8gV29ybGQ=",
+        "CheckDstMac_bool": false,
+        "DstMacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "DstMacMask_bin": "SGVsbG8gV29ybGQ=",
+        "CheckTcpState_bool": false,
+        "Established_bool": false,
+        "Delay_u32": 0,
+        "Jitter_u32": 0,
+        "Loss_u32": 0,
+        "RedirectUrl_str": "redirecturl"
+      },
+      {
+        "Id_u32": 0,
+        "Note_utf": "note",
+        "Active_bool": false,
+        "Priority_u32": 0,
+        "Discard_bool": false,
+        "IsIPv6_bool": false,
+        "SrcIpAddress_ip": "192.168.0.1",
+        "SrcSubnetMask_ip": "255.255.255.255",
+        "DestIpAddress_ip": "192.168.0.1",
+        "DestSubnetMask_ip": "255.255.255.255",
+        "SrcIpAddress6_bin": "SGVsbG8gV29ybGQ=",
+        "SrcSubnetMask6_bin": "SGVsbG8gV29ybGQ=",
+        "DestIpAddress6_bin": "SGVsbG8gV29ybGQ=",
+        "DestSubnetMask6_bin": "SGVsbG8gV29ybGQ=",
+        "Protocol_u32": 0,
+        "SrcPortStart_u32": 0,
+        "SrcPortEnd_u32": 0,
+        "DestPortStart_u32": 0,
+        "DestPortEnd_u32": 0,
+        "SrcUsername_str": "srcusername",
+        "DestUsername_str": "destusername",
+        "CheckSrcMac_bool": false,
+        "SrcMacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "SrcMacMask_bin": "SGVsbG8gV29ybGQ=",
+        "CheckDstMac_bool": false,
+        "DstMacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "DstMacMask_bin": "SGVsbG8gV29ybGQ=",
+        "CheckTcpState_bool": false,
+        "Established_bool": false,
+        "Delay_u32": 0,
+        "Jitter_u32": 0,
+        "Loss_u32": 0,
+        "RedirectUrl_str": "redirecturl"
+      }
+    ]
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "AccessList": [
+      {
+        "Id_u32": 0,
+        "Note_utf": "note",
+        "Active_bool": false,
+        "Priority_u32": 0,
+        "Discard_bool": false,
+        "IsIPv6_bool": false,
+        "SrcIpAddress_ip": "192.168.0.1",
+        "SrcSubnetMask_ip": "255.255.255.255",
+        "DestIpAddress_ip": "192.168.0.1",
+        "DestSubnetMask_ip": "255.255.255.255",
+        "SrcIpAddress6_bin": "SGVsbG8gV29ybGQ=",
+        "SrcSubnetMask6_bin": "SGVsbG8gV29ybGQ=",
+        "DestIpAddress6_bin": "SGVsbG8gV29ybGQ=",
+        "DestSubnetMask6_bin": "SGVsbG8gV29ybGQ=",
+        "Protocol_u32": 0,
+        "SrcPortStart_u32": 0,
+        "SrcPortEnd_u32": 0,
+        "DestPortStart_u32": 0,
+        "DestPortEnd_u32": 0,
+        "SrcUsername_str": "srcusername",
+        "DestUsername_str": "destusername",
+        "CheckSrcMac_bool": false,
+        "SrcMacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "SrcMacMask_bin": "SGVsbG8gV29ybGQ=",
+        "CheckDstMac_bool": false,
+        "DstMacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "DstMacMask_bin": "SGVsbG8gV29ybGQ=",
+        "CheckTcpState_bool": false,
+        "Established_bool": false,
+        "Delay_u32": 0,
+        "Jitter_u32": 0,
+        "Loss_u32": 0,
+        "RedirectUrl_str": "redirecturl"
+      },
+      {
+        "Id_u32": 0,
+        "Note_utf": "note",
+        "Active_bool": false,
+        "Priority_u32": 0,
+        "Discard_bool": false,
+        "IsIPv6_bool": false,
+        "SrcIpAddress_ip": "192.168.0.1",
+        "SrcSubnetMask_ip": "255.255.255.255",
+        "DestIpAddress_ip": "192.168.0.1",
+        "DestSubnetMask_ip": "255.255.255.255",
+        "SrcIpAddress6_bin": "SGVsbG8gV29ybGQ=",
+        "SrcSubnetMask6_bin": "SGVsbG8gV29ybGQ=",
+        "DestIpAddress6_bin": "SGVsbG8gV29ybGQ=",
+        "DestSubnetMask6_bin": "SGVsbG8gV29ybGQ=",
+        "Protocol_u32": 0,
+        "SrcPortStart_u32": 0,
+        "SrcPortEnd_u32": 0,
+        "DestPortStart_u32": 0,
+        "DestPortEnd_u32": 0,
+        "SrcUsername_str": "srcusername",
+        "DestUsername_str": "destusername",
+        "CheckSrcMac_bool": false,
+        "SrcMacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "SrcMacMask_bin": "SGVsbG8gV29ybGQ=",
+        "CheckDstMac_bool": false,
+        "DstMacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "DstMacMask_bin": "SGVsbG8gV29ybGQ=",
+        "CheckTcpState_bool": false,
+        "Established_bool": false,
+        "Delay_u32": 0,
+        "Jitter_u32": 0,
+        "Loss_u32": 0,
+        "RedirectUrl_str": "redirecturl"
+      },
+      {
+        "Id_u32": 0,
+        "Note_utf": "note",
+        "Active_bool": false,
+        "Priority_u32": 0,
+        "Discard_bool": false,
+        "IsIPv6_bool": false,
+        "SrcIpAddress_ip": "192.168.0.1",
+        "SrcSubnetMask_ip": "255.255.255.255",
+        "DestIpAddress_ip": "192.168.0.1",
+        "DestSubnetMask_ip": "255.255.255.255",
+        "SrcIpAddress6_bin": "SGVsbG8gV29ybGQ=",
+        "SrcSubnetMask6_bin": "SGVsbG8gV29ybGQ=",
+        "DestIpAddress6_bin": "SGVsbG8gV29ybGQ=",
+        "DestSubnetMask6_bin": "SGVsbG8gV29ybGQ=",
+        "Protocol_u32": 0,
+        "SrcPortStart_u32": 0,
+        "SrcPortEnd_u32": 0,
+        "DestPortStart_u32": 0,
+        "DestPortEnd_u32": 0,
+        "SrcUsername_str": "srcusername",
+        "DestUsername_str": "destusername",
+        "CheckSrcMac_bool": false,
+        "SrcMacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "SrcMacMask_bin": "SGVsbG8gV29ybGQ=",
+        "CheckDstMac_bool": false,
+        "DstMacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "DstMacMask_bin": "SGVsbG8gV29ybGQ=",
+        "CheckTcpState_bool": false,
+        "Established_bool": false,
+        "Delay_u32": 0,
+        "Jitter_u32": 0,
+        "Loss_u32": 0,
+        "RedirectUrl_str": "redirecturl"
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
AccessListArray objectAccess list
Id_u32number (uint32)ID
Note_utfstring (UTF8)Specify a description (note) for this rule
Active_boolbooleanEnabled flag (true: enabled, false: disabled)
Priority_u32number (uint32)Specify an integer of 1 or higher to indicate the priority of the rule. Higher priority is given to rules with the lower priority values.
Discard_boolbooleanThe flag if the rule is DISCARD operation or PASS operation. When a packet matches this rule condition, this operation is decided. When the operation of the rule is PASS, the packet is allowed to pass, otherwise the packet will be discarded.
IsIPv6_boolbooleanThe flag if the rule is for IPv6. Specify false for IPv4, or specify true for IPv6.
SrcIpAddress_ipstring (IP address)Valid only if the rule is IPv4 mode (IsIPv6_bool == false). Specify a source IPv4 address as a rule condition. You must also specify the SrcSubnetMask_ip field.
SrcSubnetMask_ipstring (IP address)Valid only if the rule is IPv4 mode (IsIPv6_bool == false). Specify a source IPv4 subnet mask as a rule condition. "0.0.0.0" means all hosts. "255.255.255.255" means one single host.
DestIpAddress_ipstring (IP address)Valid only if the rule is IPv4 mode (IsIPv6_bool == false). Specify a destination IPv4 address as a rule condition. You must also specify the DestSubnetMask_ip field.
DestSubnetMask_ipstring (IP address)Valid only if the rule is IPv4 mode (IsIPv6_bool == false). Specify a destination IPv4 subnet mask as a rule condition. "0.0.0.0" means all hosts. "255.255.255.255" means one single host.
SrcIpAddress6_binstring (Base64 binary)Valid only if the rule is IPv6 mode (IsIPv6_bool == true). Specify a source IPv6 address as a rule condition. The field must be a byte array of 16 bytes (128 bits) to contain the IPv6 address in binary form. You must also specify the SrcSubnetMask6_bin field.
SrcSubnetMask6_binstring (Base64 binary)Valid only if the rule is IPv6 mode (IsIPv6_bool == true). Specify a source IPv6 subnet mask as a rule condition. The field must be a byte array of 16 bytes (128 bits) to contain the IPv6 subnet mask in binary form.
DestIpAddress6_binstring (Base64 binary)Valid only if the rule is IPv6 mode (IsIPv6_bool == true). Specify a destination IPv6 address as a rule condition. The field must be a byte array of 16 bytes (128 bits) to contain the IPv6 address in binary form. You must also specify the DestSubnetMask6_bin field.
DestSubnetMask6_binstring (Base64 binary)Valid only if the rule is IPv6 mode (IsIPv6_bool == true). Specify a destination IPv6 subnet mask as a rule condition. The field must be a byte array of 16 bytes (128 bits) to contain the IPv6 subnet mask in binary form.
Protocol_u32number (enum)The IP protocol number
Values:
1: ICMP for IPv4
6: TCP
17: UDP
58: ICMP for IPv6
SrcPortStart_u32number (uint32)The Start Value of the Source Port Number Range. If the specified protocol is TCP/IP or UDP/IP, specify the source port number as the rule condition. Protocols other than this will be ignored. When this parameter is not specified, the rules will apply to all port numbers.
SrcPortEnd_u32number (uint32)The End Value of the Source Port Number Range. If the specified protocol is TCP/IP or UDP/IP, specify the source port number as the rule condition. Protocols other than this will be ignored. When this parameter is not specified, the rules will apply to all port numbers.
DestPortStart_u32number (uint32)The Start Value of the Destination Port Number Range. If the specified protocol is TCP/IP or UDP/IP, specify the destination port number as the rule condition. Protocols other than this will be ignored. When this parameter is not specified, the rules will apply to all port numbers.
DestPortEnd_u32number (uint32)The End Value of the Destination Port Number Range. If the specified protocol is TCP/IP or UDP/IP, specify the destination port number as the rule condition. Protocols other than this will be ignored. When this parameter is not specified, the rules will apply to all port numbers.
SrcUsername_strstring (ASCII)Source user name. You can apply this rule to only the packets sent by a user session of a user name that has been specified as a rule condition. In this case, specify the user name.
DestUsername_strstring (ASCII)Destination user name. You can apply this rule to only the packets received by a user session of a user name that has been specified as a rule condition. In this case, specify the user name.
CheckSrcMac_boolbooleanSpecify true if you want to check the source MAC address.
SrcMacAddress_binstring (Base64 binary)Source MAC address (6 bytes), valid only if CheckSrcMac_bool == true.
SrcMacMask_binstring (Base64 binary)Source MAC address mask (6 bytes), valid only if CheckSrcMac_bool == true.
CheckDstMac_boolbooleanSpecify true if you want to check the destination MAC address.
DstMacAddress_binstring (Base64 binary)Destination MAC address (6 bytes), valid only if CheckSrcMac_bool == true.
DstMacMask_binstring (Base64 binary)Destination MAC address mask (6 bytes), valid only if CheckSrcMac_bool == true.
CheckTcpState_boolbooleanSpecify true if you want to check the state of the TCP connection.
Established_boolbooleanValid only if CheckTcpState_bool == true. Set this field true to match only TCP-established packets. Set this field false to match only TCP-non established packets.
Delay_u32number (uint32)Set this value to generate delays when packets is passing. Specify the delay period in milliseconds. Specify 0 means no delays to generate. The delays must be 10000 milliseconds at most.
Jitter_u32number (uint32)Set this value to generate jitters when packets is passing. Specify the ratio of fluctuation of jitters within 0% to 100% range. Specify 0 means no jitters to generate.
Loss_u32number (uint32)Set this value to generate packet losses when packets is passing. Specify the ratio of packet losses within 0% to 100% range. Specify 0 means no packet losses to generate.
RedirectUrl_strstring (ASCII)The specified URL will be mandatory replied to the client as a response for TCP connecting request packets which matches the conditions of this access list entry via this Virtual Hub. To use this setting, you can enforce the web browser of the VPN Client computer to show the specified web site when that web browser tries to access the specific IP address.
+
+

+

"CreateUser" RPC API - Create a user

+

Description

+

Create a user. Use this to create a new user in the security account database of the currently managed Virtual Hub. By creating a user, the VPN Client can connect to the Virtual Hub by using the authentication information of that user. Note that a user whose user name has been created as "" (a single asterisk character) will automatically be registered as a RADIUS authentication user. For cases where there are users with "" as the name, when a user, whose user name that has been provided when a client connected to a VPN Server does not match existing user names, is able to be authenticated by a RADIUS server or NT domain controller by inputting a user name and password, the authentication settings and security policy settings will follow the setting for the user "*". To change the user information of a user that has been created, use the SetUser API. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a member server on a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "CreateUser",
+  "params": {
+    "HubName_str": "hubname",
+    "Name_str": "name",
+    "Realname_utf": "realname",
+    "Note_utf": "note",
+    "ExpireTime_dt": "2020-08-01T12:24:36.123",
+    "AuthType_u32": 0,
+    "Auth_Password_str": "auth_password",
+    "UserX_bin": "SGVsbG8gV29ybGQ=",
+    "Serial_bin": "SGVsbG8gV29ybGQ=",
+    "CommonName_utf": "auth_rootcert_commonname",
+    "RadiusUsername_utf": "auth_radius_radiususername",
+    "NtUsername_utf": "auth_nt_ntusername",
+    "UsePolicy_bool": false,
+    "policy:Access_bool": false,
+    "policy:DHCPFilter_bool": false,
+    "policy:DHCPNoServer_bool": false,
+    "policy:DHCPForce_bool": false,
+    "policy:NoBridge_bool": false,
+    "policy:NoRouting_bool": false,
+    "policy:CheckMac_bool": false,
+    "policy:CheckIP_bool": false,
+    "policy:ArpDhcpOnly_bool": false,
+    "policy:PrivacyFilter_bool": false,
+    "policy:NoServer_bool": false,
+    "policy:NoBroadcastLimiter_bool": false,
+    "policy:MonitorPort_bool": false,
+    "policy:MaxConnection_u32": 0,
+    "policy:TimeOut_u32": 0,
+    "policy:MaxMac_u32": 0,
+    "policy:MaxIP_u32": 0,
+    "policy:MaxUpload_u32": 0,
+    "policy:MaxDownload_u32": 0,
+    "policy:FixPassword_bool": false,
+    "policy:MultiLogins_u32": 0,
+    "policy:NoQoS_bool": false,
+    "policy:RSandRAFilter_bool": false,
+    "policy:RAFilter_bool": false,
+    "policy:DHCPv6Filter_bool": false,
+    "policy:DHCPv6NoServer_bool": false,
+    "policy:NoRoutingV6_bool": false,
+    "policy:CheckIPv6_bool": false,
+    "policy:NoServerV6_bool": false,
+    "policy:MaxIPv6_u32": 0,
+    "policy:NoSavePassword_bool": false,
+    "policy:AutoDisconnect_u32": 0,
+    "policy:FilterIPv4_bool": false,
+    "policy:FilterIPv6_bool": false,
+    "policy:FilterNonIP_bool": false,
+    "policy:NoIPv6DefaultRouterInRA_bool": false,
+    "policy:NoIPv6DefaultRouterInRAWhenIPv6_bool": false,
+    "policy:VLanId_u32": 0,
+    "policy:Ver3_bool": false
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "Name_str": "name",
+    "GroupName_str": "groupname",
+    "Realname_utf": "realname",
+    "Note_utf": "note",
+    "CreatedTime_dt": "2020-08-01T12:24:36.123",
+    "UpdatedTime_dt": "2020-08-01T12:24:36.123",
+    "ExpireTime_dt": "2020-08-01T12:24:36.123",
+    "AuthType_u32": 0,
+    "Auth_Password_str": "auth_password",
+    "UserX_bin": "SGVsbG8gV29ybGQ=",
+    "Serial_bin": "SGVsbG8gV29ybGQ=",
+    "CommonName_utf": "auth_rootcert_commonname",
+    "RadiusUsername_utf": "auth_radius_radiususername",
+    "NtUsername_utf": "auth_nt_ntusername",
+    "NumLogin_u32": 0,
+    "Recv.BroadcastBytes_u64": 0,
+    "Recv.BroadcastCount_u64": 0,
+    "Recv.UnicastBytes_u64": 0,
+    "Recv.UnicastCount_u64": 0,
+    "Send.BroadcastBytes_u64": 0,
+    "Send.BroadcastCount_u64": 0,
+    "Send.UnicastBytes_u64": 0,
+    "Send.UnicastCount_u64": 0,
+    "UsePolicy_bool": false,
+    "policy:Access_bool": false,
+    "policy:DHCPFilter_bool": false,
+    "policy:DHCPNoServer_bool": false,
+    "policy:DHCPForce_bool": false,
+    "policy:NoBridge_bool": false,
+    "policy:NoRouting_bool": false,
+    "policy:CheckMac_bool": false,
+    "policy:CheckIP_bool": false,
+    "policy:ArpDhcpOnly_bool": false,
+    "policy:PrivacyFilter_bool": false,
+    "policy:NoServer_bool": false,
+    "policy:NoBroadcastLimiter_bool": false,
+    "policy:MonitorPort_bool": false,
+    "policy:MaxConnection_u32": 0,
+    "policy:TimeOut_u32": 0,
+    "policy:MaxMac_u32": 0,
+    "policy:MaxIP_u32": 0,
+    "policy:MaxUpload_u32": 0,
+    "policy:MaxDownload_u32": 0,
+    "policy:FixPassword_bool": false,
+    "policy:MultiLogins_u32": 0,
+    "policy:NoQoS_bool": false,
+    "policy:RSandRAFilter_bool": false,
+    "policy:RAFilter_bool": false,
+    "policy:DHCPv6Filter_bool": false,
+    "policy:DHCPv6NoServer_bool": false,
+    "policy:NoRoutingV6_bool": false,
+    "policy:CheckIPv6_bool": false,
+    "policy:NoServerV6_bool": false,
+    "policy:MaxIPv6_u32": 0,
+    "policy:NoSavePassword_bool": false,
+    "policy:AutoDisconnect_u32": 0,
+    "policy:FilterIPv4_bool": false,
+    "policy:FilterIPv6_bool": false,
+    "policy:FilterNonIP_bool": false,
+    "policy:NoIPv6DefaultRouterInRA_bool": false,
+    "policy:NoIPv6DefaultRouterInRAWhenIPv6_bool": false,
+    "policy:VLanId_u32": 0,
+    "policy:Ver3_bool": false
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
Name_strstring (ASCII)Specify the user name of the user
GroupName_strstring (ASCII)Assigned group name for the user
Realname_utfstring (UTF8)Optional real name (full name) of the user, allow using any Unicode characters
Note_utfstring (UTF8)Optional User Description
CreatedTime_dtDateCreation date and time
UpdatedTime_dtDateLast modified date and time
ExpireTime_dtDateExpiration date and time
AuthType_u32number (enum)Authentication method of the user
Values:
0: Anonymous authentication
1: Password authentication
2: User certificate authentication
3: Root certificate which is issued by trusted Certificate Authority
4: Radius authentication
5: Windows NT authentication
Auth_Password_strstring (ASCII)User password, valid only if AuthType_u32 == Password(1). Valid only to create or set operations.
UserX_binstring (Base64 binary)User certificate, valid only if AuthType_u32 == UserCert(2).
Serial_binstring (Base64 binary)Certificate Serial Number, optional, valid only if AuthType_u32 == RootCert(3).
CommonName_utfstring (UTF8)Certificate Common Name, optional, valid only if AuthType_u32 == RootCert(3).
RadiusUsername_utfstring (UTF8)Username in RADIUS server, optional, valid only if AuthType_u32 == Radius(4).
NtUsername_utfstring (UTF8)Username in NT Domain server, optional, valid only if AuthType_u32 == NT(5).
NumLogin_u32number (uint32)Number of total logins of the user
Recv.BroadcastBytes_u64number (uint64)Number of broadcast packets (Recv)
Recv.BroadcastCount_u64number (uint64)Broadcast bytes (Recv)
Recv.UnicastBytes_u64number (uint64)Unicast count (Recv)
Recv.UnicastCount_u64number (uint64)Unicast bytes (Recv)
Send.BroadcastBytes_u64number (uint64)Number of broadcast packets (Send)
Send.BroadcastCount_u64number (uint64)Broadcast bytes (Send)
Send.UnicastBytes_u64number (uint64)Unicast bytes (Send)
Send.UnicastCount_u64number (uint64)Unicast bytes (Send)
UsePolicy_boolbooleanThe flag whether to use security policy
policy:Access_boolbooleanSecurity policy: Allow Access. The users, which this policy value is true, have permission to make VPN connection to VPN Server.
policy:DHCPFilter_boolbooleanSecurity policy: Filter DHCP Packets (IPv4). All IPv4 DHCP packets in sessions defined this policy will be filtered.
policy:DHCPNoServer_boolbooleanSecurity policy: Disallow DHCP Server Operation (IPv4). Computers connected to sessions that have this policy setting will not be allowed to become a DHCP server and distribute IPv4 addresses to DHCP clients.
policy:DHCPForce_boolbooleanSecurity policy: Enforce DHCP Allocated IP Addresses (IPv4). Computers in sessions that have this policy setting will only be able to use IPv4 addresses allocated by a DHCP server on the virtual network side.
policy:NoBridge_boolbooleanSecurity policy: Deny Bridge Operation. Bridge-mode connections are denied for user sessions that have this policy setting. Even in cases when the Ethernet Bridge is configured in the client side, communication will not be possible.
policy:NoRouting_boolbooleanSecurity policy: Deny Routing Operation (IPv4). IPv4 routing will be denied for sessions that have this policy setting. Even in the case where the IP router is operating on the user client side, communication will not be possible.
policy:CheckMac_boolbooleanSecurity policy: Deny MAC Addresses Duplication. The use of duplicating MAC addresses that are in use by computers of different sessions cannot be used by sessions with this policy setting.
policy:CheckIP_boolbooleanSecurity policy: Deny IP Address Duplication (IPv4). The use of duplicating IPv4 addresses that are in use by computers of different sessions cannot be used by sessions with this policy setting.
policy:ArpDhcpOnly_boolbooleanSecurity policy: Deny Non-ARP / Non-DHCP / Non-ICMPv6 broadcasts. The sending or receiving of broadcast packets that are not ARP protocol, DHCP protocol, nor ICMPv6 on the virtual network will not be allowed for sessions with this policy setting.
policy:PrivacyFilter_boolbooleanSecurity policy: Privacy Filter Mode. All direct communication between sessions with the privacy filter mode policy setting will be filtered.
policy:NoServer_boolbooleanSecurity policy: Deny Operation as TCP/IP Server (IPv4). Computers of sessions with this policy setting can't listen and accept TCP/IP connections in IPv4.
policy:NoBroadcastLimiter_boolbooleanSecurity policy: Unlimited Number of Broadcasts. If a computer of a session with this policy setting sends broadcast packets of a number unusually larger than what would be considered normal on the virtual network, there will be no automatic limiting.
policy:MonitorPort_boolbooleanSecurity policy: Allow Monitoring Mode. Users with this policy setting will be granted to connect to the Virtual Hub in Monitoring Mode. Sessions in Monitoring Mode are able to monitor (tap) all packets flowing through the Virtual Hub.
policy:MaxConnection_u32number (uint32)Security policy: Maximum Number of TCP Connections. For sessions with this policy setting, this sets the maximum number of physical TCP connections consists in a physical VPN session.
policy:TimeOut_u32number (uint32)Security policy: Time-out Period. For sessions with this policy setting, this sets, in seconds, the time-out period to wait before disconnecting a session when communication trouble occurs between the VPN Client / VPN Server.
policy:MaxMac_u32number (uint32)Security policy: Maximum Number of MAC Addresses. For sessions with this policy setting, this limits the number of MAC addresses per session.
policy:MaxIP_u32number (uint32)Security policy: Maximum Number of IP Addresses (IPv4). For sessions with this policy setting, this specifies the number of IPv4 addresses that can be registered for a single session.
policy:MaxUpload_u32number (uint32)Security policy: Upload Bandwidth. For sessions with this policy setting, this limits the traffic bandwidth that is in the inwards direction from outside to inside the Virtual Hub.
policy:MaxDownload_u32number (uint32)Security policy: Download Bandwidth. For sessions with this policy setting, this limits the traffic bandwidth that is in the outwards direction from inside the Virtual Hub to outside the Virtual Hub.
policy:FixPassword_boolbooleanSecurity policy: Deny Changing Password. The users which use password authentication with this policy setting are not allowed to change their own password from the VPN Client Manager or similar.
policy:MultiLogins_u32number (uint32)Security policy: Maximum Number of Multiple Logins. Users with this policy setting are unable to have more than this number of concurrent logins. Bridge Mode sessions are not subjects to this policy.
policy:NoQoS_boolbooleanSecurity policy: Deny VoIP / QoS Function. Users with this security policy are unable to use VoIP / QoS functions in VPN connection sessions.
policy:RSandRAFilter_boolbooleanSecurity policy: Filter RS / RA Packets (IPv6). All ICMPv6 packets which the message-type is 133 (Router Solicitation) or 134 (Router Advertisement) in sessions defined this policy will be filtered. As a result, an IPv6 client will be unable to use IPv6 address prefix auto detection and IPv6 default gateway auto detection.
policy:RAFilter_boolbooleanSecurity policy: Filter RA Packets (IPv6). All ICMPv6 packets which the message-type is 134 (Router Advertisement) in sessions defined this policy will be filtered. As a result, a malicious users will be unable to spread illegal IPv6 prefix or default gateway advertisements on the network.
policy:DHCPv6Filter_boolbooleanSecurity policy: Filter DHCP Packets (IPv6). All IPv6 DHCP packets in sessions defined this policy will be filtered.
policy:DHCPv6NoServer_boolbooleanSecurity policy: Disallow DHCP Server Operation (IPv6). Computers connected to sessions that have this policy setting will not be allowed to become a DHCP server and distribute IPv6 addresses to DHCP clients.
policy:NoRoutingV6_boolbooleanSecurity policy: Deny Routing Operation (IPv6). IPv6 routing will be denied for sessions that have this policy setting. Even in the case where the IP router is operating on the user client side, communication will not be possible.
policy:CheckIPv6_boolbooleanSecurity policy: Deny IP Address Duplication (IPv6). The use of duplicating IPv6 addresses that are in use by computers of different sessions cannot be used by sessions with this policy setting.
policy:NoServerV6_boolbooleanSecurity policy: Deny Operation as TCP/IP Server (IPv6). Computers of sessions with this policy setting can't listen and accept TCP/IP connections in IPv6.
policy:MaxIPv6_u32number (uint32)Security policy: Maximum Number of IP Addresses (IPv6). For sessions with this policy setting, this specifies the number of IPv6 addresses that can be registered for a single session.
policy:NoSavePassword_boolbooleanSecurity policy: Disallow Password Save in VPN Client. For users with this policy setting, when the user is using standard password authentication, the user will be unable to save the password in VPN Client. The user will be required to input passwords for every time to connect a VPN. This will improve the security. If this policy is enabled, VPN Client Version 2.0 will be denied to access.
policy:AutoDisconnect_u32number (uint32)Security policy: VPN Client Automatic Disconnect. For users with this policy setting, a user's VPN session will be disconnected automatically after the specific period will elapse. In this case no automatic re-connection will be performed. This can prevent a lot of inactive VPN Sessions. If this policy is enabled, VPN Client Version 2.0 will be denied to access.
policy:FilterIPv4_boolbooleanSecurity policy: Filter All IPv4 Packets. All IPv4 and ARP packets in sessions defined this policy will be filtered.
policy:FilterIPv6_boolbooleanSecurity policy: Filter All IPv6 Packets. All IPv6 packets in sessions defined this policy will be filtered.
policy:FilterNonIP_boolbooleanSecurity policy: Filter All Non-IP Packets. All non-IP packets in sessions defined this policy will be filtered. "Non-IP packet" mean a packet which is not IPv4, ARP nor IPv6. Any tagged-VLAN packets via the Virtual Hub will be regarded as non-IP packets.
policy:NoIPv6DefaultRouterInRA_boolbooleanSecurity policy: No Default-Router on IPv6 RA. In all VPN Sessions defines this policy, any IPv6 RA (Router Advertisement) packet with non-zero value in the router-lifetime will set to zero-value. This is effective to avoid the horrible behavior from the IPv6 routing confusion which is caused by the VPN client's attempts to use the remote-side IPv6 router as its local IPv6 router.
policy:NoIPv6DefaultRouterInRAWhenIPv6_boolbooleanSecurity policy: No Default-Router on IPv6 RA (physical IPv6). In all VPN Sessions defines this policy (only when the physical communication protocol between VPN Client / VPN Bridge and VPN Server is IPv6), any IPv6 RA (Router Advertisement) packet with non-zero value in the router-lifetime will set to zero-value. This is effective to avoid the horrible behavior from the IPv6 routing confusion which is caused by the VPN client's attempts to use the remote-side IPv6 router as its local IPv6 router.
policy:VLanId_u32number (uint32)Security policy: VLAN ID (IEEE802.1Q). You can specify the VLAN ID on the security policy. All VPN Sessions defines this policy, all Ethernet packets toward the Virtual Hub from the user will be inserted a VLAN tag (IEEE 802.1Q) with the VLAN ID. The user can also receive only packets with a VLAN tag which has the same VLAN ID. (Receiving process removes the VLAN tag automatically.) Any Ethernet packets with any other VLAN IDs or non-VLAN packets will not be received. All VPN Sessions without this policy definition can send / receive any kinds of Ethernet packets regardless of VLAN tags, and VLAN tags are not inserted or removed automatically. Any tagged-VLAN packets via the Virtual Hub will be regarded as non-IP packets. Therefore, tagged-VLAN packets are not subjects for IPv4 / IPv6 security policies, access lists nor other IPv4 / IPv6 specific deep processing.
policy:Ver3_boolbooleanSecurity policy: Whether version 3.0 (must be true)
+
+

+

"SetUser" RPC API - Change User Settings

+

Description

+

Change User Settings. Use this to change user settings that is registered on the security account database of the currently managed Virtual Hub. The user settings that can be changed using this API are the three items that are specified when a new user is created using the CreateUser API: Group Name, Full Name, and Description. To get the list of currently registered users, use the EnumUser API. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a member server on a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetUser",
+  "params": {
+    "HubName_str": "hubname",
+    "Name_str": "name",
+    "GroupName_str": "groupname",
+    "Realname_utf": "realname",
+    "Note_utf": "note",
+    "ExpireTime_dt": "2020-08-01T12:24:36.123",
+    "AuthType_u32": 0,
+    "Auth_Password_str": "auth_password",
+    "UserX_bin": "SGVsbG8gV29ybGQ=",
+    "Serial_bin": "SGVsbG8gV29ybGQ=",
+    "CommonName_utf": "auth_rootcert_commonname",
+    "RadiusUsername_utf": "auth_radius_radiususername",
+    "NtUsername_utf": "auth_nt_ntusername",
+    "UsePolicy_bool": false,
+    "policy:Access_bool": false,
+    "policy:DHCPFilter_bool": false,
+    "policy:DHCPNoServer_bool": false,
+    "policy:DHCPForce_bool": false,
+    "policy:NoBridge_bool": false,
+    "policy:NoRouting_bool": false,
+    "policy:CheckMac_bool": false,
+    "policy:CheckIP_bool": false,
+    "policy:ArpDhcpOnly_bool": false,
+    "policy:PrivacyFilter_bool": false,
+    "policy:NoServer_bool": false,
+    "policy:NoBroadcastLimiter_bool": false,
+    "policy:MonitorPort_bool": false,
+    "policy:MaxConnection_u32": 0,
+    "policy:TimeOut_u32": 0,
+    "policy:MaxMac_u32": 0,
+    "policy:MaxIP_u32": 0,
+    "policy:MaxUpload_u32": 0,
+    "policy:MaxDownload_u32": 0,
+    "policy:FixPassword_bool": false,
+    "policy:MultiLogins_u32": 0,
+    "policy:NoQoS_bool": false,
+    "policy:RSandRAFilter_bool": false,
+    "policy:RAFilter_bool": false,
+    "policy:DHCPv6Filter_bool": false,
+    "policy:DHCPv6NoServer_bool": false,
+    "policy:NoRoutingV6_bool": false,
+    "policy:CheckIPv6_bool": false,
+    "policy:NoServerV6_bool": false,
+    "policy:MaxIPv6_u32": 0,
+    "policy:NoSavePassword_bool": false,
+    "policy:AutoDisconnect_u32": 0,
+    "policy:FilterIPv4_bool": false,
+    "policy:FilterIPv6_bool": false,
+    "policy:FilterNonIP_bool": false,
+    "policy:NoIPv6DefaultRouterInRA_bool": false,
+    "policy:NoIPv6DefaultRouterInRAWhenIPv6_bool": false,
+    "policy:VLanId_u32": 0,
+    "policy:Ver3_bool": false
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "Name_str": "name",
+    "GroupName_str": "groupname",
+    "Realname_utf": "realname",
+    "Note_utf": "note",
+    "CreatedTime_dt": "2020-08-01T12:24:36.123",
+    "UpdatedTime_dt": "2020-08-01T12:24:36.123",
+    "ExpireTime_dt": "2020-08-01T12:24:36.123",
+    "AuthType_u32": 0,
+    "Auth_Password_str": "auth_password",
+    "UserX_bin": "SGVsbG8gV29ybGQ=",
+    "Serial_bin": "SGVsbG8gV29ybGQ=",
+    "CommonName_utf": "auth_rootcert_commonname",
+    "RadiusUsername_utf": "auth_radius_radiususername",
+    "NtUsername_utf": "auth_nt_ntusername",
+    "NumLogin_u32": 0,
+    "Recv.BroadcastBytes_u64": 0,
+    "Recv.BroadcastCount_u64": 0,
+    "Recv.UnicastBytes_u64": 0,
+    "Recv.UnicastCount_u64": 0,
+    "Send.BroadcastBytes_u64": 0,
+    "Send.BroadcastCount_u64": 0,
+    "Send.UnicastBytes_u64": 0,
+    "Send.UnicastCount_u64": 0,
+    "UsePolicy_bool": false,
+    "policy:Access_bool": false,
+    "policy:DHCPFilter_bool": false,
+    "policy:DHCPNoServer_bool": false,
+    "policy:DHCPForce_bool": false,
+    "policy:NoBridge_bool": false,
+    "policy:NoRouting_bool": false,
+    "policy:CheckMac_bool": false,
+    "policy:CheckIP_bool": false,
+    "policy:ArpDhcpOnly_bool": false,
+    "policy:PrivacyFilter_bool": false,
+    "policy:NoServer_bool": false,
+    "policy:NoBroadcastLimiter_bool": false,
+    "policy:MonitorPort_bool": false,
+    "policy:MaxConnection_u32": 0,
+    "policy:TimeOut_u32": 0,
+    "policy:MaxMac_u32": 0,
+    "policy:MaxIP_u32": 0,
+    "policy:MaxUpload_u32": 0,
+    "policy:MaxDownload_u32": 0,
+    "policy:FixPassword_bool": false,
+    "policy:MultiLogins_u32": 0,
+    "policy:NoQoS_bool": false,
+    "policy:RSandRAFilter_bool": false,
+    "policy:RAFilter_bool": false,
+    "policy:DHCPv6Filter_bool": false,
+    "policy:DHCPv6NoServer_bool": false,
+    "policy:NoRoutingV6_bool": false,
+    "policy:CheckIPv6_bool": false,
+    "policy:NoServerV6_bool": false,
+    "policy:MaxIPv6_u32": 0,
+    "policy:NoSavePassword_bool": false,
+    "policy:AutoDisconnect_u32": 0,
+    "policy:FilterIPv4_bool": false,
+    "policy:FilterIPv6_bool": false,
+    "policy:FilterNonIP_bool": false,
+    "policy:NoIPv6DefaultRouterInRA_bool": false,
+    "policy:NoIPv6DefaultRouterInRAWhenIPv6_bool": false,
+    "policy:VLanId_u32": 0,
+    "policy:Ver3_bool": false
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
Name_strstring (ASCII)Specify the user name of the user
GroupName_strstring (ASCII)Assigned group name for the user
Realname_utfstring (UTF8)Optional real name (full name) of the user, allow using any Unicode characters
Note_utfstring (UTF8)Optional User Description
CreatedTime_dtDateCreation date and time
UpdatedTime_dtDateLast modified date and time
ExpireTime_dtDateExpiration date and time
AuthType_u32number (enum)Authentication method of the user
Values:
0: Anonymous authentication
1: Password authentication
2: User certificate authentication
3: Root certificate which is issued by trusted Certificate Authority
4: Radius authentication
5: Windows NT authentication
Auth_Password_strstring (ASCII)User password, valid only if AuthType_u32 == Password(1). Valid only to create or set operations.
UserX_binstring (Base64 binary)User certificate, valid only if AuthType_u32 == UserCert(2).
Serial_binstring (Base64 binary)Certificate Serial Number, optional, valid only if AuthType_u32 == RootCert(3).
CommonName_utfstring (UTF8)Certificate Common Name, optional, valid only if AuthType_u32 == RootCert(3).
RadiusUsername_utfstring (UTF8)Username in RADIUS server, optional, valid only if AuthType_u32 == Radius(4).
NtUsername_utfstring (UTF8)Username in NT Domain server, optional, valid only if AuthType_u32 == NT(5).
NumLogin_u32number (uint32)Number of total logins of the user
Recv.BroadcastBytes_u64number (uint64)Number of broadcast packets (Recv)
Recv.BroadcastCount_u64number (uint64)Broadcast bytes (Recv)
Recv.UnicastBytes_u64number (uint64)Unicast count (Recv)
Recv.UnicastCount_u64number (uint64)Unicast bytes (Recv)
Send.BroadcastBytes_u64number (uint64)Number of broadcast packets (Send)
Send.BroadcastCount_u64number (uint64)Broadcast bytes (Send)
Send.UnicastBytes_u64number (uint64)Unicast bytes (Send)
Send.UnicastCount_u64number (uint64)Unicast bytes (Send)
UsePolicy_boolbooleanThe flag whether to use security policy
policy:Access_boolbooleanSecurity policy: Allow Access. The users, which this policy value is true, have permission to make VPN connection to VPN Server.
policy:DHCPFilter_boolbooleanSecurity policy: Filter DHCP Packets (IPv4). All IPv4 DHCP packets in sessions defined this policy will be filtered.
policy:DHCPNoServer_boolbooleanSecurity policy: Disallow DHCP Server Operation (IPv4). Computers connected to sessions that have this policy setting will not be allowed to become a DHCP server and distribute IPv4 addresses to DHCP clients.
policy:DHCPForce_boolbooleanSecurity policy: Enforce DHCP Allocated IP Addresses (IPv4). Computers in sessions that have this policy setting will only be able to use IPv4 addresses allocated by a DHCP server on the virtual network side.
policy:NoBridge_boolbooleanSecurity policy: Deny Bridge Operation. Bridge-mode connections are denied for user sessions that have this policy setting. Even in cases when the Ethernet Bridge is configured in the client side, communication will not be possible.
policy:NoRouting_boolbooleanSecurity policy: Deny Routing Operation (IPv4). IPv4 routing will be denied for sessions that have this policy setting. Even in the case where the IP router is operating on the user client side, communication will not be possible.
policy:CheckMac_boolbooleanSecurity policy: Deny MAC Addresses Duplication. The use of duplicating MAC addresses that are in use by computers of different sessions cannot be used by sessions with this policy setting.
policy:CheckIP_boolbooleanSecurity policy: Deny IP Address Duplication (IPv4). The use of duplicating IPv4 addresses that are in use by computers of different sessions cannot be used by sessions with this policy setting.
policy:ArpDhcpOnly_boolbooleanSecurity policy: Deny Non-ARP / Non-DHCP / Non-ICMPv6 broadcasts. The sending or receiving of broadcast packets that are not ARP protocol, DHCP protocol, nor ICMPv6 on the virtual network will not be allowed for sessions with this policy setting.
policy:PrivacyFilter_boolbooleanSecurity policy: Privacy Filter Mode. All direct communication between sessions with the privacy filter mode policy setting will be filtered.
policy:NoServer_boolbooleanSecurity policy: Deny Operation as TCP/IP Server (IPv4). Computers of sessions with this policy setting can't listen and accept TCP/IP connections in IPv4.
policy:NoBroadcastLimiter_boolbooleanSecurity policy: Unlimited Number of Broadcasts. If a computer of a session with this policy setting sends broadcast packets of a number unusually larger than what would be considered normal on the virtual network, there will be no automatic limiting.
policy:MonitorPort_boolbooleanSecurity policy: Allow Monitoring Mode. Users with this policy setting will be granted to connect to the Virtual Hub in Monitoring Mode. Sessions in Monitoring Mode are able to monitor (tap) all packets flowing through the Virtual Hub.
policy:MaxConnection_u32number (uint32)Security policy: Maximum Number of TCP Connections. For sessions with this policy setting, this sets the maximum number of physical TCP connections consists in a physical VPN session.
policy:TimeOut_u32number (uint32)Security policy: Time-out Period. For sessions with this policy setting, this sets, in seconds, the time-out period to wait before disconnecting a session when communication trouble occurs between the VPN Client / VPN Server.
policy:MaxMac_u32number (uint32)Security policy: Maximum Number of MAC Addresses. For sessions with this policy setting, this limits the number of MAC addresses per session.
policy:MaxIP_u32number (uint32)Security policy: Maximum Number of IP Addresses (IPv4). For sessions with this policy setting, this specifies the number of IPv4 addresses that can be registered for a single session.
policy:MaxUpload_u32number (uint32)Security policy: Upload Bandwidth. For sessions with this policy setting, this limits the traffic bandwidth that is in the inwards direction from outside to inside the Virtual Hub.
policy:MaxDownload_u32number (uint32)Security policy: Download Bandwidth. For sessions with this policy setting, this limits the traffic bandwidth that is in the outwards direction from inside the Virtual Hub to outside the Virtual Hub.
policy:FixPassword_boolbooleanSecurity policy: Deny Changing Password. The users which use password authentication with this policy setting are not allowed to change their own password from the VPN Client Manager or similar.
policy:MultiLogins_u32number (uint32)Security policy: Maximum Number of Multiple Logins. Users with this policy setting are unable to have more than this number of concurrent logins. Bridge Mode sessions are not subjects to this policy.
policy:NoQoS_boolbooleanSecurity policy: Deny VoIP / QoS Function. Users with this security policy are unable to use VoIP / QoS functions in VPN connection sessions.
policy:RSandRAFilter_boolbooleanSecurity policy: Filter RS / RA Packets (IPv6). All ICMPv6 packets which the message-type is 133 (Router Solicitation) or 134 (Router Advertisement) in sessions defined this policy will be filtered. As a result, an IPv6 client will be unable to use IPv6 address prefix auto detection and IPv6 default gateway auto detection.
policy:RAFilter_boolbooleanSecurity policy: Filter RA Packets (IPv6). All ICMPv6 packets which the message-type is 134 (Router Advertisement) in sessions defined this policy will be filtered. As a result, a malicious users will be unable to spread illegal IPv6 prefix or default gateway advertisements on the network.
policy:DHCPv6Filter_boolbooleanSecurity policy: Filter DHCP Packets (IPv6). All IPv6 DHCP packets in sessions defined this policy will be filtered.
policy:DHCPv6NoServer_boolbooleanSecurity policy: Disallow DHCP Server Operation (IPv6). Computers connected to sessions that have this policy setting will not be allowed to become a DHCP server and distribute IPv6 addresses to DHCP clients.
policy:NoRoutingV6_boolbooleanSecurity policy: Deny Routing Operation (IPv6). IPv6 routing will be denied for sessions that have this policy setting. Even in the case where the IP router is operating on the user client side, communication will not be possible.
policy:CheckIPv6_boolbooleanSecurity policy: Deny IP Address Duplication (IPv6). The use of duplicating IPv6 addresses that are in use by computers of different sessions cannot be used by sessions with this policy setting.
policy:NoServerV6_boolbooleanSecurity policy: Deny Operation as TCP/IP Server (IPv6). Computers of sessions with this policy setting can't listen and accept TCP/IP connections in IPv6.
policy:MaxIPv6_u32number (uint32)Security policy: Maximum Number of IP Addresses (IPv6). For sessions with this policy setting, this specifies the number of IPv6 addresses that can be registered for a single session.
policy:NoSavePassword_boolbooleanSecurity policy: Disallow Password Save in VPN Client. For users with this policy setting, when the user is using standard password authentication, the user will be unable to save the password in VPN Client. The user will be required to input passwords for every time to connect a VPN. This will improve the security. If this policy is enabled, VPN Client Version 2.0 will be denied to access.
policy:AutoDisconnect_u32number (uint32)Security policy: VPN Client Automatic Disconnect. For users with this policy setting, a user's VPN session will be disconnected automatically after the specific period will elapse. In this case no automatic re-connection will be performed. This can prevent a lot of inactive VPN Sessions. If this policy is enabled, VPN Client Version 2.0 will be denied to access.
policy:FilterIPv4_boolbooleanSecurity policy: Filter All IPv4 Packets. All IPv4 and ARP packets in sessions defined this policy will be filtered.
policy:FilterIPv6_boolbooleanSecurity policy: Filter All IPv6 Packets. All IPv6 packets in sessions defined this policy will be filtered.
policy:FilterNonIP_boolbooleanSecurity policy: Filter All Non-IP Packets. All non-IP packets in sessions defined this policy will be filtered. "Non-IP packet" mean a packet which is not IPv4, ARP nor IPv6. Any tagged-VLAN packets via the Virtual Hub will be regarded as non-IP packets.
policy:NoIPv6DefaultRouterInRA_boolbooleanSecurity policy: No Default-Router on IPv6 RA. In all VPN Sessions defines this policy, any IPv6 RA (Router Advertisement) packet with non-zero value in the router-lifetime will set to zero-value. This is effective to avoid the horrible behavior from the IPv6 routing confusion which is caused by the VPN client's attempts to use the remote-side IPv6 router as its local IPv6 router.
policy:NoIPv6DefaultRouterInRAWhenIPv6_boolbooleanSecurity policy: No Default-Router on IPv6 RA (physical IPv6). In all VPN Sessions defines this policy (only when the physical communication protocol between VPN Client / VPN Bridge and VPN Server is IPv6), any IPv6 RA (Router Advertisement) packet with non-zero value in the router-lifetime will set to zero-value. This is effective to avoid the horrible behavior from the IPv6 routing confusion which is caused by the VPN client's attempts to use the remote-side IPv6 router as its local IPv6 router.
policy:VLanId_u32number (uint32)Security policy: VLAN ID (IEEE802.1Q). You can specify the VLAN ID on the security policy. All VPN Sessions defines this policy, all Ethernet packets toward the Virtual Hub from the user will be inserted a VLAN tag (IEEE 802.1Q) with the VLAN ID. The user can also receive only packets with a VLAN tag which has the same VLAN ID. (Receiving process removes the VLAN tag automatically.) Any Ethernet packets with any other VLAN IDs or non-VLAN packets will not be received. All VPN Sessions without this policy definition can send / receive any kinds of Ethernet packets regardless of VLAN tags, and VLAN tags are not inserted or removed automatically. Any tagged-VLAN packets via the Virtual Hub will be regarded as non-IP packets. Therefore, tagged-VLAN packets are not subjects for IPv4 / IPv6 security policies, access lists nor other IPv4 / IPv6 specific deep processing.
policy:Ver3_boolbooleanSecurity policy: Whether version 3.0 (must be true)
+
+

+

"GetUser" RPC API - Get User Settings

+

Description

+

Get User Settings. Use this to get user settings information that is registered on the security account database of the currently managed Virtual Hub. The information that you can get using this API are User Name, Full Name, Group Name, Expiration Date, Security Policy, and Auth Type, as well as parameters that are specified as auth type attributes and the statistical data of that user. To get the list of currently registered users, use the EnumUser API. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a member server on a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetUser",
+  "params": {
+    "HubName_str": "hubname",
+    "Name_str": "name"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "Name_str": "name",
+    "GroupName_str": "groupname",
+    "Realname_utf": "realname",
+    "Note_utf": "note",
+    "CreatedTime_dt": "2020-08-01T12:24:36.123",
+    "UpdatedTime_dt": "2020-08-01T12:24:36.123",
+    "ExpireTime_dt": "2020-08-01T12:24:36.123",
+    "AuthType_u32": 0,
+    "Auth_Password_str": "auth_password",
+    "UserX_bin": "SGVsbG8gV29ybGQ=",
+    "Serial_bin": "SGVsbG8gV29ybGQ=",
+    "CommonName_utf": "auth_rootcert_commonname",
+    "RadiusUsername_utf": "auth_radius_radiususername",
+    "NtUsername_utf": "auth_nt_ntusername",
+    "NumLogin_u32": 0,
+    "Recv.BroadcastBytes_u64": 0,
+    "Recv.BroadcastCount_u64": 0,
+    "Recv.UnicastBytes_u64": 0,
+    "Recv.UnicastCount_u64": 0,
+    "Send.BroadcastBytes_u64": 0,
+    "Send.BroadcastCount_u64": 0,
+    "Send.UnicastBytes_u64": 0,
+    "Send.UnicastCount_u64": 0,
+    "UsePolicy_bool": false,
+    "policy:Access_bool": false,
+    "policy:DHCPFilter_bool": false,
+    "policy:DHCPNoServer_bool": false,
+    "policy:DHCPForce_bool": false,
+    "policy:NoBridge_bool": false,
+    "policy:NoRouting_bool": false,
+    "policy:CheckMac_bool": false,
+    "policy:CheckIP_bool": false,
+    "policy:ArpDhcpOnly_bool": false,
+    "policy:PrivacyFilter_bool": false,
+    "policy:NoServer_bool": false,
+    "policy:NoBroadcastLimiter_bool": false,
+    "policy:MonitorPort_bool": false,
+    "policy:MaxConnection_u32": 0,
+    "policy:TimeOut_u32": 0,
+    "policy:MaxMac_u32": 0,
+    "policy:MaxIP_u32": 0,
+    "policy:MaxUpload_u32": 0,
+    "policy:MaxDownload_u32": 0,
+    "policy:FixPassword_bool": false,
+    "policy:MultiLogins_u32": 0,
+    "policy:NoQoS_bool": false,
+    "policy:RSandRAFilter_bool": false,
+    "policy:RAFilter_bool": false,
+    "policy:DHCPv6Filter_bool": false,
+    "policy:DHCPv6NoServer_bool": false,
+    "policy:NoRoutingV6_bool": false,
+    "policy:CheckIPv6_bool": false,
+    "policy:NoServerV6_bool": false,
+    "policy:MaxIPv6_u32": 0,
+    "policy:NoSavePassword_bool": false,
+    "policy:AutoDisconnect_u32": 0,
+    "policy:FilterIPv4_bool": false,
+    "policy:FilterIPv6_bool": false,
+    "policy:FilterNonIP_bool": false,
+    "policy:NoIPv6DefaultRouterInRA_bool": false,
+    "policy:NoIPv6DefaultRouterInRAWhenIPv6_bool": false,
+    "policy:VLanId_u32": 0,
+    "policy:Ver3_bool": false
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
Name_strstring (ASCII)Specify the user name of the user
GroupName_strstring (ASCII)Assigned group name for the user
Realname_utfstring (UTF8)Optional real name (full name) of the user, allow using any Unicode characters
Note_utfstring (UTF8)Optional User Description
CreatedTime_dtDateCreation date and time
UpdatedTime_dtDateLast modified date and time
ExpireTime_dtDateExpiration date and time
AuthType_u32number (enum)Authentication method of the user
Values:
0: Anonymous authentication
1: Password authentication
2: User certificate authentication
3: Root certificate which is issued by trusted Certificate Authority
4: Radius authentication
5: Windows NT authentication
Auth_Password_strstring (ASCII)User password, valid only if AuthType_u32 == Password(1). Valid only to create or set operations.
UserX_binstring (Base64 binary)User certificate, valid only if AuthType_u32 == UserCert(2).
Serial_binstring (Base64 binary)Certificate Serial Number, optional, valid only if AuthType_u32 == RootCert(3).
CommonName_utfstring (UTF8)Certificate Common Name, optional, valid only if AuthType_u32 == RootCert(3).
RadiusUsername_utfstring (UTF8)Username in RADIUS server, optional, valid only if AuthType_u32 == Radius(4).
NtUsername_utfstring (UTF8)Username in NT Domain server, optional, valid only if AuthType_u32 == NT(5).
NumLogin_u32number (uint32)Number of total logins of the user
Recv.BroadcastBytes_u64number (uint64)Number of broadcast packets (Recv)
Recv.BroadcastCount_u64number (uint64)Broadcast bytes (Recv)
Recv.UnicastBytes_u64number (uint64)Unicast count (Recv)
Recv.UnicastCount_u64number (uint64)Unicast bytes (Recv)
Send.BroadcastBytes_u64number (uint64)Number of broadcast packets (Send)
Send.BroadcastCount_u64number (uint64)Broadcast bytes (Send)
Send.UnicastBytes_u64number (uint64)Unicast bytes (Send)
Send.UnicastCount_u64number (uint64)Unicast bytes (Send)
UsePolicy_boolbooleanThe flag whether to use security policy
policy:Access_boolbooleanSecurity policy: Allow Access. The users, which this policy value is true, have permission to make VPN connection to VPN Server.
policy:DHCPFilter_boolbooleanSecurity policy: Filter DHCP Packets (IPv4). All IPv4 DHCP packets in sessions defined this policy will be filtered.
policy:DHCPNoServer_boolbooleanSecurity policy: Disallow DHCP Server Operation (IPv4). Computers connected to sessions that have this policy setting will not be allowed to become a DHCP server and distribute IPv4 addresses to DHCP clients.
policy:DHCPForce_boolbooleanSecurity policy: Enforce DHCP Allocated IP Addresses (IPv4). Computers in sessions that have this policy setting will only be able to use IPv4 addresses allocated by a DHCP server on the virtual network side.
policy:NoBridge_boolbooleanSecurity policy: Deny Bridge Operation. Bridge-mode connections are denied for user sessions that have this policy setting. Even in cases when the Ethernet Bridge is configured in the client side, communication will not be possible.
policy:NoRouting_boolbooleanSecurity policy: Deny Routing Operation (IPv4). IPv4 routing will be denied for sessions that have this policy setting. Even in the case where the IP router is operating on the user client side, communication will not be possible.
policy:CheckMac_boolbooleanSecurity policy: Deny MAC Addresses Duplication. The use of duplicating MAC addresses that are in use by computers of different sessions cannot be used by sessions with this policy setting.
policy:CheckIP_boolbooleanSecurity policy: Deny IP Address Duplication (IPv4). The use of duplicating IPv4 addresses that are in use by computers of different sessions cannot be used by sessions with this policy setting.
policy:ArpDhcpOnly_boolbooleanSecurity policy: Deny Non-ARP / Non-DHCP / Non-ICMPv6 broadcasts. The sending or receiving of broadcast packets that are not ARP protocol, DHCP protocol, nor ICMPv6 on the virtual network will not be allowed for sessions with this policy setting.
policy:PrivacyFilter_boolbooleanSecurity policy: Privacy Filter Mode. All direct communication between sessions with the privacy filter mode policy setting will be filtered.
policy:NoServer_boolbooleanSecurity policy: Deny Operation as TCP/IP Server (IPv4). Computers of sessions with this policy setting can't listen and accept TCP/IP connections in IPv4.
policy:NoBroadcastLimiter_boolbooleanSecurity policy: Unlimited Number of Broadcasts. If a computer of a session with this policy setting sends broadcast packets of a number unusually larger than what would be considered normal on the virtual network, there will be no automatic limiting.
policy:MonitorPort_boolbooleanSecurity policy: Allow Monitoring Mode. Users with this policy setting will be granted to connect to the Virtual Hub in Monitoring Mode. Sessions in Monitoring Mode are able to monitor (tap) all packets flowing through the Virtual Hub.
policy:MaxConnection_u32number (uint32)Security policy: Maximum Number of TCP Connections. For sessions with this policy setting, this sets the maximum number of physical TCP connections consists in a physical VPN session.
policy:TimeOut_u32number (uint32)Security policy: Time-out Period. For sessions with this policy setting, this sets, in seconds, the time-out period to wait before disconnecting a session when communication trouble occurs between the VPN Client / VPN Server.
policy:MaxMac_u32number (uint32)Security policy: Maximum Number of MAC Addresses. For sessions with this policy setting, this limits the number of MAC addresses per session.
policy:MaxIP_u32number (uint32)Security policy: Maximum Number of IP Addresses (IPv4). For sessions with this policy setting, this specifies the number of IPv4 addresses that can be registered for a single session.
policy:MaxUpload_u32number (uint32)Security policy: Upload Bandwidth. For sessions with this policy setting, this limits the traffic bandwidth that is in the inwards direction from outside to inside the Virtual Hub.
policy:MaxDownload_u32number (uint32)Security policy: Download Bandwidth. For sessions with this policy setting, this limits the traffic bandwidth that is in the outwards direction from inside the Virtual Hub to outside the Virtual Hub.
policy:FixPassword_boolbooleanSecurity policy: Deny Changing Password. The users which use password authentication with this policy setting are not allowed to change their own password from the VPN Client Manager or similar.
policy:MultiLogins_u32number (uint32)Security policy: Maximum Number of Multiple Logins. Users with this policy setting are unable to have more than this number of concurrent logins. Bridge Mode sessions are not subjects to this policy.
policy:NoQoS_boolbooleanSecurity policy: Deny VoIP / QoS Function. Users with this security policy are unable to use VoIP / QoS functions in VPN connection sessions.
policy:RSandRAFilter_boolbooleanSecurity policy: Filter RS / RA Packets (IPv6). All ICMPv6 packets which the message-type is 133 (Router Solicitation) or 134 (Router Advertisement) in sessions defined this policy will be filtered. As a result, an IPv6 client will be unable to use IPv6 address prefix auto detection and IPv6 default gateway auto detection.
policy:RAFilter_boolbooleanSecurity policy: Filter RA Packets (IPv6). All ICMPv6 packets which the message-type is 134 (Router Advertisement) in sessions defined this policy will be filtered. As a result, a malicious users will be unable to spread illegal IPv6 prefix or default gateway advertisements on the network.
policy:DHCPv6Filter_boolbooleanSecurity policy: Filter DHCP Packets (IPv6). All IPv6 DHCP packets in sessions defined this policy will be filtered.
policy:DHCPv6NoServer_boolbooleanSecurity policy: Disallow DHCP Server Operation (IPv6). Computers connected to sessions that have this policy setting will not be allowed to become a DHCP server and distribute IPv6 addresses to DHCP clients.
policy:NoRoutingV6_boolbooleanSecurity policy: Deny Routing Operation (IPv6). IPv6 routing will be denied for sessions that have this policy setting. Even in the case where the IP router is operating on the user client side, communication will not be possible.
policy:CheckIPv6_boolbooleanSecurity policy: Deny IP Address Duplication (IPv6). The use of duplicating IPv6 addresses that are in use by computers of different sessions cannot be used by sessions with this policy setting.
policy:NoServerV6_boolbooleanSecurity policy: Deny Operation as TCP/IP Server (IPv6). Computers of sessions with this policy setting can't listen and accept TCP/IP connections in IPv6.
policy:MaxIPv6_u32number (uint32)Security policy: Maximum Number of IP Addresses (IPv6). For sessions with this policy setting, this specifies the number of IPv6 addresses that can be registered for a single session.
policy:NoSavePassword_boolbooleanSecurity policy: Disallow Password Save in VPN Client. For users with this policy setting, when the user is using standard password authentication, the user will be unable to save the password in VPN Client. The user will be required to input passwords for every time to connect a VPN. This will improve the security. If this policy is enabled, VPN Client Version 2.0 will be denied to access.
policy:AutoDisconnect_u32number (uint32)Security policy: VPN Client Automatic Disconnect. For users with this policy setting, a user's VPN session will be disconnected automatically after the specific period will elapse. In this case no automatic re-connection will be performed. This can prevent a lot of inactive VPN Sessions. If this policy is enabled, VPN Client Version 2.0 will be denied to access.
policy:FilterIPv4_boolbooleanSecurity policy: Filter All IPv4 Packets. All IPv4 and ARP packets in sessions defined this policy will be filtered.
policy:FilterIPv6_boolbooleanSecurity policy: Filter All IPv6 Packets. All IPv6 packets in sessions defined this policy will be filtered.
policy:FilterNonIP_boolbooleanSecurity policy: Filter All Non-IP Packets. All non-IP packets in sessions defined this policy will be filtered. "Non-IP packet" mean a packet which is not IPv4, ARP nor IPv6. Any tagged-VLAN packets via the Virtual Hub will be regarded as non-IP packets.
policy:NoIPv6DefaultRouterInRA_boolbooleanSecurity policy: No Default-Router on IPv6 RA. In all VPN Sessions defines this policy, any IPv6 RA (Router Advertisement) packet with non-zero value in the router-lifetime will set to zero-value. This is effective to avoid the horrible behavior from the IPv6 routing confusion which is caused by the VPN client's attempts to use the remote-side IPv6 router as its local IPv6 router.
policy:NoIPv6DefaultRouterInRAWhenIPv6_boolbooleanSecurity policy: No Default-Router on IPv6 RA (physical IPv6). In all VPN Sessions defines this policy (only when the physical communication protocol between VPN Client / VPN Bridge and VPN Server is IPv6), any IPv6 RA (Router Advertisement) packet with non-zero value in the router-lifetime will set to zero-value. This is effective to avoid the horrible behavior from the IPv6 routing confusion which is caused by the VPN client's attempts to use the remote-side IPv6 router as its local IPv6 router.
policy:VLanId_u32number (uint32)Security policy: VLAN ID (IEEE802.1Q). You can specify the VLAN ID on the security policy. All VPN Sessions defines this policy, all Ethernet packets toward the Virtual Hub from the user will be inserted a VLAN tag (IEEE 802.1Q) with the VLAN ID. The user can also receive only packets with a VLAN tag which has the same VLAN ID. (Receiving process removes the VLAN tag automatically.) Any Ethernet packets with any other VLAN IDs or non-VLAN packets will not be received. All VPN Sessions without this policy definition can send / receive any kinds of Ethernet packets regardless of VLAN tags, and VLAN tags are not inserted or removed automatically. Any tagged-VLAN packets via the Virtual Hub will be regarded as non-IP packets. Therefore, tagged-VLAN packets are not subjects for IPv4 / IPv6 security policies, access lists nor other IPv4 / IPv6 specific deep processing.
policy:Ver3_boolbooleanSecurity policy: Whether version 3.0 (must be true)
+
+

+

"DeleteUser" RPC API - Delete a user

+

Description

+

Delete a user. Use this to delete a user that is registered on the security account database of the currently managed Virtual Hub. By deleting the user, that user will no long be able to connect to the Virtual Hub. You can use the SetUser API to set the user's security policy to deny access instead of deleting a user, set the user to be temporarily denied from logging in. To get the list of currently registered users, use the EnumUser API. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a member server on a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "DeleteUser",
+  "params": {
+    "HubName_str": "hubname",
+    "Name_str": "name"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "Name_str": "name"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
Name_strstring (ASCII)User or group name
+
+

+

"EnumUser" RPC API - Get List of Users

+

Description

+

Get List of Users. Use this to get a list of users that are registered on the security account database of the currently managed Virtual Hub. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a member server on a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "EnumUser",
+  "params": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "UserList": [
+      {
+        "Name_str": "name",
+        "GroupName_str": "groupname",
+        "Realname_utf": "realname",
+        "Note_utf": "note",
+        "AuthType_u32": 0,
+        "NumLogin_u32": 0,
+        "LastLoginTime_dt": "2020-08-01T12:24:36.123",
+        "DenyAccess_bool": false,
+        "IsTrafficFilled_bool": false,
+        "IsExpiresFilled_bool": false,
+        "Expires_dt": "2020-08-01T12:24:36.123",
+        "Ex.Recv.BroadcastBytes_u64": 0,
+        "Ex.Recv.BroadcastCount_u64": 0,
+        "Ex.Recv.UnicastBytes_u64": 0,
+        "Ex.Recv.UnicastCount_u64": 0,
+        "Ex.Send.BroadcastBytes_u64": 0,
+        "Ex.Send.BroadcastCount_u64": 0,
+        "Ex.Send.UnicastBytes_u64": 0,
+        "Ex.Send.UnicastCount_u64": 0
+      },
+      {
+        "Name_str": "name",
+        "GroupName_str": "groupname",
+        "Realname_utf": "realname",
+        "Note_utf": "note",
+        "AuthType_u32": 0,
+        "NumLogin_u32": 0,
+        "LastLoginTime_dt": "2020-08-01T12:24:36.123",
+        "DenyAccess_bool": false,
+        "IsTrafficFilled_bool": false,
+        "IsExpiresFilled_bool": false,
+        "Expires_dt": "2020-08-01T12:24:36.123",
+        "Ex.Recv.BroadcastBytes_u64": 0,
+        "Ex.Recv.BroadcastCount_u64": 0,
+        "Ex.Recv.UnicastBytes_u64": 0,
+        "Ex.Recv.UnicastCount_u64": 0,
+        "Ex.Send.BroadcastBytes_u64": 0,
+        "Ex.Send.BroadcastCount_u64": 0,
+        "Ex.Send.UnicastBytes_u64": 0,
+        "Ex.Send.UnicastCount_u64": 0
+      },
+      {
+        "Name_str": "name",
+        "GroupName_str": "groupname",
+        "Realname_utf": "realname",
+        "Note_utf": "note",
+        "AuthType_u32": 0,
+        "NumLogin_u32": 0,
+        "LastLoginTime_dt": "2020-08-01T12:24:36.123",
+        "DenyAccess_bool": false,
+        "IsTrafficFilled_bool": false,
+        "IsExpiresFilled_bool": false,
+        "Expires_dt": "2020-08-01T12:24:36.123",
+        "Ex.Recv.BroadcastBytes_u64": 0,
+        "Ex.Recv.BroadcastCount_u64": 0,
+        "Ex.Recv.UnicastBytes_u64": 0,
+        "Ex.Recv.UnicastCount_u64": 0,
+        "Ex.Send.BroadcastBytes_u64": 0,
+        "Ex.Send.BroadcastCount_u64": 0,
+        "Ex.Send.UnicastBytes_u64": 0,
+        "Ex.Send.UnicastCount_u64": 0
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
UserListArray objectUser list
Name_strstring (ASCII)User name
GroupName_strstring (ASCII)Group name
Realname_utfstring (UTF8)Real name
Note_utfstring (UTF8)Note
AuthType_u32number (enum)Authentication method
Values:
0: Anonymous authentication
1: Password authentication
2: User certificate authentication
3: Root certificate which is issued by trusted Certificate Authority
4: Radius authentication
5: Windows NT authentication
NumLogin_u32number (uint32)Number of logins
LastLoginTime_dtDateLast login date and time
DenyAccess_boolbooleanAccess denied
IsTrafficFilled_boolbooleanFlag of whether the traffic variable is set
IsExpiresFilled_boolbooleanFlag of whether expiration date variable is set
Expires_dtDateExpiration date
Ex.Recv.BroadcastBytes_u64number (uint64)Number of broadcast packets (Recv)
Ex.Recv.BroadcastCount_u64number (uint64)Broadcast bytes (Recv)
Ex.Recv.UnicastBytes_u64number (uint64)Unicast count (Recv)
Ex.Recv.UnicastCount_u64number (uint64)Unicast bytes (Recv)
Ex.Send.BroadcastBytes_u64number (uint64)Number of broadcast packets (Send)
Ex.Send.BroadcastCount_u64number (uint64)Broadcast bytes (Send)
Ex.Send.UnicastBytes_u64number (uint64)Unicast bytes (Send)
Ex.Send.UnicastCount_u64number (uint64)Unicast bytes (Send)
+
+

+

"CreateGroup" RPC API - Create Group

+

Description

+

Create Group. Use this to create a new group in the security account database of the currently managed Virtual Hub. You can register multiple users in a group. To register users in a group use the SetUser API. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a member server on a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "CreateGroup",
+  "params": {
+    "HubName_str": "hubname",
+    "Name_str": "name",
+    "Realname_utf": "realname",
+    "Note_utf": "note",
+    "UsePolicy_bool": false,
+    "policy:Access_bool": false,
+    "policy:DHCPFilter_bool": false,
+    "policy:DHCPNoServer_bool": false,
+    "policy:DHCPForce_bool": false,
+    "policy:NoBridge_bool": false,
+    "policy:NoRouting_bool": false,
+    "policy:CheckMac_bool": false,
+    "policy:CheckIP_bool": false,
+    "policy:ArpDhcpOnly_bool": false,
+    "policy:PrivacyFilter_bool": false,
+    "policy:NoServer_bool": false,
+    "policy:NoBroadcastLimiter_bool": false,
+    "policy:MonitorPort_bool": false,
+    "policy:MaxConnection_u32": 0,
+    "policy:TimeOut_u32": 0,
+    "policy:MaxMac_u32": 0,
+    "policy:MaxIP_u32": 0,
+    "policy:MaxUpload_u32": 0,
+    "policy:MaxDownload_u32": 0,
+    "policy:FixPassword_bool": false,
+    "policy:MultiLogins_u32": 0,
+    "policy:NoQoS_bool": false,
+    "policy:RSandRAFilter_bool": false,
+    "policy:RAFilter_bool": false,
+    "policy:DHCPv6Filter_bool": false,
+    "policy:DHCPv6NoServer_bool": false,
+    "policy:NoRoutingV6_bool": false,
+    "policy:CheckIPv6_bool": false,
+    "policy:NoServerV6_bool": false,
+    "policy:MaxIPv6_u32": 0,
+    "policy:NoSavePassword_bool": false,
+    "policy:AutoDisconnect_u32": 0,
+    "policy:FilterIPv4_bool": false,
+    "policy:FilterIPv6_bool": false,
+    "policy:FilterNonIP_bool": false,
+    "policy:NoIPv6DefaultRouterInRA_bool": false,
+    "policy:NoIPv6DefaultRouterInRAWhenIPv6_bool": false,
+    "policy:VLanId_u32": 0,
+    "policy:Ver3_bool": false
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "Name_str": "name",
+    "Realname_utf": "realname",
+    "Note_utf": "note",
+    "Recv.BroadcastBytes_u64": 0,
+    "Recv.BroadcastCount_u64": 0,
+    "Recv.UnicastBytes_u64": 0,
+    "Recv.UnicastCount_u64": 0,
+    "Send.BroadcastBytes_u64": 0,
+    "Send.BroadcastCount_u64": 0,
+    "Send.UnicastBytes_u64": 0,
+    "Send.UnicastCount_u64": 0,
+    "UsePolicy_bool": false,
+    "policy:Access_bool": false,
+    "policy:DHCPFilter_bool": false,
+    "policy:DHCPNoServer_bool": false,
+    "policy:DHCPForce_bool": false,
+    "policy:NoBridge_bool": false,
+    "policy:NoRouting_bool": false,
+    "policy:CheckMac_bool": false,
+    "policy:CheckIP_bool": false,
+    "policy:ArpDhcpOnly_bool": false,
+    "policy:PrivacyFilter_bool": false,
+    "policy:NoServer_bool": false,
+    "policy:NoBroadcastLimiter_bool": false,
+    "policy:MonitorPort_bool": false,
+    "policy:MaxConnection_u32": 0,
+    "policy:TimeOut_u32": 0,
+    "policy:MaxMac_u32": 0,
+    "policy:MaxIP_u32": 0,
+    "policy:MaxUpload_u32": 0,
+    "policy:MaxDownload_u32": 0,
+    "policy:FixPassword_bool": false,
+    "policy:MultiLogins_u32": 0,
+    "policy:NoQoS_bool": false,
+    "policy:RSandRAFilter_bool": false,
+    "policy:RAFilter_bool": false,
+    "policy:DHCPv6Filter_bool": false,
+    "policy:DHCPv6NoServer_bool": false,
+    "policy:NoRoutingV6_bool": false,
+    "policy:CheckIPv6_bool": false,
+    "policy:NoServerV6_bool": false,
+    "policy:MaxIPv6_u32": 0,
+    "policy:NoSavePassword_bool": false,
+    "policy:AutoDisconnect_u32": 0,
+    "policy:FilterIPv4_bool": false,
+    "policy:FilterIPv6_bool": false,
+    "policy:FilterNonIP_bool": false,
+    "policy:NoIPv6DefaultRouterInRA_bool": false,
+    "policy:NoIPv6DefaultRouterInRAWhenIPv6_bool": false,
+    "policy:VLanId_u32": 0,
+    "policy:Ver3_bool": false
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
Name_strstring (ASCII)The group name
Realname_utfstring (UTF8)Optional real name (full name) of the group, allow using any Unicode characters
Note_utfstring (UTF8)Optional, specify a description of the group
Recv.BroadcastBytes_u64number (uint64)Number of broadcast packets (Recv)
Recv.BroadcastCount_u64number (uint64)Broadcast bytes (Recv)
Recv.UnicastBytes_u64number (uint64)Unicast count (Recv)
Recv.UnicastCount_u64number (uint64)Unicast bytes (Recv)
Send.BroadcastBytes_u64number (uint64)Number of broadcast packets (Send)
Send.BroadcastCount_u64number (uint64)Broadcast bytes (Send)
Send.UnicastBytes_u64number (uint64)Unicast bytes (Send)
Send.UnicastCount_u64number (uint64)Unicast bytes (Send)
UsePolicy_boolbooleanThe flag whether to use security policy
policy:Access_boolbooleanSecurity policy: Allow Access. The users, which this policy value is true, have permission to make VPN connection to VPN Server.
policy:DHCPFilter_boolbooleanSecurity policy: Filter DHCP Packets (IPv4). All IPv4 DHCP packets in sessions defined this policy will be filtered.
policy:DHCPNoServer_boolbooleanSecurity policy: Disallow DHCP Server Operation (IPv4). Computers connected to sessions that have this policy setting will not be allowed to become a DHCP server and distribute IPv4 addresses to DHCP clients.
policy:DHCPForce_boolbooleanSecurity policy: Enforce DHCP Allocated IP Addresses (IPv4). Computers in sessions that have this policy setting will only be able to use IPv4 addresses allocated by a DHCP server on the virtual network side.
policy:NoBridge_boolbooleanSecurity policy: Deny Bridge Operation. Bridge-mode connections are denied for user sessions that have this policy setting. Even in cases when the Ethernet Bridge is configured in the client side, communication will not be possible.
policy:NoRouting_boolbooleanSecurity policy: Deny Routing Operation (IPv4). IPv4 routing will be denied for sessions that have this policy setting. Even in the case where the IP router is operating on the user client side, communication will not be possible.
policy:CheckMac_boolbooleanSecurity policy: Deny MAC Addresses Duplication. The use of duplicating MAC addresses that are in use by computers of different sessions cannot be used by sessions with this policy setting.
policy:CheckIP_boolbooleanSecurity policy: Deny IP Address Duplication (IPv4). The use of duplicating IPv4 addresses that are in use by computers of different sessions cannot be used by sessions with this policy setting.
policy:ArpDhcpOnly_boolbooleanSecurity policy: Deny Non-ARP / Non-DHCP / Non-ICMPv6 broadcasts. The sending or receiving of broadcast packets that are not ARP protocol, DHCP protocol, nor ICMPv6 on the virtual network will not be allowed for sessions with this policy setting.
policy:PrivacyFilter_boolbooleanSecurity policy: Privacy Filter Mode. All direct communication between sessions with the privacy filter mode policy setting will be filtered.
policy:NoServer_boolbooleanSecurity policy: Deny Operation as TCP/IP Server (IPv4). Computers of sessions with this policy setting can't listen and accept TCP/IP connections in IPv4.
policy:NoBroadcastLimiter_boolbooleanSecurity policy: Unlimited Number of Broadcasts. If a computer of a session with this policy setting sends broadcast packets of a number unusually larger than what would be considered normal on the virtual network, there will be no automatic limiting.
policy:MonitorPort_boolbooleanSecurity policy: Allow Monitoring Mode. Users with this policy setting will be granted to connect to the Virtual Hub in Monitoring Mode. Sessions in Monitoring Mode are able to monitor (tap) all packets flowing through the Virtual Hub.
policy:MaxConnection_u32number (uint32)Security policy: Maximum Number of TCP Connections. For sessions with this policy setting, this sets the maximum number of physical TCP connections consists in a physical VPN session.
policy:TimeOut_u32number (uint32)Security policy: Time-out Period. For sessions with this policy setting, this sets, in seconds, the time-out period to wait before disconnecting a session when communication trouble occurs between the VPN Client / VPN Server.
policy:MaxMac_u32number (uint32)Security policy: Maximum Number of MAC Addresses. For sessions with this policy setting, this limits the number of MAC addresses per session.
policy:MaxIP_u32number (uint32)Security policy: Maximum Number of IP Addresses (IPv4). For sessions with this policy setting, this specifies the number of IPv4 addresses that can be registered for a single session.
policy:MaxUpload_u32number (uint32)Security policy: Upload Bandwidth. For sessions with this policy setting, this limits the traffic bandwidth that is in the inwards direction from outside to inside the Virtual Hub.
policy:MaxDownload_u32number (uint32)Security policy: Download Bandwidth. For sessions with this policy setting, this limits the traffic bandwidth that is in the outwards direction from inside the Virtual Hub to outside the Virtual Hub.
policy:FixPassword_boolbooleanSecurity policy: Deny Changing Password. The users which use password authentication with this policy setting are not allowed to change their own password from the VPN Client Manager or similar.
policy:MultiLogins_u32number (uint32)Security policy: Maximum Number of Multiple Logins. Users with this policy setting are unable to have more than this number of concurrent logins. Bridge Mode sessions are not subjects to this policy.
policy:NoQoS_boolbooleanSecurity policy: Deny VoIP / QoS Function. Users with this security policy are unable to use VoIP / QoS functions in VPN connection sessions.
policy:RSandRAFilter_boolbooleanSecurity policy: Filter RS / RA Packets (IPv6). All ICMPv6 packets which the message-type is 133 (Router Solicitation) or 134 (Router Advertisement) in sessions defined this policy will be filtered. As a result, an IPv6 client will be unable to use IPv6 address prefix auto detection and IPv6 default gateway auto detection.
policy:RAFilter_boolbooleanSecurity policy: Filter RA Packets (IPv6). All ICMPv6 packets which the message-type is 134 (Router Advertisement) in sessions defined this policy will be filtered. As a result, a malicious users will be unable to spread illegal IPv6 prefix or default gateway advertisements on the network.
policy:DHCPv6Filter_boolbooleanSecurity policy: Filter DHCP Packets (IPv6). All IPv6 DHCP packets in sessions defined this policy will be filtered.
policy:DHCPv6NoServer_boolbooleanSecurity policy: Disallow DHCP Server Operation (IPv6). Computers connected to sessions that have this policy setting will not be allowed to become a DHCP server and distribute IPv6 addresses to DHCP clients.
policy:NoRoutingV6_boolbooleanSecurity policy: Deny Routing Operation (IPv6). IPv6 routing will be denied for sessions that have this policy setting. Even in the case where the IP router is operating on the user client side, communication will not be possible.
policy:CheckIPv6_boolbooleanSecurity policy: Deny IP Address Duplication (IPv6). The use of duplicating IPv6 addresses that are in use by computers of different sessions cannot be used by sessions with this policy setting.
policy:NoServerV6_boolbooleanSecurity policy: Deny Operation as TCP/IP Server (IPv6). Computers of sessions with this policy setting can't listen and accept TCP/IP connections in IPv6.
policy:MaxIPv6_u32number (uint32)Security policy: Maximum Number of IP Addresses (IPv6). For sessions with this policy setting, this specifies the number of IPv6 addresses that can be registered for a single session.
policy:NoSavePassword_boolbooleanSecurity policy: Disallow Password Save in VPN Client. For users with this policy setting, when the user is using standard password authentication, the user will be unable to save the password in VPN Client. The user will be required to input passwords for every time to connect a VPN. This will improve the security. If this policy is enabled, VPN Client Version 2.0 will be denied to access.
policy:AutoDisconnect_u32number (uint32)Security policy: VPN Client Automatic Disconnect. For users with this policy setting, a user's VPN session will be disconnected automatically after the specific period will elapse. In this case no automatic re-connection will be performed. This can prevent a lot of inactive VPN Sessions. If this policy is enabled, VPN Client Version 2.0 will be denied to access.
policy:FilterIPv4_boolbooleanSecurity policy: Filter All IPv4 Packets. All IPv4 and ARP packets in sessions defined this policy will be filtered.
policy:FilterIPv6_boolbooleanSecurity policy: Filter All IPv6 Packets. All IPv6 packets in sessions defined this policy will be filtered.
policy:FilterNonIP_boolbooleanSecurity policy: Filter All Non-IP Packets. All non-IP packets in sessions defined this policy will be filtered. "Non-IP packet" mean a packet which is not IPv4, ARP nor IPv6. Any tagged-VLAN packets via the Virtual Hub will be regarded as non-IP packets.
policy:NoIPv6DefaultRouterInRA_boolbooleanSecurity policy: No Default-Router on IPv6 RA. In all VPN Sessions defines this policy, any IPv6 RA (Router Advertisement) packet with non-zero value in the router-lifetime will set to zero-value. This is effective to avoid the horrible behavior from the IPv6 routing confusion which is caused by the VPN client's attempts to use the remote-side IPv6 router as its local IPv6 router.
policy:NoIPv6DefaultRouterInRAWhenIPv6_boolbooleanSecurity policy: No Default-Router on IPv6 RA (physical IPv6). In all VPN Sessions defines this policy (only when the physical communication protocol between VPN Client / VPN Bridge and VPN Server is IPv6), any IPv6 RA (Router Advertisement) packet with non-zero value in the router-lifetime will set to zero-value. This is effective to avoid the horrible behavior from the IPv6 routing confusion which is caused by the VPN client's attempts to use the remote-side IPv6 router as its local IPv6 router.
policy:VLanId_u32number (uint32)Security policy: VLAN ID (IEEE802.1Q). You can specify the VLAN ID on the security policy. All VPN Sessions defines this policy, all Ethernet packets toward the Virtual Hub from the user will be inserted a VLAN tag (IEEE 802.1Q) with the VLAN ID. The user can also receive only packets with a VLAN tag which has the same VLAN ID. (Receiving process removes the VLAN tag automatically.) Any Ethernet packets with any other VLAN IDs or non-VLAN packets will not be received. All VPN Sessions without this policy definition can send / receive any kinds of Ethernet packets regardless of VLAN tags, and VLAN tags are not inserted or removed automatically. Any tagged-VLAN packets via the Virtual Hub will be regarded as non-IP packets. Therefore, tagged-VLAN packets are not subjects for IPv4 / IPv6 security policies, access lists nor other IPv4 / IPv6 specific deep processing.
policy:Ver3_boolbooleanSecurity policy: Whether version 3.0 (must be true)
+
+

+

"SetGroup" RPC API - Set group settings

+

Description

+

Set group settings. Use this to set group settings that is registered on the security account database of the currently managed Virtual Hub. To get the list of currently registered groups, use the EnumGroup API. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a member server on a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetGroup",
+  "params": {
+    "HubName_str": "hubname",
+    "Name_str": "name",
+    "Realname_utf": "realname",
+    "Note_utf": "note",
+    "UsePolicy_bool": false,
+    "policy:Access_bool": false,
+    "policy:DHCPFilter_bool": false,
+    "policy:DHCPNoServer_bool": false,
+    "policy:DHCPForce_bool": false,
+    "policy:NoBridge_bool": false,
+    "policy:NoRouting_bool": false,
+    "policy:CheckMac_bool": false,
+    "policy:CheckIP_bool": false,
+    "policy:ArpDhcpOnly_bool": false,
+    "policy:PrivacyFilter_bool": false,
+    "policy:NoServer_bool": false,
+    "policy:NoBroadcastLimiter_bool": false,
+    "policy:MonitorPort_bool": false,
+    "policy:MaxConnection_u32": 0,
+    "policy:TimeOut_u32": 0,
+    "policy:MaxMac_u32": 0,
+    "policy:MaxIP_u32": 0,
+    "policy:MaxUpload_u32": 0,
+    "policy:MaxDownload_u32": 0,
+    "policy:FixPassword_bool": false,
+    "policy:MultiLogins_u32": 0,
+    "policy:NoQoS_bool": false,
+    "policy:RSandRAFilter_bool": false,
+    "policy:RAFilter_bool": false,
+    "policy:DHCPv6Filter_bool": false,
+    "policy:DHCPv6NoServer_bool": false,
+    "policy:NoRoutingV6_bool": false,
+    "policy:CheckIPv6_bool": false,
+    "policy:NoServerV6_bool": false,
+    "policy:MaxIPv6_u32": 0,
+    "policy:NoSavePassword_bool": false,
+    "policy:AutoDisconnect_u32": 0,
+    "policy:FilterIPv4_bool": false,
+    "policy:FilterIPv6_bool": false,
+    "policy:FilterNonIP_bool": false,
+    "policy:NoIPv6DefaultRouterInRA_bool": false,
+    "policy:NoIPv6DefaultRouterInRAWhenIPv6_bool": false,
+    "policy:VLanId_u32": 0,
+    "policy:Ver3_bool": false
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "Name_str": "name",
+    "Realname_utf": "realname",
+    "Note_utf": "note",
+    "Recv.BroadcastBytes_u64": 0,
+    "Recv.BroadcastCount_u64": 0,
+    "Recv.UnicastBytes_u64": 0,
+    "Recv.UnicastCount_u64": 0,
+    "Send.BroadcastBytes_u64": 0,
+    "Send.BroadcastCount_u64": 0,
+    "Send.UnicastBytes_u64": 0,
+    "Send.UnicastCount_u64": 0,
+    "UsePolicy_bool": false,
+    "policy:Access_bool": false,
+    "policy:DHCPFilter_bool": false,
+    "policy:DHCPNoServer_bool": false,
+    "policy:DHCPForce_bool": false,
+    "policy:NoBridge_bool": false,
+    "policy:NoRouting_bool": false,
+    "policy:CheckMac_bool": false,
+    "policy:CheckIP_bool": false,
+    "policy:ArpDhcpOnly_bool": false,
+    "policy:PrivacyFilter_bool": false,
+    "policy:NoServer_bool": false,
+    "policy:NoBroadcastLimiter_bool": false,
+    "policy:MonitorPort_bool": false,
+    "policy:MaxConnection_u32": 0,
+    "policy:TimeOut_u32": 0,
+    "policy:MaxMac_u32": 0,
+    "policy:MaxIP_u32": 0,
+    "policy:MaxUpload_u32": 0,
+    "policy:MaxDownload_u32": 0,
+    "policy:FixPassword_bool": false,
+    "policy:MultiLogins_u32": 0,
+    "policy:NoQoS_bool": false,
+    "policy:RSandRAFilter_bool": false,
+    "policy:RAFilter_bool": false,
+    "policy:DHCPv6Filter_bool": false,
+    "policy:DHCPv6NoServer_bool": false,
+    "policy:NoRoutingV6_bool": false,
+    "policy:CheckIPv6_bool": false,
+    "policy:NoServerV6_bool": false,
+    "policy:MaxIPv6_u32": 0,
+    "policy:NoSavePassword_bool": false,
+    "policy:AutoDisconnect_u32": 0,
+    "policy:FilterIPv4_bool": false,
+    "policy:FilterIPv6_bool": false,
+    "policy:FilterNonIP_bool": false,
+    "policy:NoIPv6DefaultRouterInRA_bool": false,
+    "policy:NoIPv6DefaultRouterInRAWhenIPv6_bool": false,
+    "policy:VLanId_u32": 0,
+    "policy:Ver3_bool": false
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
Name_strstring (ASCII)The group name
Realname_utfstring (UTF8)Optional real name (full name) of the group, allow using any Unicode characters
Note_utfstring (UTF8)Optional, specify a description of the group
Recv.BroadcastBytes_u64number (uint64)Number of broadcast packets (Recv)
Recv.BroadcastCount_u64number (uint64)Broadcast bytes (Recv)
Recv.UnicastBytes_u64number (uint64)Unicast count (Recv)
Recv.UnicastCount_u64number (uint64)Unicast bytes (Recv)
Send.BroadcastBytes_u64number (uint64)Number of broadcast packets (Send)
Send.BroadcastCount_u64number (uint64)Broadcast bytes (Send)
Send.UnicastBytes_u64number (uint64)Unicast bytes (Send)
Send.UnicastCount_u64number (uint64)Unicast bytes (Send)
UsePolicy_boolbooleanThe flag whether to use security policy
policy:Access_boolbooleanSecurity policy: Allow Access. The users, which this policy value is true, have permission to make VPN connection to VPN Server.
policy:DHCPFilter_boolbooleanSecurity policy: Filter DHCP Packets (IPv4). All IPv4 DHCP packets in sessions defined this policy will be filtered.
policy:DHCPNoServer_boolbooleanSecurity policy: Disallow DHCP Server Operation (IPv4). Computers connected to sessions that have this policy setting will not be allowed to become a DHCP server and distribute IPv4 addresses to DHCP clients.
policy:DHCPForce_boolbooleanSecurity policy: Enforce DHCP Allocated IP Addresses (IPv4). Computers in sessions that have this policy setting will only be able to use IPv4 addresses allocated by a DHCP server on the virtual network side.
policy:NoBridge_boolbooleanSecurity policy: Deny Bridge Operation. Bridge-mode connections are denied for user sessions that have this policy setting. Even in cases when the Ethernet Bridge is configured in the client side, communication will not be possible.
policy:NoRouting_boolbooleanSecurity policy: Deny Routing Operation (IPv4). IPv4 routing will be denied for sessions that have this policy setting. Even in the case where the IP router is operating on the user client side, communication will not be possible.
policy:CheckMac_boolbooleanSecurity policy: Deny MAC Addresses Duplication. The use of duplicating MAC addresses that are in use by computers of different sessions cannot be used by sessions with this policy setting.
policy:CheckIP_boolbooleanSecurity policy: Deny IP Address Duplication (IPv4). The use of duplicating IPv4 addresses that are in use by computers of different sessions cannot be used by sessions with this policy setting.
policy:ArpDhcpOnly_boolbooleanSecurity policy: Deny Non-ARP / Non-DHCP / Non-ICMPv6 broadcasts. The sending or receiving of broadcast packets that are not ARP protocol, DHCP protocol, nor ICMPv6 on the virtual network will not be allowed for sessions with this policy setting.
policy:PrivacyFilter_boolbooleanSecurity policy: Privacy Filter Mode. All direct communication between sessions with the privacy filter mode policy setting will be filtered.
policy:NoServer_boolbooleanSecurity policy: Deny Operation as TCP/IP Server (IPv4). Computers of sessions with this policy setting can't listen and accept TCP/IP connections in IPv4.
policy:NoBroadcastLimiter_boolbooleanSecurity policy: Unlimited Number of Broadcasts. If a computer of a session with this policy setting sends broadcast packets of a number unusually larger than what would be considered normal on the virtual network, there will be no automatic limiting.
policy:MonitorPort_boolbooleanSecurity policy: Allow Monitoring Mode. Users with this policy setting will be granted to connect to the Virtual Hub in Monitoring Mode. Sessions in Monitoring Mode are able to monitor (tap) all packets flowing through the Virtual Hub.
policy:MaxConnection_u32number (uint32)Security policy: Maximum Number of TCP Connections. For sessions with this policy setting, this sets the maximum number of physical TCP connections consists in a physical VPN session.
policy:TimeOut_u32number (uint32)Security policy: Time-out Period. For sessions with this policy setting, this sets, in seconds, the time-out period to wait before disconnecting a session when communication trouble occurs between the VPN Client / VPN Server.
policy:MaxMac_u32number (uint32)Security policy: Maximum Number of MAC Addresses. For sessions with this policy setting, this limits the number of MAC addresses per session.
policy:MaxIP_u32number (uint32)Security policy: Maximum Number of IP Addresses (IPv4). For sessions with this policy setting, this specifies the number of IPv4 addresses that can be registered for a single session.
policy:MaxUpload_u32number (uint32)Security policy: Upload Bandwidth. For sessions with this policy setting, this limits the traffic bandwidth that is in the inwards direction from outside to inside the Virtual Hub.
policy:MaxDownload_u32number (uint32)Security policy: Download Bandwidth. For sessions with this policy setting, this limits the traffic bandwidth that is in the outwards direction from inside the Virtual Hub to outside the Virtual Hub.
policy:FixPassword_boolbooleanSecurity policy: Deny Changing Password. The users which use password authentication with this policy setting are not allowed to change their own password from the VPN Client Manager or similar.
policy:MultiLogins_u32number (uint32)Security policy: Maximum Number of Multiple Logins. Users with this policy setting are unable to have more than this number of concurrent logins. Bridge Mode sessions are not subjects to this policy.
policy:NoQoS_boolbooleanSecurity policy: Deny VoIP / QoS Function. Users with this security policy are unable to use VoIP / QoS functions in VPN connection sessions.
policy:RSandRAFilter_boolbooleanSecurity policy: Filter RS / RA Packets (IPv6). All ICMPv6 packets which the message-type is 133 (Router Solicitation) or 134 (Router Advertisement) in sessions defined this policy will be filtered. As a result, an IPv6 client will be unable to use IPv6 address prefix auto detection and IPv6 default gateway auto detection.
policy:RAFilter_boolbooleanSecurity policy: Filter RA Packets (IPv6). All ICMPv6 packets which the message-type is 134 (Router Advertisement) in sessions defined this policy will be filtered. As a result, a malicious users will be unable to spread illegal IPv6 prefix or default gateway advertisements on the network.
policy:DHCPv6Filter_boolbooleanSecurity policy: Filter DHCP Packets (IPv6). All IPv6 DHCP packets in sessions defined this policy will be filtered.
policy:DHCPv6NoServer_boolbooleanSecurity policy: Disallow DHCP Server Operation (IPv6). Computers connected to sessions that have this policy setting will not be allowed to become a DHCP server and distribute IPv6 addresses to DHCP clients.
policy:NoRoutingV6_boolbooleanSecurity policy: Deny Routing Operation (IPv6). IPv6 routing will be denied for sessions that have this policy setting. Even in the case where the IP router is operating on the user client side, communication will not be possible.
policy:CheckIPv6_boolbooleanSecurity policy: Deny IP Address Duplication (IPv6). The use of duplicating IPv6 addresses that are in use by computers of different sessions cannot be used by sessions with this policy setting.
policy:NoServerV6_boolbooleanSecurity policy: Deny Operation as TCP/IP Server (IPv6). Computers of sessions with this policy setting can't listen and accept TCP/IP connections in IPv6.
policy:MaxIPv6_u32number (uint32)Security policy: Maximum Number of IP Addresses (IPv6). For sessions with this policy setting, this specifies the number of IPv6 addresses that can be registered for a single session.
policy:NoSavePassword_boolbooleanSecurity policy: Disallow Password Save in VPN Client. For users with this policy setting, when the user is using standard password authentication, the user will be unable to save the password in VPN Client. The user will be required to input passwords for every time to connect a VPN. This will improve the security. If this policy is enabled, VPN Client Version 2.0 will be denied to access.
policy:AutoDisconnect_u32number (uint32)Security policy: VPN Client Automatic Disconnect. For users with this policy setting, a user's VPN session will be disconnected automatically after the specific period will elapse. In this case no automatic re-connection will be performed. This can prevent a lot of inactive VPN Sessions. If this policy is enabled, VPN Client Version 2.0 will be denied to access.
policy:FilterIPv4_boolbooleanSecurity policy: Filter All IPv4 Packets. All IPv4 and ARP packets in sessions defined this policy will be filtered.
policy:FilterIPv6_boolbooleanSecurity policy: Filter All IPv6 Packets. All IPv6 packets in sessions defined this policy will be filtered.
policy:FilterNonIP_boolbooleanSecurity policy: Filter All Non-IP Packets. All non-IP packets in sessions defined this policy will be filtered. "Non-IP packet" mean a packet which is not IPv4, ARP nor IPv6. Any tagged-VLAN packets via the Virtual Hub will be regarded as non-IP packets.
policy:NoIPv6DefaultRouterInRA_boolbooleanSecurity policy: No Default-Router on IPv6 RA. In all VPN Sessions defines this policy, any IPv6 RA (Router Advertisement) packet with non-zero value in the router-lifetime will set to zero-value. This is effective to avoid the horrible behavior from the IPv6 routing confusion which is caused by the VPN client's attempts to use the remote-side IPv6 router as its local IPv6 router.
policy:NoIPv6DefaultRouterInRAWhenIPv6_boolbooleanSecurity policy: No Default-Router on IPv6 RA (physical IPv6). In all VPN Sessions defines this policy (only when the physical communication protocol between VPN Client / VPN Bridge and VPN Server is IPv6), any IPv6 RA (Router Advertisement) packet with non-zero value in the router-lifetime will set to zero-value. This is effective to avoid the horrible behavior from the IPv6 routing confusion which is caused by the VPN client's attempts to use the remote-side IPv6 router as its local IPv6 router.
policy:VLanId_u32number (uint32)Security policy: VLAN ID (IEEE802.1Q). You can specify the VLAN ID on the security policy. All VPN Sessions defines this policy, all Ethernet packets toward the Virtual Hub from the user will be inserted a VLAN tag (IEEE 802.1Q) with the VLAN ID. The user can also receive only packets with a VLAN tag which has the same VLAN ID. (Receiving process removes the VLAN tag automatically.) Any Ethernet packets with any other VLAN IDs or non-VLAN packets will not be received. All VPN Sessions without this policy definition can send / receive any kinds of Ethernet packets regardless of VLAN tags, and VLAN tags are not inserted or removed automatically. Any tagged-VLAN packets via the Virtual Hub will be regarded as non-IP packets. Therefore, tagged-VLAN packets are not subjects for IPv4 / IPv6 security policies, access lists nor other IPv4 / IPv6 specific deep processing.
policy:Ver3_boolbooleanSecurity policy: Whether version 3.0 (must be true)
+
+

+

"GetGroup" RPC API - Get Group Setting (Sync mode)

+

Description

+

Get Group Setting (Sync mode). Use this to get the setting of a group that is registered on the security account database of the currently managed Virtual Hub. To get the list of currently registered groups, use the EnumGroup API. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a member server on a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetGroup",
+  "params": {
+    "HubName_str": "hubname",
+    "Name_str": "name"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "Name_str": "name",
+    "Realname_utf": "realname",
+    "Note_utf": "note",
+    "Recv.BroadcastBytes_u64": 0,
+    "Recv.BroadcastCount_u64": 0,
+    "Recv.UnicastBytes_u64": 0,
+    "Recv.UnicastCount_u64": 0,
+    "Send.BroadcastBytes_u64": 0,
+    "Send.BroadcastCount_u64": 0,
+    "Send.UnicastBytes_u64": 0,
+    "Send.UnicastCount_u64": 0,
+    "UsePolicy_bool": false,
+    "policy:Access_bool": false,
+    "policy:DHCPFilter_bool": false,
+    "policy:DHCPNoServer_bool": false,
+    "policy:DHCPForce_bool": false,
+    "policy:NoBridge_bool": false,
+    "policy:NoRouting_bool": false,
+    "policy:CheckMac_bool": false,
+    "policy:CheckIP_bool": false,
+    "policy:ArpDhcpOnly_bool": false,
+    "policy:PrivacyFilter_bool": false,
+    "policy:NoServer_bool": false,
+    "policy:NoBroadcastLimiter_bool": false,
+    "policy:MonitorPort_bool": false,
+    "policy:MaxConnection_u32": 0,
+    "policy:TimeOut_u32": 0,
+    "policy:MaxMac_u32": 0,
+    "policy:MaxIP_u32": 0,
+    "policy:MaxUpload_u32": 0,
+    "policy:MaxDownload_u32": 0,
+    "policy:FixPassword_bool": false,
+    "policy:MultiLogins_u32": 0,
+    "policy:NoQoS_bool": false,
+    "policy:RSandRAFilter_bool": false,
+    "policy:RAFilter_bool": false,
+    "policy:DHCPv6Filter_bool": false,
+    "policy:DHCPv6NoServer_bool": false,
+    "policy:NoRoutingV6_bool": false,
+    "policy:CheckIPv6_bool": false,
+    "policy:NoServerV6_bool": false,
+    "policy:MaxIPv6_u32": 0,
+    "policy:NoSavePassword_bool": false,
+    "policy:AutoDisconnect_u32": 0,
+    "policy:FilterIPv4_bool": false,
+    "policy:FilterIPv6_bool": false,
+    "policy:FilterNonIP_bool": false,
+    "policy:NoIPv6DefaultRouterInRA_bool": false,
+    "policy:NoIPv6DefaultRouterInRAWhenIPv6_bool": false,
+    "policy:VLanId_u32": 0,
+    "policy:Ver3_bool": false
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
Name_strstring (ASCII)The group name
Realname_utfstring (UTF8)Optional real name (full name) of the group, allow using any Unicode characters
Note_utfstring (UTF8)Optional, specify a description of the group
Recv.BroadcastBytes_u64number (uint64)Number of broadcast packets (Recv)
Recv.BroadcastCount_u64number (uint64)Broadcast bytes (Recv)
Recv.UnicastBytes_u64number (uint64)Unicast count (Recv)
Recv.UnicastCount_u64number (uint64)Unicast bytes (Recv)
Send.BroadcastBytes_u64number (uint64)Number of broadcast packets (Send)
Send.BroadcastCount_u64number (uint64)Broadcast bytes (Send)
Send.UnicastBytes_u64number (uint64)Unicast bytes (Send)
Send.UnicastCount_u64number (uint64)Unicast bytes (Send)
UsePolicy_boolbooleanThe flag whether to use security policy
policy:Access_boolbooleanSecurity policy: Allow Access. The users, which this policy value is true, have permission to make VPN connection to VPN Server.
policy:DHCPFilter_boolbooleanSecurity policy: Filter DHCP Packets (IPv4). All IPv4 DHCP packets in sessions defined this policy will be filtered.
policy:DHCPNoServer_boolbooleanSecurity policy: Disallow DHCP Server Operation (IPv4). Computers connected to sessions that have this policy setting will not be allowed to become a DHCP server and distribute IPv4 addresses to DHCP clients.
policy:DHCPForce_boolbooleanSecurity policy: Enforce DHCP Allocated IP Addresses (IPv4). Computers in sessions that have this policy setting will only be able to use IPv4 addresses allocated by a DHCP server on the virtual network side.
policy:NoBridge_boolbooleanSecurity policy: Deny Bridge Operation. Bridge-mode connections are denied for user sessions that have this policy setting. Even in cases when the Ethernet Bridge is configured in the client side, communication will not be possible.
policy:NoRouting_boolbooleanSecurity policy: Deny Routing Operation (IPv4). IPv4 routing will be denied for sessions that have this policy setting. Even in the case where the IP router is operating on the user client side, communication will not be possible.
policy:CheckMac_boolbooleanSecurity policy: Deny MAC Addresses Duplication. The use of duplicating MAC addresses that are in use by computers of different sessions cannot be used by sessions with this policy setting.
policy:CheckIP_boolbooleanSecurity policy: Deny IP Address Duplication (IPv4). The use of duplicating IPv4 addresses that are in use by computers of different sessions cannot be used by sessions with this policy setting.
policy:ArpDhcpOnly_boolbooleanSecurity policy: Deny Non-ARP / Non-DHCP / Non-ICMPv6 broadcasts. The sending or receiving of broadcast packets that are not ARP protocol, DHCP protocol, nor ICMPv6 on the virtual network will not be allowed for sessions with this policy setting.
policy:PrivacyFilter_boolbooleanSecurity policy: Privacy Filter Mode. All direct communication between sessions with the privacy filter mode policy setting will be filtered.
policy:NoServer_boolbooleanSecurity policy: Deny Operation as TCP/IP Server (IPv4). Computers of sessions with this policy setting can't listen and accept TCP/IP connections in IPv4.
policy:NoBroadcastLimiter_boolbooleanSecurity policy: Unlimited Number of Broadcasts. If a computer of a session with this policy setting sends broadcast packets of a number unusually larger than what would be considered normal on the virtual network, there will be no automatic limiting.
policy:MonitorPort_boolbooleanSecurity policy: Allow Monitoring Mode. Users with this policy setting will be granted to connect to the Virtual Hub in Monitoring Mode. Sessions in Monitoring Mode are able to monitor (tap) all packets flowing through the Virtual Hub.
policy:MaxConnection_u32number (uint32)Security policy: Maximum Number of TCP Connections. For sessions with this policy setting, this sets the maximum number of physical TCP connections consists in a physical VPN session.
policy:TimeOut_u32number (uint32)Security policy: Time-out Period. For sessions with this policy setting, this sets, in seconds, the time-out period to wait before disconnecting a session when communication trouble occurs between the VPN Client / VPN Server.
policy:MaxMac_u32number (uint32)Security policy: Maximum Number of MAC Addresses. For sessions with this policy setting, this limits the number of MAC addresses per session.
policy:MaxIP_u32number (uint32)Security policy: Maximum Number of IP Addresses (IPv4). For sessions with this policy setting, this specifies the number of IPv4 addresses that can be registered for a single session.
policy:MaxUpload_u32number (uint32)Security policy: Upload Bandwidth. For sessions with this policy setting, this limits the traffic bandwidth that is in the inwards direction from outside to inside the Virtual Hub.
policy:MaxDownload_u32number (uint32)Security policy: Download Bandwidth. For sessions with this policy setting, this limits the traffic bandwidth that is in the outwards direction from inside the Virtual Hub to outside the Virtual Hub.
policy:FixPassword_boolbooleanSecurity policy: Deny Changing Password. The users which use password authentication with this policy setting are not allowed to change their own password from the VPN Client Manager or similar.
policy:MultiLogins_u32number (uint32)Security policy: Maximum Number of Multiple Logins. Users with this policy setting are unable to have more than this number of concurrent logins. Bridge Mode sessions are not subjects to this policy.
policy:NoQoS_boolbooleanSecurity policy: Deny VoIP / QoS Function. Users with this security policy are unable to use VoIP / QoS functions in VPN connection sessions.
policy:RSandRAFilter_boolbooleanSecurity policy: Filter RS / RA Packets (IPv6). All ICMPv6 packets which the message-type is 133 (Router Solicitation) or 134 (Router Advertisement) in sessions defined this policy will be filtered. As a result, an IPv6 client will be unable to use IPv6 address prefix auto detection and IPv6 default gateway auto detection.
policy:RAFilter_boolbooleanSecurity policy: Filter RA Packets (IPv6). All ICMPv6 packets which the message-type is 134 (Router Advertisement) in sessions defined this policy will be filtered. As a result, a malicious users will be unable to spread illegal IPv6 prefix or default gateway advertisements on the network.
policy:DHCPv6Filter_boolbooleanSecurity policy: Filter DHCP Packets (IPv6). All IPv6 DHCP packets in sessions defined this policy will be filtered.
policy:DHCPv6NoServer_boolbooleanSecurity policy: Disallow DHCP Server Operation (IPv6). Computers connected to sessions that have this policy setting will not be allowed to become a DHCP server and distribute IPv6 addresses to DHCP clients.
policy:NoRoutingV6_boolbooleanSecurity policy: Deny Routing Operation (IPv6). IPv6 routing will be denied for sessions that have this policy setting. Even in the case where the IP router is operating on the user client side, communication will not be possible.
policy:CheckIPv6_boolbooleanSecurity policy: Deny IP Address Duplication (IPv6). The use of duplicating IPv6 addresses that are in use by computers of different sessions cannot be used by sessions with this policy setting.
policy:NoServerV6_boolbooleanSecurity policy: Deny Operation as TCP/IP Server (IPv6). Computers of sessions with this policy setting can't listen and accept TCP/IP connections in IPv6.
policy:MaxIPv6_u32number (uint32)Security policy: Maximum Number of IP Addresses (IPv6). For sessions with this policy setting, this specifies the number of IPv6 addresses that can be registered for a single session.
policy:NoSavePassword_boolbooleanSecurity policy: Disallow Password Save in VPN Client. For users with this policy setting, when the user is using standard password authentication, the user will be unable to save the password in VPN Client. The user will be required to input passwords for every time to connect a VPN. This will improve the security. If this policy is enabled, VPN Client Version 2.0 will be denied to access.
policy:AutoDisconnect_u32number (uint32)Security policy: VPN Client Automatic Disconnect. For users with this policy setting, a user's VPN session will be disconnected automatically after the specific period will elapse. In this case no automatic re-connection will be performed. This can prevent a lot of inactive VPN Sessions. If this policy is enabled, VPN Client Version 2.0 will be denied to access.
policy:FilterIPv4_boolbooleanSecurity policy: Filter All IPv4 Packets. All IPv4 and ARP packets in sessions defined this policy will be filtered.
policy:FilterIPv6_boolbooleanSecurity policy: Filter All IPv6 Packets. All IPv6 packets in sessions defined this policy will be filtered.
policy:FilterNonIP_boolbooleanSecurity policy: Filter All Non-IP Packets. All non-IP packets in sessions defined this policy will be filtered. "Non-IP packet" mean a packet which is not IPv4, ARP nor IPv6. Any tagged-VLAN packets via the Virtual Hub will be regarded as non-IP packets.
policy:NoIPv6DefaultRouterInRA_boolbooleanSecurity policy: No Default-Router on IPv6 RA. In all VPN Sessions defines this policy, any IPv6 RA (Router Advertisement) packet with non-zero value in the router-lifetime will set to zero-value. This is effective to avoid the horrible behavior from the IPv6 routing confusion which is caused by the VPN client's attempts to use the remote-side IPv6 router as its local IPv6 router.
policy:NoIPv6DefaultRouterInRAWhenIPv6_boolbooleanSecurity policy: No Default-Router on IPv6 RA (physical IPv6). In all VPN Sessions defines this policy (only when the physical communication protocol between VPN Client / VPN Bridge and VPN Server is IPv6), any IPv6 RA (Router Advertisement) packet with non-zero value in the router-lifetime will set to zero-value. This is effective to avoid the horrible behavior from the IPv6 routing confusion which is caused by the VPN client's attempts to use the remote-side IPv6 router as its local IPv6 router.
policy:VLanId_u32number (uint32)Security policy: VLAN ID (IEEE802.1Q). You can specify the VLAN ID on the security policy. All VPN Sessions defines this policy, all Ethernet packets toward the Virtual Hub from the user will be inserted a VLAN tag (IEEE 802.1Q) with the VLAN ID. The user can also receive only packets with a VLAN tag which has the same VLAN ID. (Receiving process removes the VLAN tag automatically.) Any Ethernet packets with any other VLAN IDs or non-VLAN packets will not be received. All VPN Sessions without this policy definition can send / receive any kinds of Ethernet packets regardless of VLAN tags, and VLAN tags are not inserted or removed automatically. Any tagged-VLAN packets via the Virtual Hub will be regarded as non-IP packets. Therefore, tagged-VLAN packets are not subjects for IPv4 / IPv6 security policies, access lists nor other IPv4 / IPv6 specific deep processing.
policy:Ver3_boolbooleanSecurity policy: Whether version 3.0 (must be true)
+
+

+

"DeleteGroup" RPC API - Delete User from Group

+

Description

+

Delete User from Group. Use this to delete a specified user from the group that is registered on the security account database of the currently managed Virtual Hub. By deleting a user from the group, that user becomes unassigned. To get the list of currently registered groups, use the EnumGroup API. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a member server on a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "DeleteGroup",
+  "params": {
+    "HubName_str": "hubname",
+    "Name_str": "name"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "Name_str": "name"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
Name_strstring (ASCII)User or group name
+
+

+

"EnumGroup" RPC API - Get List of Groups

+

Description

+

Get List of Groups. Use this to get a list of groups that are registered on the security account database of the currently managed Virtual Hub. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a member server on a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "EnumGroup",
+  "params": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "GroupList": [
+      {
+        "Name_str": "name",
+        "Realname_utf": "realname",
+        "Note_utf": "note",
+        "NumUsers_u32": 0,
+        "DenyAccess_bool": false
+      },
+      {
+        "Name_str": "name",
+        "Realname_utf": "realname",
+        "Note_utf": "note",
+        "NumUsers_u32": 0,
+        "DenyAccess_bool": false
+      },
+      {
+        "Name_str": "name",
+        "Realname_utf": "realname",
+        "Note_utf": "note",
+        "NumUsers_u32": 0,
+        "DenyAccess_bool": false
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
GroupListArray objectGroup list
Name_strstring (ASCII)User name
Realname_utfstring (UTF8)Real name
Note_utfstring (UTF8)Note
NumUsers_u32number (uint32)Number of users
DenyAccess_boolbooleanAccess denied
+
+

+

"EnumSession" RPC API - Get List of Connected VPN Sessions

+

Description

+

Get List of Connected VPN Sessions. Use this to get a list of the sessions connected to the Virtual Hub currently being managed. In the list of sessions, the following information will be obtained for each connection: Session Name, Session Site, User Name, Source Host Name, TCP Connection, Transfer Bytes and Transfer Packets. If the currently connected VPN Server is a cluster controller and the currently managed Virtual Hub is a static Virtual Hub, you can get an all-linked-together list of all sessions connected to that Virtual Hub on all cluster members. In all other cases, only the list of sessions that are actually connected to the currently managed VPN Server will be obtained.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "EnumSession",
+  "params": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "SessionList": [
+      {
+        "Name_str": "name",
+        "RemoteSession_bool": false,
+        "RemoteHostname_str": "remotehostname",
+        "Username_str": "username",
+        "ClientIP_ip": "192.168.0.1",
+        "Hostname_str": "hostname",
+        "MaxNumTcp_u32": 0,
+        "CurrentNumTcp_u32": 0,
+        "PacketSize_u64": 0,
+        "PacketNum_u64": 0,
+        "LinkMode_bool": false,
+        "SecureNATMode_bool": false,
+        "BridgeMode_bool": false,
+        "Layer3Mode_bool": false,
+        "Client_BridgeMode_bool": false,
+        "Client_MonitorMode_bool": false,
+        "VLanId_u32": 0,
+        "UniqueId_bin": "SGVsbG8gV29ybGQ=",
+        "CreatedTime_dt": "2020-08-01T12:24:36.123",
+        "LastCommTime_dt": "2020-08-01T12:24:36.123"
+      },
+      {
+        "Name_str": "name",
+        "RemoteSession_bool": false,
+        "RemoteHostname_str": "remotehostname",
+        "Username_str": "username",
+        "ClientIP_ip": "192.168.0.1",
+        "Hostname_str": "hostname",
+        "MaxNumTcp_u32": 0,
+        "CurrentNumTcp_u32": 0,
+        "PacketSize_u64": 0,
+        "PacketNum_u64": 0,
+        "LinkMode_bool": false,
+        "SecureNATMode_bool": false,
+        "BridgeMode_bool": false,
+        "Layer3Mode_bool": false,
+        "Client_BridgeMode_bool": false,
+        "Client_MonitorMode_bool": false,
+        "VLanId_u32": 0,
+        "UniqueId_bin": "SGVsbG8gV29ybGQ=",
+        "CreatedTime_dt": "2020-08-01T12:24:36.123",
+        "LastCommTime_dt": "2020-08-01T12:24:36.123"
+      },
+      {
+        "Name_str": "name",
+        "RemoteSession_bool": false,
+        "RemoteHostname_str": "remotehostname",
+        "Username_str": "username",
+        "ClientIP_ip": "192.168.0.1",
+        "Hostname_str": "hostname",
+        "MaxNumTcp_u32": 0,
+        "CurrentNumTcp_u32": 0,
+        "PacketSize_u64": 0,
+        "PacketNum_u64": 0,
+        "LinkMode_bool": false,
+        "SecureNATMode_bool": false,
+        "BridgeMode_bool": false,
+        "Layer3Mode_bool": false,
+        "Client_BridgeMode_bool": false,
+        "Client_MonitorMode_bool": false,
+        "VLanId_u32": 0,
+        "UniqueId_bin": "SGVsbG8gV29ybGQ=",
+        "CreatedTime_dt": "2020-08-01T12:24:36.123",
+        "LastCommTime_dt": "2020-08-01T12:24:36.123"
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
SessionListArray objectVPN sessions list
Name_strstring (ASCII)Session name
RemoteSession_boolbooleanRemote session
RemoteHostname_strstring (ASCII)Remote server name
Username_strstring (ASCII)User name
ClientIP_ipstring (IP address)IP address
Hostname_strstring (ASCII)Host name
MaxNumTcp_u32number (uint32)Maximum number of underlying TCP connections
CurrentNumTcp_u32number (uint32)Number of current underlying TCP connections
PacketSize_u64number (uint64)Packet size transmitted
PacketNum_u64number (uint64)Number of packets transmitted
LinkMode_boolbooleanIs a Cascade VPN session
SecureNATMode_boolbooleanIs a SecureNAT VPN session
BridgeMode_boolbooleanIs the VPN session for Local Bridge
Layer3Mode_boolbooleanIs a Layer-3 Switch VPN session
Client_BridgeMode_boolbooleanIs in Bridge Mode
Client_MonitorMode_boolbooleanIs in Monitor Mode
VLanId_u32number (uint32)VLAN ID
UniqueId_binstring (Base64 binary)Unique ID of the VPN Session
CreatedTime_dtDateCreation date and time
LastCommTime_dtDateLast communication date and time
+
+

+

"GetSessionStatus" RPC API - Get Session Status

+

Description

+

Get Session Status. Use this to specify a session currently connected to the currently managed Virtual Hub and get the session information. The session status includes the following: source host name and user name, version information, time information, number of TCP connections, communication parameters, session key, statistical information on data transferred, and other client and server information. To get the list of currently connected sessions, use the EnumSession API.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetSessionStatus",
+  "params": {
+    "HubName_str": "hubname",
+    "Name_str": "name"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "Name_str": "name",
+    "Username_str": "username",
+    "RealUsername_str": "realusername",
+    "GroupName_str": "groupname",
+    "LinkMode_bool": false,
+    "Client_Ip_Address_ip": "192.168.0.1",
+    "SessionStatus_ClientHostName_str": "clienthostname",
+    "Active_bool": false,
+    "Connected_bool": false,
+    "SessionStatus_u32": 0,
+    "ServerName_str": "servername",
+    "ServerPort_u32": 0,
+    "ServerProductName_str": "serverproductname",
+    "ServerProductVer_u32": 0,
+    "ServerProductBuild_u32": 0,
+    "StartTime_dt": "2020-08-01T12:24:36.123",
+    "FirstConnectionEstablisiedTime_dt": "2020-08-01T12:24:36.123",
+    "CurrentConnectionEstablishTime_dt": "2020-08-01T12:24:36.123",
+    "NumConnectionsEatablished_u32": 0,
+    "HalfConnection_bool": false,
+    "QoS_bool": false,
+    "MaxTcpConnections_u32": 0,
+    "NumTcpConnections_u32": 0,
+    "NumTcpConnectionsUpload_u32": 0,
+    "NumTcpConnectionsDownload_u32": 0,
+    "UseEncrypt_bool": false,
+    "CipherName_str": "ciphername",
+    "UseCompress_bool": false,
+    "IsRUDPSession_bool": false,
+    "UnderlayProtocol_str": "underlayprotocol",
+    "IsUdpAccelerationEnabled_bool": false,
+    "IsUsingUdpAcceleration_bool": false,
+    "SessionName_str": "sessionname",
+    "ConnectionName_str": "connectionname",
+    "SessionKey_bin": "SGVsbG8gV29ybGQ=",
+    "TotalSendSize_u64": 0,
+    "TotalRecvSize_u64": 0,
+    "TotalSendSizeReal_u64": 0,
+    "TotalRecvSizeReal_u64": 0,
+    "IsBridgeMode_bool": false,
+    "IsMonitorMode_bool": false,
+    "VLanId_u32": 0,
+    "ClientProductName_str": "clientproductname",
+    "ClientProductVer_u32": 0,
+    "ClientProductBuild_u32": 0,
+    "ClientOsName_str": "clientosname",
+    "ClientOsVer_str": "clientosver",
+    "ClientOsProductId_str": "clientosproductid",
+    "ClientHostname_str": "clienthostname",
+    "UniqueId_bin": "SGVsbG8gV29ybGQ="
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
Name_strstring (ASCII)VPN session name
Username_strstring (ASCII)User name
RealUsername_strstring (ASCII)Real user name which was used for the authentication
GroupName_strstring (ASCII)Group name
LinkMode_boolbooleanIs Cascade Session
Client_Ip_Address_ipstring (IP address)Client IP address
SessionStatus_ClientHostName_strstring (ASCII)Client host name
Active_boolbooleanOperation flag
Connected_boolbooleanConnected flag
SessionStatus_u32number (enum)State of the client session
Values:
0: Connecting
1: Negotiating
2: During user authentication
3: Connection complete
4: Wait to retry
5: Idle state
ServerName_strstring (ASCII)Server name
ServerPort_u32number (uint32)Port number of the server
ServerProductName_strstring (ASCII)Server product name
ServerProductVer_u32number (uint32)Server product version
ServerProductBuild_u32number (uint32)Server product build number
StartTime_dtDateConnection start time
FirstConnectionEstablisiedTime_dtDateConnection completion time of the first connection
CurrentConnectionEstablishTime_dtDateConnection completion time of this connection
NumConnectionsEatablished_u32number (uint32)Number of connections have been established so far
HalfConnection_boolbooleanHalf-connection
QoS_boolbooleanVoIP / QoS
MaxTcpConnections_u32number (uint32)Maximum number of the underlying TCP connections
NumTcpConnections_u32number (uint32)Number of current underlying TCP connections
NumTcpConnectionsUpload_u32number (uint32)Number of inbound underlying connections
NumTcpConnectionsDownload_u32number (uint32)Number of outbound underlying connections
UseEncrypt_boolbooleanUse of encryption
CipherName_strstring (ASCII)Cipher algorithm name
UseCompress_boolbooleanUse of compression
IsRUDPSession_boolbooleanIs R-UDP session
UnderlayProtocol_strstring (ASCII)Physical underlying communication protocol
IsUdpAccelerationEnabled_boolbooleanThe UDP acceleration is enabled
IsUsingUdpAcceleration_boolbooleanUsing the UDP acceleration function
SessionName_strstring (ASCII)VPN session name
ConnectionName_strstring (ASCII)Connection name
SessionKey_binstring (Base64 binary)Session key
TotalSendSize_u64number (uint64)Total transmitted data size
TotalRecvSize_u64number (uint64)Total received data size
TotalSendSizeReal_u64number (uint64)Total transmitted data size (no compression)
TotalRecvSizeReal_u64number (uint64)Total received data size (no compression)
IsBridgeMode_boolbooleanIs Bridge Mode
IsMonitorMode_boolbooleanIs Monitor mode
VLanId_u32number (uint32)VLAN ID
ClientProductName_strstring (ASCII)Client product name
ClientProductVer_u32number (uint32)Client version
ClientProductBuild_u32number (uint32)Client build number
ClientOsName_strstring (ASCII)Client OS name
ClientOsVer_strstring (ASCII)Client OS version
ClientOsProductId_strstring (ASCII)Client OS Product ID
ClientHostname_strstring (ASCII)Client host name
UniqueId_binstring (Base64 binary)Unique ID
+
+

+

"DeleteSession" RPC API - Disconnect Session

+

Description

+

Disconnect Session. Use this to specify a session currently connected to the currently managed Virtual Hub and forcefully disconnect that session using manager privileges. Note that when communication is disconnected by settings on the source client side and the automatically reconnect option is enabled, it is possible that the client will reconnect. To get the list of currently connected sessions, use the EnumSession API.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "DeleteSession",
+  "params": {
+    "HubName_str": "hubname",
+    "Name_str": "name"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "Name_str": "name"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
Name_strstring (ASCII)Session name
+
+

+

"EnumMacTable" RPC API - Get the MAC Address Table Database

+

Description

+

Get the MAC Address Table Database. Use this to get the MAC address table database that is held by the currently managed Virtual Hub. The MAC address table database is a table that the Virtual Hub requires to perform the action of switching Ethernet frames and the Virtual Hub decides the sorting destination session of each Ethernet frame based on the MAC address table database. The MAC address database is built by the Virtual Hub automatically analyzing the contents of the communication.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "EnumMacTable",
+  "params": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "MacTable": [
+      {
+        "Key_u32": 0,
+        "SessionName_str": "sessionname",
+        "MacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "CreatedTime_dt": "2020-08-01T12:24:36.123",
+        "UpdatedTime_dt": "2020-08-01T12:24:36.123",
+        "RemoteItem_bool": false,
+        "RemoteHostname_str": "remotehostname",
+        "VlanId_u32": 0
+      },
+      {
+        "Key_u32": 0,
+        "SessionName_str": "sessionname",
+        "MacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "CreatedTime_dt": "2020-08-01T12:24:36.123",
+        "UpdatedTime_dt": "2020-08-01T12:24:36.123",
+        "RemoteItem_bool": false,
+        "RemoteHostname_str": "remotehostname",
+        "VlanId_u32": 0
+      },
+      {
+        "Key_u32": 0,
+        "SessionName_str": "sessionname",
+        "MacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "CreatedTime_dt": "2020-08-01T12:24:36.123",
+        "UpdatedTime_dt": "2020-08-01T12:24:36.123",
+        "RemoteItem_bool": false,
+        "RemoteHostname_str": "remotehostname",
+        "VlanId_u32": 0
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
MacTableArray objectMAC table
Key_u32number (uint32)Key ID
SessionName_strstring (ASCII)Session name
MacAddress_binstring (Base64 binary)MAC address
CreatedTime_dtDateCreation date and time
UpdatedTime_dtDateUpdating date
RemoteItem_boolbooleanRemote items
RemoteHostname_strstring (ASCII)Remote host name
VlanId_u32number (uint32)VLAN ID
+
+

+

"DeleteMacTable" RPC API - Delete MAC Address Table Entry

+

Description

+

Delete MAC Address Table Entry. Use this API to operate the MAC address table database held by the currently managed Virtual Hub and delete a specified MAC address table entry from the database. To get the contents of the current MAC address table database use the EnumMacTable API.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "DeleteMacTable",
+  "params": {
+    "HubName_str": "hubname",
+    "Key_u32": 0
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "Key_u32": 0
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
Key_u32number (uint32)Key ID
+
+

+

"EnumIpTable" RPC API - Get the IP Address Table Database

+

Description

+

Get the IP Address Table Database. Use this to get the IP address table database that is held by the currently managed Virtual Hub. The IP address table database is a table that is automatically generated by analyzing the contents of communication so that the Virtual Hub can always know which session is using which IP address and it is frequently used by the engine that applies the Virtual Hub security policy. By specifying the session name you can get the IP address table entry that has been associated with that session.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "EnumIpTable",
+  "params": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "IpTable": [
+      {
+        "Key_u32": 0,
+        "SessionName_str": "sessionname",
+        "IpAddress_ip": "192.168.0.1",
+        "DhcpAllocated_bool": false,
+        "CreatedTime_dt": "2020-08-01T12:24:36.123",
+        "UpdatedTime_dt": "2020-08-01T12:24:36.123",
+        "RemoteItem_bool": false,
+        "RemoteHostname_str": "remotehostname"
+      },
+      {
+        "Key_u32": 0,
+        "SessionName_str": "sessionname",
+        "IpAddress_ip": "192.168.0.1",
+        "DhcpAllocated_bool": false,
+        "CreatedTime_dt": "2020-08-01T12:24:36.123",
+        "UpdatedTime_dt": "2020-08-01T12:24:36.123",
+        "RemoteItem_bool": false,
+        "RemoteHostname_str": "remotehostname"
+      },
+      {
+        "Key_u32": 0,
+        "SessionName_str": "sessionname",
+        "IpAddress_ip": "192.168.0.1",
+        "DhcpAllocated_bool": false,
+        "CreatedTime_dt": "2020-08-01T12:24:36.123",
+        "UpdatedTime_dt": "2020-08-01T12:24:36.123",
+        "RemoteItem_bool": false,
+        "RemoteHostname_str": "remotehostname"
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
IpTableArray objectMAC table
Key_u32number (uint32)Key ID
SessionName_strstring (ASCII)Session name
IpAddress_ipstring (IP address)IP address
DhcpAllocated_boolbooleanAssigned by the DHCP
CreatedTime_dtDateCreation date and time
UpdatedTime_dtDateUpdating date
RemoteItem_boolbooleanRemote items
RemoteHostname_strstring (ASCII)Remote host name
+
+

+

"DeleteIpTable" RPC API - Delete IP Address Table Entry

+

Description

+

Delete IP Address Table Entry. Use this API to operate the IP address table database held by the currently managed Virtual Hub and delete a specified IP address table entry from the database. To get the contents of the current IP address table database use the EnumIpTable API.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "DeleteIpTable",
+  "params": {
+    "HubName_str": "hubname",
+    "Key_u32": 0
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "Key_u32": 0
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
Key_u32number (uint32)Key ID
+
+

+

"SetKeep" RPC API - Set the Keep Alive Internet Connection Function

+

Description

+

Set the Keep Alive Internet Connection Function. Use this to set the destination host name etc. of the Keep Alive Internet Connection Function. For network connection environments where connections will automatically be disconnected where there are periods of no communication that are longer than a set period, by using the Keep Alive Internet Connection Function, it is possible to keep alive the Internet connection by sending packets to a nominated server on the Internet at set intervals. When using this API, you can specify the following: Host Name, Port Number, Packet Send Interval, and Protocol. Packets sent to keep alive the Internet connection will have random content and personal information that could identify a computer or user is not sent. You can use the SetKeep API to enable/disable the Keep Alive Internet Connection Function. To execute this API on a VPN Server or VPN Bridge, you must have administrator privileges.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetKeep",
+  "params": {
+    "UseKeepConnect_bool": false,
+    "KeepConnectHost_str": "keepconnecthost",
+    "KeepConnectPort_u32": 0,
+    "KeepConnectProtocol_u32": 0,
+    "KeepConnectInterval_u32": 0
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "UseKeepConnect_bool": false,
+    "KeepConnectHost_str": "keepconnecthost",
+    "KeepConnectPort_u32": 0,
+    "KeepConnectProtocol_u32": 0,
+    "KeepConnectInterval_u32": 0
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
UseKeepConnect_boolbooleanThe flag to enable keep-alive to the Internet
KeepConnectHost_strstring (ASCII)Specify the host name or IP address of the destination
KeepConnectPort_u32number (uint32)Specify the port number of the destination
KeepConnectProtocol_u32number (enum)Protocol type
Values:
0: TCP
1: UDP
KeepConnectInterval_u32number (uint32)Interval Between Packets Sends (Seconds)
+
+

+

"GetKeep" RPC API - Get the Keep Alive Internet Connection Function

+

Description

+

Get the Keep Alive Internet Connection Function. Use this to get the current setting contents of the Keep Alive Internet Connection Function. In addition to the destination's Host Name, Port Number, Packet Send Interval and Protocol, you can obtain the current enabled/disabled status of the Keep Alive Internet Connection Function.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetKeep",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "UseKeepConnect_bool": false,
+    "KeepConnectHost_str": "keepconnecthost",
+    "KeepConnectPort_u32": 0,
+    "KeepConnectProtocol_u32": 0,
+    "KeepConnectInterval_u32": 0
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
UseKeepConnect_boolbooleanThe flag to enable keep-alive to the Internet
KeepConnectHost_strstring (ASCII)Specify the host name or IP address of the destination
KeepConnectPort_u32number (uint32)Specify the port number of the destination
KeepConnectProtocol_u32number (enum)Protocol type
Values:
0: TCP
1: UDP
KeepConnectInterval_u32number (uint32)Interval Between Packets Sends (Seconds)
+
+

+

"EnableSecureNAT" RPC API - Enable the Virtual NAT and DHCP Server Function (SecureNAT Function)

+

Description

+

Enable the Virtual NAT and DHCP Server Function (SecureNAT Function). Use this to enable the Virtual NAT and DHCP Server function (SecureNAT Function) on the currently managed Virtual Hub and begin its operation. Before executing this API, you must first check the setting contents of the current Virtual NAT function and DHCP Server function using the SetSecureNATOption API and GetSecureNATOption API. By enabling the SecureNAT function, you can virtually operate a NAT router (IP masquerade) and the DHCP Server function on a virtual network on the Virtual Hub. [Warning about SecureNAT Function] The SecureNAT function is recommended only for system administrators and people with a detailed knowledge of networks. If you use the SecureNAT function correctly, it is possible to achieve a safe form of remote access via a VPN. However when used in the wrong way, it can put the entire network in danger. Anyone who does not have a thorough knowledge of networks and anyone who does not have the network administrator's permission must not enable the SecureNAT function. For a detailed explanation of the SecureNAT function, please refer to the VPN Server's manual and online documentation. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "EnableSecureNAT",
+  "params": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
+
+

+

"DisableSecureNAT" RPC API - Disable the Virtual NAT and DHCP Server Function (SecureNAT Function)

+

Description

+

Disable the Virtual NAT and DHCP Server Function (SecureNAT Function). Use this to disable the Virtual NAT and DHCP Server function (SecureNAT Function) on the currently managed Virtual Hub. By executing this API the Virtual NAT function immediately stops operating and the Virtual DHCP Server function deletes the DHCP lease database and stops the service. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "DisableSecureNAT",
+  "params": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
+
+

+

"SetSecureNATOption" RPC API - Change Settings of SecureNAT Function

+

Description

+

Change Settings of SecureNAT Function. Use this to change and save the virtual host network interface settings, virtual NAT function settings and virtual DHCP server settings of the Virtual NAT and DHCP Server function (SecureNAT function) on the currently managed Virtual Hub. The SecureNAT function holds one virtual network adapter on the L2 segment inside the Virtual Hub and it has been assigned a MAC address and an IP address. By doing this, another host connected to the same L2 segment is able to communicate with the SecureNAT virtual host as if it is an actual IP host existing on the network. [Warning about SecureNAT Function] The SecureNAT function is recommended only for system administrators and people with a detailed knowledge of networks. If you use the SecureNAT function correctly, it is possible to achieve a safe form of remote access via a VPN. However when used in the wrong way, it can put the entire network in danger. Anyone who does not have a thorough knowledge of networks and anyone who does not have the network administrators permission must not enable the SecureNAT function. For a detailed explanation of the SecureNAT function, please refer to the VPN Server's manual and online documentation. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetSecureNATOption",
+  "params": {
+    "RpcHubName_str": "rpchubname",
+    "MacAddress_bin": "SGVsbG8gV29ybGQ=",
+    "Ip_ip": "192.168.0.1",
+    "Mask_ip": "255.255.255.255",
+    "UseNat_bool": false,
+    "Mtu_u32": 0,
+    "NatTcpTimeout_u32": 0,
+    "NatUdpTimeout_u32": 0,
+    "UseDhcp_bool": false,
+    "DhcpLeaseIPStart_ip": "192.168.0.1",
+    "DhcpLeaseIPEnd_ip": "192.168.0.1",
+    "DhcpSubnetMask_ip": "255.255.255.255",
+    "DhcpExpireTimeSpan_u32": 0,
+    "DhcpGatewayAddress_ip": "192.168.0.1",
+    "DhcpDnsServerAddress_ip": "192.168.0.1",
+    "DhcpDnsServerAddress2_ip": "192.168.0.1",
+    "DhcpDomainName_str": "dhcpdomainname",
+    "SaveLog_bool": false,
+    "ApplyDhcpPushRoutes_bool": false,
+    "DhcpPushRoutes_str": "dhcppushroutes"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "RpcHubName_str": "rpchubname",
+    "MacAddress_bin": "SGVsbG8gV29ybGQ=",
+    "Ip_ip": "192.168.0.1",
+    "Mask_ip": "255.255.255.255",
+    "UseNat_bool": false,
+    "Mtu_u32": 0,
+    "NatTcpTimeout_u32": 0,
+    "NatUdpTimeout_u32": 0,
+    "UseDhcp_bool": false,
+    "DhcpLeaseIPStart_ip": "192.168.0.1",
+    "DhcpLeaseIPEnd_ip": "192.168.0.1",
+    "DhcpSubnetMask_ip": "255.255.255.255",
+    "DhcpExpireTimeSpan_u32": 0,
+    "DhcpGatewayAddress_ip": "192.168.0.1",
+    "DhcpDnsServerAddress_ip": "192.168.0.1",
+    "DhcpDnsServerAddress2_ip": "192.168.0.1",
+    "DhcpDomainName_str": "dhcpdomainname",
+    "SaveLog_bool": false,
+    "ApplyDhcpPushRoutes_bool": false,
+    "DhcpPushRoutes_str": "dhcppushroutes"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
RpcHubName_strstring (ASCII)Target Virtual HUB name
MacAddress_binstring (Base64 binary)MAC address
Ip_ipstring (IP address)IP address
Mask_ipstring (IP address)Subnet mask
UseNat_boolbooleanUse flag of the Virtual NAT function
Mtu_u32number (uint32)MTU value (Standard: 1500)
NatTcpTimeout_u32number (uint32)NAT TCP timeout in seconds
NatUdpTimeout_u32number (uint32)NAT UDP timeout in seconds
UseDhcp_boolbooleanUsing flag of DHCP function
DhcpLeaseIPStart_ipstring (IP address)Specify the start point of the address band to be distributed to the client. (Example: 192.168.30.10)
DhcpLeaseIPEnd_ipstring (IP address)Specify the end point of the address band to be distributed to the client. (Example: 192.168.30.200)
DhcpSubnetMask_ipstring (IP address)Specify the subnet mask to be specified for the client. (Example: 255.255.255.0)
DhcpExpireTimeSpan_u32number (uint32)Specify the expiration date in second units for leasing an IP address to a client.
DhcpGatewayAddress_ipstring (IP address)Specify the IP address of the default gateway to be notified to the client. You can specify a SecureNAT Virtual Host IP address for this when the SecureNAT Function's Virtual NAT Function has been enabled and is being used also. If you specify 0 or none, then the client will not be notified of the default gateway.
DhcpDnsServerAddress_ipstring (IP address)Specify the IP address of the primary DNS Server to be notified to the client. You can specify a SecureNAT Virtual Host IP address for this when the SecureNAT Function's Virtual NAT Function has been enabled and is being used also. If you specify empty, then the client will not be notified of the DNS Server address.
DhcpDnsServerAddress2_ipstring (IP address)Specify the IP address of the secondary DNS Server to be notified to the client. You can specify a SecureNAT Virtual Host IP address for this when the SecureNAT Function's Virtual NAT Function has been enabled and is being used also. If you specify empty, then the client will not be notified of the DNS Server address.
DhcpDomainName_strstring (ASCII)Specify the domain name to be notified to the client. If you specify none, then the client will not be notified of the domain name.
SaveLog_boolbooleanSpecify whether or not to save the Virtual DHCP Server operation in the Virtual Hub security log. Specify true to save it. This value is interlinked with the Virtual NAT Function log save setting.
ApplyDhcpPushRoutes_boolbooleanThe flag to enable the DhcpPushRoutes_str field.
DhcpPushRoutes_strstring (ASCII)Specify the static routing table to push. Example: "192.168.5.0/255.255.255.0/192.168.4.254, 10.0.0.0/255.0.0.0/192.168.4.253" Split multiple entries (maximum: 64 entries) by comma or space characters. Each entry must be specified in the "IP network address/subnet mask/gateway IP address" format. This Virtual DHCP Server can push the classless static routes (RFC 3442) with DHCP reply messages to VPN clients. Whether or not a VPN client can recognize the classless static routes (RFC 3442) depends on the target VPN client software. SoftEther VPN Client and OpenVPN Client are supporting the classless static routes. On L2TP/IPsec and MS-SSTP protocols, the compatibility depends on the implementation of the client software. You can realize the split tunneling if you clear the default gateway field on the Virtual DHCP Server options. On the client side, L2TP/IPsec and MS-SSTP clients need to be configured not to set up the default gateway for the split tunneling usage. You can also push the classless static routes (RFC 3442) by your existing external DHCP server. In that case, disable the Virtual DHCP Server function on SecureNAT, and you need not to set up the classless routes on this API. See the RFC 3442 to understand the classless routes.
+
+

+

"GetSecureNATOption" RPC API - Get Settings of SecureNAT Function

+

Description

+

Get Settings of SecureNAT Function. This API get the registered settings for the SecureNAT function which is set by the SetSecureNATOption API.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetSecureNATOption",
+  "params": {
+    "RpcHubName_str": "rpchubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "RpcHubName_str": "rpchubname",
+    "MacAddress_bin": "SGVsbG8gV29ybGQ=",
+    "Ip_ip": "192.168.0.1",
+    "Mask_ip": "255.255.255.255",
+    "UseNat_bool": false,
+    "Mtu_u32": 0,
+    "NatTcpTimeout_u32": 0,
+    "NatUdpTimeout_u32": 0,
+    "UseDhcp_bool": false,
+    "DhcpLeaseIPStart_ip": "192.168.0.1",
+    "DhcpLeaseIPEnd_ip": "192.168.0.1",
+    "DhcpSubnetMask_ip": "255.255.255.255",
+    "DhcpExpireTimeSpan_u32": 0,
+    "DhcpGatewayAddress_ip": "192.168.0.1",
+    "DhcpDnsServerAddress_ip": "192.168.0.1",
+    "DhcpDnsServerAddress2_ip": "192.168.0.1",
+    "DhcpDomainName_str": "dhcpdomainname",
+    "SaveLog_bool": false,
+    "ApplyDhcpPushRoutes_bool": false,
+    "DhcpPushRoutes_str": "dhcppushroutes"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
RpcHubName_strstring (ASCII)Target Virtual HUB name
MacAddress_binstring (Base64 binary)MAC address
Ip_ipstring (IP address)IP address
Mask_ipstring (IP address)Subnet mask
UseNat_boolbooleanUse flag of the Virtual NAT function
Mtu_u32number (uint32)MTU value (Standard: 1500)
NatTcpTimeout_u32number (uint32)NAT TCP timeout in seconds
NatUdpTimeout_u32number (uint32)NAT UDP timeout in seconds
UseDhcp_boolbooleanUsing flag of DHCP function
DhcpLeaseIPStart_ipstring (IP address)Specify the start point of the address band to be distributed to the client. (Example: 192.168.30.10)
DhcpLeaseIPEnd_ipstring (IP address)Specify the end point of the address band to be distributed to the client. (Example: 192.168.30.200)
DhcpSubnetMask_ipstring (IP address)Specify the subnet mask to be specified for the client. (Example: 255.255.255.0)
DhcpExpireTimeSpan_u32number (uint32)Specify the expiration date in second units for leasing an IP address to a client.
DhcpGatewayAddress_ipstring (IP address)Specify the IP address of the default gateway to be notified to the client. You can specify a SecureNAT Virtual Host IP address for this when the SecureNAT Function's Virtual NAT Function has been enabled and is being used also. If you specify 0 or none, then the client will not be notified of the default gateway.
DhcpDnsServerAddress_ipstring (IP address)Specify the IP address of the primary DNS Server to be notified to the client. You can specify a SecureNAT Virtual Host IP address for this when the SecureNAT Function's Virtual NAT Function has been enabled and is being used also. If you specify empty, then the client will not be notified of the DNS Server address.
DhcpDnsServerAddress2_ipstring (IP address)Specify the IP address of the secondary DNS Server to be notified to the client. You can specify a SecureNAT Virtual Host IP address for this when the SecureNAT Function's Virtual NAT Function has been enabled and is being used also. If you specify empty, then the client will not be notified of the DNS Server address.
DhcpDomainName_strstring (ASCII)Specify the domain name to be notified to the client. If you specify none, then the client will not be notified of the domain name.
SaveLog_boolbooleanSpecify whether or not to save the Virtual DHCP Server operation in the Virtual Hub security log. Specify true to save it. This value is interlinked with the Virtual NAT Function log save setting.
ApplyDhcpPushRoutes_boolbooleanThe flag to enable the DhcpPushRoutes_str field.
DhcpPushRoutes_strstring (ASCII)Specify the static routing table to push. Example: "192.168.5.0/255.255.255.0/192.168.4.254, 10.0.0.0/255.0.0.0/192.168.4.253" Split multiple entries (maximum: 64 entries) by comma or space characters. Each entry must be specified in the "IP network address/subnet mask/gateway IP address" format. This Virtual DHCP Server can push the classless static routes (RFC 3442) with DHCP reply messages to VPN clients. Whether or not a VPN client can recognize the classless static routes (RFC 3442) depends on the target VPN client software. SoftEther VPN Client and OpenVPN Client are supporting the classless static routes. On L2TP/IPsec and MS-SSTP protocols, the compatibility depends on the implementation of the client software. You can realize the split tunneling if you clear the default gateway field on the Virtual DHCP Server options. On the client side, L2TP/IPsec and MS-SSTP clients need to be configured not to set up the default gateway for the split tunneling usage. You can also push the classless static routes (RFC 3442) by your existing external DHCP server. In that case, disable the Virtual DHCP Server function on SecureNAT, and you need not to set up the classless routes on this API. See the RFC 3442 to understand the classless routes.
+
+

+

"EnumNAT" RPC API - Get Virtual NAT Function Session Table of SecureNAT Function

+

Description

+

Get Virtual NAT Function Session Table of SecureNAT Function. Use this to get the table of TCP and UDP sessions currently communicating via the Virtual NAT (NAT table) in cases when the Virtual NAT function is operating on the currently managed Virtual Hub. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "EnumNAT",
+  "params": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "NatTable": [
+      {
+        "Id_u32": 0,
+        "Protocol_u32": 0,
+        "SrcIp_ip": "192.168.0.1",
+        "SrcHost_str": "srchost",
+        "SrcPort_u32": 0,
+        "DestIp_ip": "192.168.0.1",
+        "DestHost_str": "desthost",
+        "DestPort_u32": 0,
+        "CreatedTime_dt": "2020-08-01T12:24:36.123",
+        "LastCommTime_dt": "2020-08-01T12:24:36.123",
+        "SendSize_u64": 0,
+        "RecvSize_u64": 0,
+        "TcpStatus_u32": 0
+      },
+      {
+        "Id_u32": 0,
+        "Protocol_u32": 0,
+        "SrcIp_ip": "192.168.0.1",
+        "SrcHost_str": "srchost",
+        "SrcPort_u32": 0,
+        "DestIp_ip": "192.168.0.1",
+        "DestHost_str": "desthost",
+        "DestPort_u32": 0,
+        "CreatedTime_dt": "2020-08-01T12:24:36.123",
+        "LastCommTime_dt": "2020-08-01T12:24:36.123",
+        "SendSize_u64": 0,
+        "RecvSize_u64": 0,
+        "TcpStatus_u32": 0
+      },
+      {
+        "Id_u32": 0,
+        "Protocol_u32": 0,
+        "SrcIp_ip": "192.168.0.1",
+        "SrcHost_str": "srchost",
+        "SrcPort_u32": 0,
+        "DestIp_ip": "192.168.0.1",
+        "DestHost_str": "desthost",
+        "DestPort_u32": 0,
+        "CreatedTime_dt": "2020-08-01T12:24:36.123",
+        "LastCommTime_dt": "2020-08-01T12:24:36.123",
+        "SendSize_u64": 0,
+        "RecvSize_u64": 0,
+        "TcpStatus_u32": 0
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)Virtual Hub Name
NatTableArray objectNAT item
Id_u32number (uint32)ID
Protocol_u32number (enum)Protocol
Values:
0: TCP
1: UDP
2: DNS
3: ICMP
SrcIp_ipstring (IP address)Source IP address
SrcHost_strstring (ASCII)Source host name
SrcPort_u32number (uint32)Source port number
DestIp_ipstring (IP address)Destination IP address
DestHost_strstring (ASCII)Destination host name
DestPort_u32number (uint32)Destination port number
CreatedTime_dtDateConnection time
LastCommTime_dtDateLast communication time
SendSize_u64number (uint64)Transmission size
RecvSize_u64number (uint64)Receive size
TcpStatus_u32number (enum)TCP state
Values:
0: Connecting
1: Send the RST (Connection failure or disconnected)
2: Connection complete
3: Connection established
4: Wait for socket disconnection
+
+

+

"EnumDHCP" RPC API - Get Virtual DHCP Server Function Lease Table of SecureNAT Function

+

Description

+

Get Virtual DHCP Server Function Lease Table of SecureNAT Function. Use this to get the lease table of IP addresses, held by the Virtual DHCP Server, that are assigned to clients in cases when the Virtual NAT function is operating on the currently managed Virtual Hub. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "EnumDHCP",
+  "params": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "DhcpTable": [
+      {
+        "Id_u32": 0,
+        "LeasedTime_dt": "2020-08-01T12:24:36.123",
+        "ExpireTime_dt": "2020-08-01T12:24:36.123",
+        "MacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "IpAddress_ip": "192.168.0.1",
+        "Mask_u32": 0,
+        "Hostname_str": "hostname"
+      },
+      {
+        "Id_u32": 0,
+        "LeasedTime_dt": "2020-08-01T12:24:36.123",
+        "ExpireTime_dt": "2020-08-01T12:24:36.123",
+        "MacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "IpAddress_ip": "192.168.0.1",
+        "Mask_u32": 0,
+        "Hostname_str": "hostname"
+      },
+      {
+        "Id_u32": 0,
+        "LeasedTime_dt": "2020-08-01T12:24:36.123",
+        "ExpireTime_dt": "2020-08-01T12:24:36.123",
+        "MacAddress_bin": "SGVsbG8gV29ybGQ=",
+        "IpAddress_ip": "192.168.0.1",
+        "Mask_u32": 0,
+        "Hostname_str": "hostname"
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)Virtual Hub Name
DhcpTableArray objectDHCP Item
Id_u32number (uint32)ID
LeasedTime_dtDateLease time
ExpireTime_dtDateExpiration date
MacAddress_binstring (Base64 binary)MAC address
IpAddress_ipstring (IP address)IP address
Mask_u32number (uint32)Subnet mask
Hostname_strstring (ASCII)Host name
+
+

+

"GetSecureNATStatus" RPC API - Get the Operating Status of the Virtual NAT and DHCP Server Function (SecureNAT Function)

+

Description

+

Get the Operating Status of the Virtual NAT and DHCP Server Function (SecureNAT Function). Use this to get the operating status of the Virtual NAT and DHCP Server function (SecureNAT Function) when it is operating on the currently managed Virtual Hub. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetSecureNATStatus",
+  "params": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "NumTcpSessions_u32": 0,
+    "NumUdpSessions_u32": 0,
+    "NumIcmpSessions_u32": 0,
+    "NumDnsSessions_u32": 0,
+    "NumDhcpClients_u32": 0,
+    "IsKernelMode_bool": false,
+    "IsRawIpMode_bool": false
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)Virtual Hub Name
NumTcpSessions_u32number (uint32)Number of TCP sessions
NumUdpSessions_u32number (uint32)Ntmber of UDP sessions
NumIcmpSessions_u32number (uint32)Nymber of ICMP sessions
NumDnsSessions_u32number (uint32)Number of DNS sessions
NumDhcpClients_u32number (uint32)Number of DHCP clients
IsKernelMode_boolbooleanWhether the NAT is operating in the Kernel Mode
IsRawIpMode_boolbooleanWhether the NAT is operating in the Raw IP Mode
+
+

+

"EnumEthernet" RPC API - Get List of Network Adapters Usable as Local Bridge

+

Description

+

Get List of Network Adapters Usable as Local Bridge. Use this to get a list of Ethernet devices (network adapters) that can be used as a bridge destination device as part of a Local Bridge connection. If possible, network connection name is displayed. You can use a device displayed here by using the AddLocalBridge API. To call this API, you must have VPN Server administrator privileges.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "EnumEthernet",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "EthList": [
+      {
+        "DeviceName_str": "devicename",
+        "NetworkConnectionName_utf": "networkconnectionname"
+      },
+      {
+        "DeviceName_str": "devicename",
+        "NetworkConnectionName_utf": "networkconnectionname"
+      },
+      {
+        "DeviceName_str": "devicename",
+        "NetworkConnectionName_utf": "networkconnectionname"
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
EthListArray objectEthernet Network Adapters list
DeviceName_strstring (ASCII)Device name
NetworkConnectionName_utfstring (UTF8)Network connection name (description)
+
+

+

"AddLocalBridge" RPC API - Create Local Bridge Connection

+

Description

+

Create Local Bridge Connection. Use this to create a new Local Bridge connection on the VPN Server. By using a Local Bridge, you can configure a Layer 2 bridge connection between a Virtual Hub operating on this VPN server and a physical Ethernet Device (Network Adapter). You can create a tap device (virtual network interface) on the system and connect a bridge between Virtual Hubs (the tap device is only supported by Linux versions). It is possible to establish a bridge to an operating network adapter of your choice for the bridge destination Ethernet device (network adapter), but in high load environments, we recommend you prepare a network adapter dedicated to serve as a bridge. To call this API, you must have VPN Server administrator privileges.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "AddLocalBridge",
+  "params": {
+    "DeviceName_str": "devicename",
+    "HubNameLB_str": "hubnamelb"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "DeviceName_str": "devicename",
+    "HubNameLB_str": "hubnamelb",
+    "Online_bool": false,
+    "Active_bool": false,
+    "TapMode_bool": false
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
DeviceName_strstring (ASCII)Physical Ethernet device name
HubNameLB_strstring (ASCII)The Virtual Hub name
Online_boolbooleanOnline flag
Active_boolbooleanRunning flag
TapMode_boolbooleanSpecify true if you are using a tap device rather than a network adapter for the bridge destination (only supported for Linux versions).
+
+

+

"DeleteLocalBridge" RPC API - Delete Local Bridge Connection

+

Description

+

Delete Local Bridge Connection. Use this to delete an existing Local Bridge connection. To get a list of current Local Bridge connections use the EnumLocalBridge API. To call this API, you must have VPN Server administrator privileges.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "DeleteLocalBridge",
+  "params": {
+    "DeviceName_str": "devicename",
+    "HubNameLB_str": "hubnamelb"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "DeviceName_str": "devicename",
+    "HubNameLB_str": "hubnamelb",
+    "Online_bool": false,
+    "Active_bool": false,
+    "TapMode_bool": false
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
DeviceName_strstring (ASCII)Physical Ethernet device name
HubNameLB_strstring (ASCII)The Virtual Hub name
Online_boolbooleanOnline flag
Active_boolbooleanRunning flag
TapMode_boolbooleanSpecify true if you are using a tap device rather than a network adapter for the bridge destination (only supported for Linux versions).
+
+

+

"EnumLocalBridge" RPC API - Get List of Local Bridge Connection

+

Description

+

Get List of Local Bridge Connection. Use this to get a list of the currently defined Local Bridge connections. You can get the Local Bridge connection Virtual Hub name and the bridge destination Ethernet device (network adapter) name or tap device name, as well as the operating status.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "EnumLocalBridge",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "LocalBridgeList": [
+      {
+        "DeviceName_str": "devicename",
+        "HubNameLB_str": "hubnamelb",
+        "Online_bool": false,
+        "Active_bool": false,
+        "TapMode_bool": false
+      },
+      {
+        "DeviceName_str": "devicename",
+        "HubNameLB_str": "hubnamelb",
+        "Online_bool": false,
+        "Active_bool": false,
+        "TapMode_bool": false
+      },
+      {
+        "DeviceName_str": "devicename",
+        "HubNameLB_str": "hubnamelb",
+        "Online_bool": false,
+        "Active_bool": false,
+        "TapMode_bool": false
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
LocalBridgeListArray objectLocal Bridge list
DeviceName_strstring (ASCII)Physical Ethernet device name
HubNameLB_strstring (ASCII)The Virtual Hub name
Online_boolbooleanOnline flag
Active_boolbooleanRunning flag
TapMode_boolbooleanSpecify true if you are using a tap device rather than a network adapter for the bridge destination (only supported for Linux versions).
+
+

+

"GetBridgeSupport" RPC API - Get whether the localbridge function is supported on the current system

+

Description

+

Get whether the localbridge function is supported on the current system.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetBridgeSupport",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "IsBridgeSupportedOs_bool": false,
+    "IsWinPcapNeeded_bool": false
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
IsBridgeSupportedOs_boolbooleanWhether the OS supports the Local Bridge function
IsWinPcapNeeded_boolbooleanWhether WinPcap is necessary to install
+
+

+

"RebootServer" RPC API - Reboot VPN Server Service

+

Description

+

Reboot VPN Server Service. Use this to restart the VPN Server service. When you restart the VPN Server, all currently connected sessions and TCP connections will be disconnected and no new connections will be accepted until the restart process has completed. By using this API, only the VPN Server service program will be restarted and the physical computer that VPN Server is operating on does not restart. This management session will also be disconnected, so you will need to reconnect to continue management. Also, by specifying the "IntValue" parameter to "1", the contents of the configuration file (.config) held by the current VPN Server will be initialized. To call this API, you must have VPN Server administrator privileges.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "RebootServer",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "IntValue_u32": 0,
+    "Int64Value_u64": 0,
+    "StrValue_str": "strvalue",
+    "UniStrValue_utf": "unistrvalue"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
IntValue_u32number (uint32)A 32-bit integer field
Int64Value_u64number (uint64)A 64-bit integer field
StrValue_strstring (ASCII)An Ascii string field
UniStrValue_utfstring (UTF8)An UTF-8 string field
+
+

+

"GetCaps" RPC API - Get List of Server Functions / Capability

+

Description

+

Get List of Server Functions / Capability. Use this get a list of functions and capability of the VPN Server currently connected and being managed. The function and capability of VPN Servers are different depending on the operating VPN server's edition and version. Using this API, you can find out the capability of the target VPN Server and report it.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetCaps",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "CapsList": [
+      {
+        "CapsName_str": "capsname",
+        "CapsValue_u32": 0,
+        "CapsDescrption_utf": "capsdescrption"
+      },
+      {
+        "CapsName_str": "capsname",
+        "CapsValue_u32": 0,
+        "CapsDescrption_utf": "capsdescrption"
+      },
+      {
+        "CapsName_str": "capsname",
+        "CapsValue_u32": 0,
+        "CapsDescrption_utf": "capsdescrption"
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
CapsListArray objectCaps list of the VPN Server
CapsName_strstring (ASCII)Name
CapsValue_u32number (uint32)Value
CapsDescrption_utfstring (UTF8)Descrption
+
+

+

"GetConfig" RPC API - Get the current configuration of the VPN Server

+

Description

+

Get the current configuration of the VPN Server. Use this to get a text file (.config file) that contains the current configuration contents of the VPN server. You can get the status on the VPN Server at the instant this API is executed. You can edit the configuration file by using a regular text editor. To write an edited configuration to the VPN Server, use the SetConfig API. To call this API, you must have VPN Server administrator privileges.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetConfig",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "FileName_str": "filename",
+    "FileData_bin": "SGVsbG8gV29ybGQ="
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
FileName_strstring (ASCII)File name (valid only for returning from the server)
FileData_binstring (Base64 binary)File data
+
+

+

"SetConfig" RPC API - Write Configuration File to VPN Server

+

Description

+

Write Configuration File to VPN Server. Use this to write the configuration file to the VPN Server. By executing this API, the contents of the specified configuration file will be applied to the VPN Server and the VPN Server program will automatically restart and upon restart, operate according to the new configuration contents. Because it is difficult for an administrator to write all the contents of a configuration file, we recommend you use the GetConfig API to get the current contents of the VPN Server configuration and save it to file. You can then edit these contents in a regular text editor and then use the SetConfig API to rewrite the contents to the VPN Server. This API is for people with a detailed knowledge of the VPN Server and if an incorrectly configured configuration file is written to the VPN Server, it not only could cause errors, it could also result in the lost of the current setting data. Take special care when carrying out this action. To call this API, you must have VPN Server administrator privileges.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetConfig",
+  "params": {
+    "FileData_bin": "SGVsbG8gV29ybGQ="
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "FileName_str": "filename",
+    "FileData_bin": "SGVsbG8gV29ybGQ="
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
FileName_strstring (ASCII)File name (valid only for returning from the server)
FileData_binstring (Base64 binary)File data
+
+

+

"GetDefaultHubAdminOptions" RPC API - Get Virtual Hub Administration Option default values

+

Description

+

Get Virtual Hub Administration Option default values.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetDefaultHubAdminOptions",
+  "params": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "AdminOptionList": [
+      {
+        "Name_str": "name",
+        "Value_u32": 0,
+        "Descrption_utf": "descrption"
+      },
+      {
+        "Name_str": "name",
+        "Value_u32": 0,
+        "Descrption_utf": "descrption"
+      },
+      {
+        "Name_str": "name",
+        "Value_u32": 0,
+        "Descrption_utf": "descrption"
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)Virtual HUB name
AdminOptionListArray objectList data
Name_strstring (ASCII)Name
Value_u32number (uint32)Data
Descrption_utfstring (UTF8)Descrption
+
+

+

"GetHubAdminOptions" RPC API - Get List of Virtual Hub Administration Options

+

Description

+

Get List of Virtual Hub Administration Options. Use this to get a list of Virtual Hub administration options that are set on the currently managed Virtual Hub. The purpose of the Virtual Hub administration options is for the VPN Server Administrator to set limits for the setting ranges when the administration of the Virtual Hub is to be trusted to each Virtual Hub administrator. Only an administrator with administration privileges for this entire VPN Server is able to add, edit and delete the Virtual Hub administration options. The Virtual Hub administrators are unable to make changes to the administration options, however they are able to view them. There is an exception however. If allow_hub_admin_change_option is set to "1", even Virtual Hub administrators are able to edit the administration options. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster member.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetHubAdminOptions",
+  "params": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "AdminOptionList": [
+      {
+        "Name_str": "name",
+        "Value_u32": 0,
+        "Descrption_utf": "descrption"
+      },
+      {
+        "Name_str": "name",
+        "Value_u32": 0,
+        "Descrption_utf": "descrption"
+      },
+      {
+        "Name_str": "name",
+        "Value_u32": 0,
+        "Descrption_utf": "descrption"
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)Virtual HUB name
AdminOptionListArray objectList data
Name_strstring (ASCII)Name
Value_u32number (uint32)Data
Descrption_utfstring (UTF8)Descrption
+
+

+

"SetHubAdminOptions" RPC API - Set Values of Virtual Hub Administration Options

+

Description

+

Set Values of Virtual Hub Administration Options. Use this to change the values of Virtual Hub administration options that are set on the currently managed Virtual Hub. The purpose of the Virtual Hub administration options is for the VPN Server Administrator to set limits for the setting ranges when the administration of the Virtual Hub is to be trusted to each Virtual Hub administrator. Only an administrator with administration privileges for this entire VPN Server is able to add, edit and delete the Virtual Hub administration options. The Virtual Hub administrators are unable to make changes to the administration options, however they are able to view them. There is an exception however. If allow_hub_admin_change_option is set to "1", even Virtual Hub administrators are able to edit the administration options. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster member.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetHubAdminOptions",
+  "params": {
+    "HubName_str": "hubname",
+    "AdminOptionList": [
+      {
+        "Name_str": "name",
+        "Value_u32": 0,
+        "Descrption_utf": "descrption"
+      },
+      {
+        "Name_str": "name",
+        "Value_u32": 0,
+        "Descrption_utf": "descrption"
+      },
+      {
+        "Name_str": "name",
+        "Value_u32": 0,
+        "Descrption_utf": "descrption"
+      }
+    ]
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "AdminOptionList": [
+      {
+        "Name_str": "name",
+        "Value_u32": 0,
+        "Descrption_utf": "descrption"
+      },
+      {
+        "Name_str": "name",
+        "Value_u32": 0,
+        "Descrption_utf": "descrption"
+      },
+      {
+        "Name_str": "name",
+        "Value_u32": 0,
+        "Descrption_utf": "descrption"
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)Virtual HUB name
AdminOptionListArray objectList data
Name_strstring (ASCII)Name
Value_u32number (uint32)Data
Descrption_utfstring (UTF8)Descrption
+
+

+

"GetHubExtOptions" RPC API - Get List of Virtual Hub Extended Options

+

Description

+

Get List of Virtual Hub Extended Options. Use this to get a Virtual Hub Extended Options List that is set on the currently managed Virtual Hub. Virtual Hub Extended Option enables you to configure more detail settings of the Virtual Hub. By default, both VPN Server's global administrators and individual Virtual Hub's administrators can modify the Virtual Hub Extended Options. However, if the deny_hub_admin_change_ext_option is set to 1 on the Virtual Hub Admin Options, the individual Virtual Hub's administrators cannot modify the Virtual Hub Extended Options. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster member.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetHubExtOptions",
+  "params": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "AdminOptionList": [
+      {
+        "Name_str": "name",
+        "Value_u32": 0,
+        "Descrption_utf": "descrption"
+      },
+      {
+        "Name_str": "name",
+        "Value_u32": 0,
+        "Descrption_utf": "descrption"
+      },
+      {
+        "Name_str": "name",
+        "Value_u32": 0,
+        "Descrption_utf": "descrption"
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)Virtual HUB name
AdminOptionListArray objectList data
Name_strstring (ASCII)Name
Value_u32number (uint32)Data
Descrption_utfstring (UTF8)Descrption
+
+

+

"SetHubExtOptions" RPC API - Set a Value of Virtual Hub Extended Options

+

Description

+

Set a Value of Virtual Hub Extended Options. Use this to set a value in the Virtual Hub Extended Options List that is set on the currently managed Virtual Hub. Virtual Hub Extended Option enables you to configure more detail settings of the Virtual Hub. By default, both VPN Server's global administrators and individual Virtual Hub's administrators can modify the Virtual Hub Extended Options. However, if the deny_hub_admin_change_ext_option is set to 1 on the Virtual Hub Admin Options, the individual Virtual Hub's administrators cannot modify the Virtual Hub Extended Options. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster member.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetHubExtOptions",
+  "params": {
+    "HubName_str": "hubname",
+    "AdminOptionList": [
+      {
+        "Name_str": "name",
+        "Value_u32": 0,
+        "Descrption_utf": "descrption"
+      },
+      {
+        "Name_str": "name",
+        "Value_u32": 0,
+        "Descrption_utf": "descrption"
+      },
+      {
+        "Name_str": "name",
+        "Value_u32": 0,
+        "Descrption_utf": "descrption"
+      }
+    ]
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "AdminOptionList": [
+      {
+        "Name_str": "name",
+        "Value_u32": 0,
+        "Descrption_utf": "descrption"
+      },
+      {
+        "Name_str": "name",
+        "Value_u32": 0,
+        "Descrption_utf": "descrption"
+      },
+      {
+        "Name_str": "name",
+        "Value_u32": 0,
+        "Descrption_utf": "descrption"
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)Virtual HUB name
AdminOptionListArray objectList data
Name_strstring (ASCII)Name
Value_u32number (uint32)Data
Descrption_utfstring (UTF8)Descrption
+
+

+

"AddL3Switch" RPC API - Define New Virtual Layer 3 Switch

+

Description

+

Define New Virtual Layer 3 Switch. Use this to define a new Virtual Layer 3 Switch on the VPN Server. To call this API, you must have VPN Server administrator privileges. Also, this API does not operate on VPN Bridge. [Explanation on Virtual Layer 3 Switch Function] You can define Virtual Layer 3 Switches between multiple Virtual Hubs operating on this VPN Server and configure routing between different IP networks. [Caution about the Virtual Layer 3 Switch Function] The Virtual Layer 3 Switch functions are provided for network administrators and other people who know a lot about networks and IP routing. If you are using the regular VPN functions, you do not need to use the Virtual Layer 3 Switch functions. If the Virtual Layer 3 Switch functions are to be used, the person who configures them must have sufficient knowledge of IP routing and be perfectly capable of not impacting the network.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "AddL3Switch",
+  "params": {
+    "Name_str": "name"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "Name_str": "name"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + +
NameTypeDescrption
Name_strstring (ASCII)Layer-3 Switch name
+
+

+

"DelL3Switch" RPC API - Delete Virtual Layer 3 Switch

+

Description

+

Delete Virtual Layer 3 Switch. Use this to delete an existing Virtual Layer 3 Switch that is defined on the VPN Server. When the specified Virtual Layer 3 Switch is operating, it will be automatically deleted after operation stops. To get a list of existing Virtual Layer 3 Switches, use the EnumL3Switch API. To call this API, you must have VPN Server administrator privileges. Also, this API does not operate on VPN Bridge.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "DelL3Switch",
+  "params": {
+    "Name_str": "name"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "Name_str": "name"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + +
NameTypeDescrption
Name_strstring (ASCII)Layer-3 Switch name
+
+

+

"EnumL3Switch" RPC API - Get List of Virtual Layer 3 Switches

+

Description

+

Get List of Virtual Layer 3 Switches. Use this to define a new Virtual Layer 3 Switch on the VPN Server. To call this API, you must have VPN Server administrator privileges. Also, this API does not operate on VPN Bridge. [Explanation on Virtual Layer 3 Switch Function] You can define Virtual Layer 3 Switches between multiple Virtual Hubs operating on this VPN Server and configure routing between different IP networks. [Caution about the Virtual Layer 3 Switch Function] The Virtual Layer 3 Switch functions are provided for network administrators and other people who know a lot about networks and IP routing. If you are using the regular VPN functions, you do not need to use the Virtual Layer 3 Switch functions. If the Virtual Layer 3 Switch functions are to be used, the person who configures them must have sufficient knowledge of IP routing and be perfectly capable of not impacting the network.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "EnumL3Switch",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "L3SWList": [
+      {
+        "Name_str": "name",
+        "NumInterfaces_u32": 0,
+        "NumTables_u32": 0,
+        "Active_bool": false,
+        "Online_bool": false
+      },
+      {
+        "Name_str": "name",
+        "NumInterfaces_u32": 0,
+        "NumTables_u32": 0,
+        "Active_bool": false,
+        "Online_bool": false
+      },
+      {
+        "Name_str": "name",
+        "NumInterfaces_u32": 0,
+        "NumTables_u32": 0,
+        "Active_bool": false,
+        "Online_bool": false
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
L3SWListArray objectLayer-3 switch list
Name_strstring (ASCII)Name of the layer-3 switch
NumInterfaces_u32number (uint32)Number of layer-3 switch virtual interfaces
NumTables_u32number (uint32)Number of routing tables
Active_boolbooleanActivated flag
Online_boolbooleanOnline flag
+
+

+

"StartL3Switch" RPC API - Start Virtual Layer 3 Switch Operation

+

Description

+

Start Virtual Layer 3 Switch Operation. Use this to start the operation of an existing Virtual Layer 3 Switch defined on the VPN Server whose operation is currently stopped. To get a list of existing Virtual Layer 3 Switches, use the EnumL3Switch API. To call this API, you must have VPN Server administrator privileges. Also, this API does not operate on VPN Bridge. [Explanation on Virtual Layer 3 Switch Function] You can define Virtual Layer 3 Switches between multiple Virtual Hubs operating on this VPN Server and configure routing between different IP networks. [Caution about the Virtual Layer 3 Switch Function] The Virtual Layer 3 Switch functions are provided for network administrators and other people who know a lot about networks and IP routing. If you are using the regular VPN functions, you do not need to use the Virtual Layer 3 Switch functions. If the Virtual Layer 3 Switch functions are to be used, the person who configures them must have sufficient knowledge of IP routing and be perfectly capable of not impacting the network.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "StartL3Switch",
+  "params": {
+    "Name_str": "name"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "Name_str": "name"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + +
NameTypeDescrption
Name_strstring (ASCII)Layer-3 Switch name
+
+

+

"StopL3Switch" RPC API - Stop Virtual Layer 3 Switch Operation

+

Description

+

Stop Virtual Layer 3 Switch Operation. Use this to stop the operation of an existing Virtual Layer 3 Switch defined on the VPN Server whose operation is currently operating. To get a list of existing Virtual Layer 3 Switches, use the EnumL3Switch API. To call this API, you must have VPN Server administrator privileges.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "StopL3Switch",
+  "params": {
+    "Name_str": "name"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "Name_str": "name"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + +
NameTypeDescrption
Name_strstring (ASCII)Layer-3 Switch name
+
+

+

"AddL3If" RPC API - Add Virtual Interface to Virtual Layer 3 Switch

+

Description

+

Add Virtual Interface to Virtual Layer 3 Switch. Use this to add to a specified Virtual Layer 3 Switch, a virtual interface that connects to a Virtual Hub operating on the same VPN Server. You can define multiple virtual interfaces and routing tables for a single Virtual Layer 3 Switch. A virtual interface is associated to a virtual Hub and operates as a single IP host on the Virtual Hub when that Virtual Hub is operating. When multiple virtual interfaces that respectively belong to a different IP network of a different Virtual Hub are defined, IP routing will be automatically performed between these interfaces. You must define the IP network space that the virtual interface belongs to and the IP address of the interface itself. Also, you must specify the name of the Virtual Hub that the interface will connect to. You can specify a Virtual Hub that currently doesn't exist for the Virtual Hub name. The virtual interface must have one IP address in the Virtual Hub. You also must specify the subnet mask of an IP network that the IP address belongs to. Routing via the Virtual Layer 3 Switches of IP spaces of multiple virtual Hubs operates based on the IP address is specified here. To call this API, you must have VPN Server administrator privileges. Also, this API does not operate on VPN Bridge. To execute this API, the target Virtual Layer 3 Switch must be stopped. If it is not stopped, first use the StopL3Switch API to stop it and then execute this API.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "AddL3If",
+  "params": {
+    "Name_str": "name",
+    "HubName_str": "hubname",
+    "IpAddress_ip": "192.168.0.1",
+    "SubnetMask_ip": "255.255.255.255"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "Name_str": "name",
+    "HubName_str": "hubname",
+    "IpAddress_ip": "192.168.0.1",
+    "SubnetMask_ip": "255.255.255.255"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
Name_strstring (ASCII)L3 switch name
HubName_strstring (ASCII)Virtual HUB name
IpAddress_ipstring (IP address)IP address
SubnetMask_ipstring (IP address)Subnet mask
+
+

+

"DelL3If" RPC API - Delete Virtual Interface of Virtual Layer 3 Switch

+

Description

+

Delete Virtual Interface of Virtual Layer 3 Switch. Use this to delete a virtual interface already defined in the specified Virtual Layer 3 Switch. You can get a list of the virtual interfaces currently defined, by using the EnumL3If API. To call this API, you must have VPN Server administrator privileges. Also, this API does not operate on VPN Bridge. To execute this API, the target Virtual Layer 3 Switch must be stopped. If it is not stopped, first use the StopL3Switch API to stop it and then execute this API.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "DelL3If",
+  "params": {
+    "Name_str": "name",
+    "HubName_str": "hubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "Name_str": "name",
+    "HubName_str": "hubname",
+    "IpAddress_ip": "192.168.0.1",
+    "SubnetMask_ip": "255.255.255.255"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
Name_strstring (ASCII)L3 switch name
HubName_strstring (ASCII)Virtual HUB name
IpAddress_ipstring (IP address)IP address
SubnetMask_ipstring (IP address)Subnet mask
+
+

+

"EnumL3If" RPC API - Get List of Interfaces Registered on the Virtual Layer 3 Switch

+

Description

+

Get List of Interfaces Registered on the Virtual Layer 3 Switch. Use this to get a list of virtual interfaces when virtual interfaces have been defined on a specified Virtual Layer 3 Switch. You can define multiple virtual interfaces and routing tables for a single Virtual Layer 3 Switch. A virtual interface is associated to a virtual Hub and operates as a single IP host on the Virtual Hub when that Virtual Hub is operating. When multiple virtual interfaces that respectively belong to a different IP network of a different Virtual Hub are defined, IP routing will be automatically performed between these interfaces. To call this API, you must have VPN Server administrator privileges. Also, this API does not operate on VPN Bridge.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "EnumL3If",
+  "params": {
+    "Name_str": "name"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "Name_str": "name",
+    "L3IFList": [
+      {
+        "Name_str": "name",
+        "HubName_str": "hubname",
+        "IpAddress_ip": "192.168.0.1",
+        "SubnetMask_ip": "255.255.255.255"
+      },
+      {
+        "Name_str": "name",
+        "HubName_str": "hubname",
+        "IpAddress_ip": "192.168.0.1",
+        "SubnetMask_ip": "255.255.255.255"
+      },
+      {
+        "Name_str": "name",
+        "HubName_str": "hubname",
+        "IpAddress_ip": "192.168.0.1",
+        "SubnetMask_ip": "255.255.255.255"
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
Name_strstring (ASCII)Layer-3 switch name
L3IFListArray objectLayer-3 interface list
Name_strstring (ASCII)L3 switch name
HubName_strstring (ASCII)Virtual HUB name
IpAddress_ipstring (IP address)IP address
SubnetMask_ipstring (IP address)Subnet mask
+
+

+

"AddL3Table" RPC API - Add Routing Table Entry for Virtual Layer 3 Switch

+

Description

+

Add Routing Table Entry for Virtual Layer 3 Switch. Here you can add a new routing table entry to the routing table of the specified Virtual Layer 3 Switch. If the destination IP address of the IP packet does not belong to any IP network that belongs to a virtual interface, the IP routing engine of the Virtual Layer 3 Switch will reference the routing table and execute routing. You must specify the contents of the routing table entry to be added to the Virtual Layer 3 Switch. You must specify any IP address that belongs to the same IP network in the virtual interface of this Virtual Layer 3 Switch as the gateway address. To call this API, you must have VPN Server administrator privileges. Also, this API does not operate on VPN Bridge. To execute this API, the target Virtual Layer 3 Switch must be stopped. If it is not stopped, first use the StopL3Switch API to stop it and then execute this API.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "AddL3Table",
+  "params": {
+    "Name_str": "name",
+    "NetworkAddress_ip": "192.168.0.1",
+    "SubnetMask_ip": "255.255.255.255",
+    "GatewayAddress_ip": "192.168.0.1",
+    "Metric_u32": 0
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "Name_str": "name",
+    "NetworkAddress_ip": "192.168.0.1",
+    "SubnetMask_ip": "255.255.255.255",
+    "GatewayAddress_ip": "192.168.0.1",
+    "Metric_u32": 0
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
Name_strstring (ASCII)L3 switch name
NetworkAddress_ipstring (IP address)Network address
SubnetMask_ipstring (IP address)Subnet mask
GatewayAddress_ipstring (IP address)Gateway address
Metric_u32number (uint32)Metric
+
+

+

"DelL3Table" RPC API - Delete Routing Table Entry of Virtual Layer 3 Switch

+

Description

+

Delete Routing Table Entry of Virtual Layer 3 Switch. Use this to delete a routing table entry that is defined in the specified Virtual Layer 3 Switch. You can get a list of the already defined routing table entries by using the EnumL3Table API. To call this API, you must have VPN Server administrator privileges. Also, this API does not operate on VPN Bridge. To execute this API, the target Virtual Layer 3 Switch must be stopped. If it is not stopped, first use the StopL3Switch API to stop it and then execute this API.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "DelL3Table",
+  "params": {
+    "Name_str": "name",
+    "NetworkAddress_ip": "192.168.0.1",
+    "SubnetMask_ip": "255.255.255.255",
+    "GatewayAddress_ip": "192.168.0.1",
+    "Metric_u32": 0
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "Name_str": "name",
+    "NetworkAddress_ip": "192.168.0.1",
+    "SubnetMask_ip": "255.255.255.255",
+    "GatewayAddress_ip": "192.168.0.1",
+    "Metric_u32": 0
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
Name_strstring (ASCII)L3 switch name
NetworkAddress_ipstring (IP address)Network address
SubnetMask_ipstring (IP address)Subnet mask
GatewayAddress_ipstring (IP address)Gateway address
Metric_u32number (uint32)Metric
+
+

+

"EnumL3Table" RPC API - Get List of Routing Tables of Virtual Layer 3 Switch

+

Description

+

Get List of Routing Tables of Virtual Layer 3 Switch. Use this to get a list of routing tables when routing tables have been defined on a specified Virtual Layer 3 Switch. If the destination IP address of the IP packet does not belong to any IP network that belongs to a virtual interface, the IP routing engine of the Virtual Layer 3 Switch will reference this routing table and execute routing. To call this API, you must have VPN Server administrator privileges. Also, this API does not operate on VPN Bridge.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "EnumL3Table",
+  "params": {
+    "Name_str": "name"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "Name_str": "name",
+    "L3Table": [
+      {
+        "Name_str": "name",
+        "NetworkAddress_ip": "192.168.0.1",
+        "SubnetMask_ip": "255.255.255.255",
+        "GatewayAddress_ip": "192.168.0.1",
+        "Metric_u32": 0
+      },
+      {
+        "Name_str": "name",
+        "NetworkAddress_ip": "192.168.0.1",
+        "SubnetMask_ip": "255.255.255.255",
+        "GatewayAddress_ip": "192.168.0.1",
+        "Metric_u32": 0
+      },
+      {
+        "Name_str": "name",
+        "NetworkAddress_ip": "192.168.0.1",
+        "SubnetMask_ip": "255.255.255.255",
+        "GatewayAddress_ip": "192.168.0.1",
+        "Metric_u32": 0
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
Name_strstring (ASCII)L3 switch name
L3TableArray objectRouting table item list
Name_strstring (ASCII)L3 switch name
NetworkAddress_ipstring (IP address)Network address
SubnetMask_ipstring (IP address)Subnet mask
GatewayAddress_ipstring (IP address)Gateway address
Metric_u32number (uint32)Metric
+
+

+

"EnumCrl" RPC API - Get List of Certificates Revocation List

+

Description

+

Get List of Certificates Revocation List. Use this to get a Certificates Revocation List that is set on the currently managed Virtual Hub. By registering certificates in the Certificates Revocation List, the clients who provide these certificates will be unable to connect to this Virtual Hub using certificate authentication mode. Normally with this function, in cases where the security of a private key has been compromised or where a person holding a certificate has been stripped of their privileges, by registering that certificate as invalid on the Virtual Hub, it is possible to deny user authentication when that certificate is used by a client to connect to the Virtual Hub. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "EnumCrl",
+  "params": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "CRLList": [
+      {
+        "Key_u32": 0,
+        "CrlInfo_utf": "crlinfo"
+      },
+      {
+        "Key_u32": 0,
+        "CrlInfo_utf": "crlinfo"
+      },
+      {
+        "Key_u32": 0,
+        "CrlInfo_utf": "crlinfo"
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
CRLListArray objectCRL list
Key_u32number (uint32)Key ID
CrlInfo_utfstring (UTF8)The contents of the CRL item
+
+

+

"AddCrl" RPC API - Add a Revoked Certificate

+

Description

+

Add a Revoked Certificate. Use this to add a new revoked certificate definition in the Certificate Revocation List that is set on the currently managed Virtual Hub. Specify the contents to be registered in the Certificate Revocation List by using the parameters of this API. When a user connects to a Virtual Hub in certificate authentication mode and that certificate matches 1 or more of the contents registered in the certificates revocation list, the user is denied connection. A certificate that matches all the conditions that are defined by the parameters specified by this API will be judged as invalid. The items that can be set are as follows: Name (CN), Organization (O), Organization Unit (OU), Country (C), State (ST), Locale (L), Serial Number (hexadecimal), MD5 Digest Value (hexadecimal, 128 bit), and SHA-1 Digest Value (hexadecimal, 160 bit). For the specification of a digest value (hash value) a certificate is optionally specified depending on the circumstances. Normally when a MD5 or SHA-1 digest value is input, it is not necessary to input the other items. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "AddCrl",
+  "params": {
+    "HubName_str": "hubname",
+    "CommonName_utf": "commonname",
+    "Organization_utf": "organization",
+    "Unit_utf": "unit",
+    "Country_utf": "country",
+    "State_utf": "state",
+    "Local_utf": "local",
+    "Serial_bin": "SGVsbG8gV29ybGQ=",
+    "DigestMD5_bin": "SGVsbG8gV29ybGQ=",
+    "DigestSHA1_bin": "SGVsbG8gV29ybGQ="
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "Key_u32": 0,
+    "CommonName_utf": "commonname",
+    "Organization_utf": "organization",
+    "Unit_utf": "unit",
+    "Country_utf": "country",
+    "State_utf": "state",
+    "Local_utf": "local",
+    "Serial_bin": "SGVsbG8gV29ybGQ=",
+    "DigestMD5_bin": "SGVsbG8gV29ybGQ=",
+    "DigestSHA1_bin": "SGVsbG8gV29ybGQ="
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
Key_u32number (uint32)Key ID
CommonName_utfstring (UTF8)CN, optional
Organization_utfstring (UTF8)O, optional
Unit_utfstring (UTF8)OU, optional
Country_utfstring (UTF8)C, optional
State_utfstring (UTF8)ST, optional
Local_utfstring (UTF8)L, optional
Serial_binstring (Base64 binary)Serial, optional
DigestMD5_binstring (Base64 binary)MD5 Digest, optional
DigestSHA1_binstring (Base64 binary)SHA1 Digest, optional
+
+

+

"DelCrl" RPC API - Delete a Revoked Certificate

+

Description

+

Delete a Revoked Certificate. Use this to specify and delete a revoked certificate definition from the certificate revocation list that is set on the currently managed Virtual Hub. To get the list of currently registered revoked certificate definitions, use the EnumCrl API. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "DelCrl",
+  "params": {
+    "HubName_str": "hubname",
+    "Key_u32": 0
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "Key_u32": 0,
+    "CommonName_utf": "commonname",
+    "Organization_utf": "organization",
+    "Unit_utf": "unit",
+    "Country_utf": "country",
+    "State_utf": "state",
+    "Local_utf": "local",
+    "Serial_bin": "SGVsbG8gV29ybGQ=",
+    "DigestMD5_bin": "SGVsbG8gV29ybGQ=",
+    "DigestSHA1_bin": "SGVsbG8gV29ybGQ="
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
Key_u32number (uint32)Key ID
CommonName_utfstring (UTF8)CN, optional
Organization_utfstring (UTF8)O, optional
Unit_utfstring (UTF8)OU, optional
Country_utfstring (UTF8)C, optional
State_utfstring (UTF8)ST, optional
Local_utfstring (UTF8)L, optional
Serial_binstring (Base64 binary)Serial, optional
DigestMD5_binstring (Base64 binary)MD5 Digest, optional
DigestSHA1_binstring (Base64 binary)SHA1 Digest, optional
+
+

+

"GetCrl" RPC API - Get a Revoked Certificate

+

Description

+

Get a Revoked Certificate. Use this to specify and get the contents of a revoked certificate definition from the Certificates Revocation List that is set on the currently managed Virtual Hub. To get the list of currently registered revoked certificate definitions, use the EnumCrl API. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetCrl",
+  "params": {
+    "HubName_str": "hubname",
+    "Key_u32": 0
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "Key_u32": 0,
+    "CommonName_utf": "commonname",
+    "Organization_utf": "organization",
+    "Unit_utf": "unit",
+    "Country_utf": "country",
+    "State_utf": "state",
+    "Local_utf": "local",
+    "Serial_bin": "SGVsbG8gV29ybGQ=",
+    "DigestMD5_bin": "SGVsbG8gV29ybGQ=",
+    "DigestSHA1_bin": "SGVsbG8gV29ybGQ="
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
Key_u32number (uint32)Key ID
CommonName_utfstring (UTF8)CN, optional
Organization_utfstring (UTF8)O, optional
Unit_utfstring (UTF8)OU, optional
Country_utfstring (UTF8)C, optional
State_utfstring (UTF8)ST, optional
Local_utfstring (UTF8)L, optional
Serial_binstring (Base64 binary)Serial, optional
DigestMD5_binstring (Base64 binary)MD5 Digest, optional
DigestSHA1_binstring (Base64 binary)SHA1 Digest, optional
+
+

+

"SetCrl" RPC API - Change Existing CRL (Certificate Revocation List) Entry

+

Description

+

Change Existing CRL (Certificate Revocation List) Entry. Use this to alter an existing revoked certificate definition in the Certificate Revocation List that is set on the currently managed Virtual Hub. Specify the contents to be registered in the Certificate Revocation List by using the parameters of this API. When a user connects to a Virtual Hub in certificate authentication mode and that certificate matches 1 or more of the contents registered in the certificates revocation list, the user is denied connection. A certificate that matches all the conditions that are defined by the parameters specified by this API will be judged as invalid. The items that can be set are as follows: Name (CN), Organization (O), Organization Unit (OU), Country (C), State (ST), Locale (L), Serial Number (hexadecimal), MD5 Digest Value (hexadecimal, 128 bit), and SHA-1 Digest Value (hexadecimal, 160 bit). For the specification of a digest value (hash value) a certificate is optionally specified depending on the circumstances. Normally when a MD5 or SHA-1 digest value is input, it is not necessary to input the other items. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetCrl",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "Key_u32": 0,
+    "CommonName_utf": "commonname",
+    "Organization_utf": "organization",
+    "Unit_utf": "unit",
+    "Country_utf": "country",
+    "State_utf": "state",
+    "Local_utf": "local",
+    "Serial_bin": "SGVsbG8gV29ybGQ=",
+    "DigestMD5_bin": "SGVsbG8gV29ybGQ=",
+    "DigestSHA1_bin": "SGVsbG8gV29ybGQ="
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
Key_u32number (uint32)Key ID
CommonName_utfstring (UTF8)CN, optional
Organization_utfstring (UTF8)O, optional
Unit_utfstring (UTF8)OU, optional
Country_utfstring (UTF8)C, optional
State_utfstring (UTF8)ST, optional
Local_utfstring (UTF8)L, optional
Serial_binstring (Base64 binary)Serial, optional
DigestMD5_binstring (Base64 binary)MD5 Digest, optional
DigestSHA1_binstring (Base64 binary)SHA1 Digest, optional
+
+

+

"SetAcList" RPC API - Add Rule to Source IP Address Limit List

+

Description

+

Add Rule to Source IP Address Limit List. Use this to add a new rule to the Source IP Address Limit List that is set on the currently managed Virtual Hub. The items set here will be used to decide whether to allow or deny connection from a VPN Client when this client attempts connection to the Virtual Hub. You can specify a client IP address, or IP address or mask to match the rule as the contents of the rule item. By specifying an IP address only, there will only be one specified computer that will match the rule, but by specifying an IP net mask address or subnet mask address, all the computers in the range of that subnet will match the rule. You can specify the priority for the rule. You can specify an integer of 1 or greater for the priority and the smaller the number, the higher the priority. To get a list of the currently registered Source IP Address Limit List, use the GetAcList API. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetAcList",
+  "params": {
+    "HubName_str": "hubname",
+    "ACList": [
+      {
+        "Id_u32": 0,
+        "Priority_u32": 0,
+        "Deny_bool": false,
+        "Masked_bool": false,
+        "IpAddress_ip": "192.168.0.1",
+        "SubnetMask_ip": "255.255.255.255"
+      },
+      {
+        "Id_u32": 0,
+        "Priority_u32": 0,
+        "Deny_bool": false,
+        "Masked_bool": false,
+        "IpAddress_ip": "192.168.0.1",
+        "SubnetMask_ip": "255.255.255.255"
+      },
+      {
+        "Id_u32": 0,
+        "Priority_u32": 0,
+        "Deny_bool": false,
+        "Masked_bool": false,
+        "IpAddress_ip": "192.168.0.1",
+        "SubnetMask_ip": "255.255.255.255"
+      }
+    ]
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "ACList": [
+      {
+        "Id_u32": 0,
+        "Priority_u32": 0,
+        "Deny_bool": false,
+        "Masked_bool": false,
+        "IpAddress_ip": "192.168.0.1",
+        "SubnetMask_ip": "255.255.255.255"
+      },
+      {
+        "Id_u32": 0,
+        "Priority_u32": 0,
+        "Deny_bool": false,
+        "Masked_bool": false,
+        "IpAddress_ip": "192.168.0.1",
+        "SubnetMask_ip": "255.255.255.255"
+      },
+      {
+        "Id_u32": 0,
+        "Priority_u32": 0,
+        "Deny_bool": false,
+        "Masked_bool": false,
+        "IpAddress_ip": "192.168.0.1",
+        "SubnetMask_ip": "255.255.255.255"
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
ACListArray objectSource IP Address Limit List
Id_u32number (uint32)ID
Priority_u32number (uint32)Priority
Deny_boolbooleanDeny access
Masked_boolbooleanSet true if you want to specify the SubnetMask_ip item.
IpAddress_ipstring (IP address)IP address
SubnetMask_ipstring (IP address)Subnet mask, valid only if Masked_bool == true
+
+

+

"GetAcList" RPC API - Get List of Rule Items of Source IP Address Limit List

+

Description

+

Get List of Rule Items of Source IP Address Limit List. Use this to get a list of Source IP Address Limit List rules that is set on the currently managed Virtual Hub. You can allow or deny VPN connections to this Virtual Hub according to the client computer's source IP address. You can define multiple rules and set a priority for each rule. The search proceeds from the rule with the highest order or priority and based on the action of the rule that the IP address first matches, the connection from the client is either allowed or denied. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetAcList",
+  "params": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "ACList": [
+      {
+        "Id_u32": 0,
+        "Priority_u32": 0,
+        "Deny_bool": false,
+        "Masked_bool": false,
+        "IpAddress_ip": "192.168.0.1",
+        "SubnetMask_ip": "255.255.255.255"
+      },
+      {
+        "Id_u32": 0,
+        "Priority_u32": 0,
+        "Deny_bool": false,
+        "Masked_bool": false,
+        "IpAddress_ip": "192.168.0.1",
+        "SubnetMask_ip": "255.255.255.255"
+      },
+      {
+        "Id_u32": 0,
+        "Priority_u32": 0,
+        "Deny_bool": false,
+        "Masked_bool": false,
+        "IpAddress_ip": "192.168.0.1",
+        "SubnetMask_ip": "255.255.255.255"
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
ACListArray objectSource IP Address Limit List
Id_u32number (uint32)ID
Priority_u32number (uint32)Priority
Deny_boolbooleanDeny access
Masked_boolbooleanSet true if you want to specify the SubnetMask_ip item.
IpAddress_ipstring (IP address)IP address
SubnetMask_ipstring (IP address)Subnet mask, valid only if Masked_bool == true
+
+

+

"EnumLogFile" RPC API - Get List of Log Files

+

Description

+

Get List of Log Files. Use this to display a list of log files outputted by the VPN Server that have been saved on the VPN Server computer. By specifying a log file file name displayed here and calling it using the ReadLogFile API you can download the contents of the log file. If you are connected to the VPN Server in server admin mode, you can display or download the packet logs and security logs of all Virtual Hubs and the server log of the VPN Server. When connected in Virtual Hub Admin Mode, you are able to view or download only the packet log and security log of the Virtual Hub that is the target of management.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "EnumLogFile",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "LogFiles": [
+      {
+        "ServerName_str": "servername",
+        "FilePath_str": "filepath",
+        "FileSize_u32": 0,
+        "UpdatedTime_dt": "2020-08-01T12:24:36.123"
+      },
+      {
+        "ServerName_str": "servername",
+        "FilePath_str": "filepath",
+        "FileSize_u32": 0,
+        "UpdatedTime_dt": "2020-08-01T12:24:36.123"
+      },
+      {
+        "ServerName_str": "servername",
+        "FilePath_str": "filepath",
+        "FileSize_u32": 0,
+        "UpdatedTime_dt": "2020-08-01T12:24:36.123"
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
LogFilesArray objectLog file list
ServerName_strstring (ASCII)Server name
FilePath_strstring (ASCII)File path
FileSize_u32number (uint32)File size
UpdatedTime_dtDateLast write date
+
+

+

"ReadLogFile" RPC API - Download a part of Log File

+

Description

+

Download a part of Log File. Use this to download the log file that is saved on the VPN Server computer. To download the log file first get the list of log files using the EnumLogFile API and then download the log file using the ReadLogFile API. If you are connected to the VPN Server in server admin mode, you can display or download the packet logs and security logs of all Virtual Hubs and the server log of the VPN Server. When connected in Virtual Hub Admin Mode, you are able to view or download only the packet log and security log of the Virtual Hub that is the target of management.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "ReadLogFile",
+  "params": {
+    "FilePath_str": "filepath"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "ServerName_str": "servername",
+    "FilePath_str": "filepath",
+    "Offset_u32": 0,
+    "Buffer_bin": "SGVsbG8gV29ybGQ="
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
ServerName_strstring (ASCII)Server name
FilePath_strstring (ASCII)File Path
Offset_u32number (uint32)Offset to download. You have to call the ReadLogFile API multiple times to download the entire log file with requesting a part of the file by specifying the Offset_u32 field.
Buffer_binstring (Base64 binary)Received buffer
+
+

+

"SetSysLog" RPC API - Set syslog Send Function

+

Description

+

Set syslog Send Function. Use this to set the usage of syslog send function and which syslog server to use.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetSysLog",
+  "params": {
+    "SaveType_u32": 0,
+    "Hostname_str": "hostname",
+    "Port_u32": 0
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "SaveType_u32": 0,
+    "Hostname_str": "hostname",
+    "Port_u32": 0
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
SaveType_u32number (enum)The behavior of the syslog function
Values:
0: Do not use syslog
1: Only server log
2: Server and Virtual HUB security log
3: Server, Virtual HUB security, and packet log
Hostname_strstring (ASCII)Specify the host name or IP address of the syslog server
Port_u32number (uint32)Specify the port number of the syslog server
+
+

+

"GetSysLog" RPC API - Get syslog Send Function

+

Description

+

Get syslog Send Function. This allows you to get the current setting contents of the syslog send function. You can get the usage setting of the syslog function and the host name and port number of the syslog server to use.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetSysLog",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "SaveType_u32": 0,
+    "Hostname_str": "hostname",
+    "Port_u32": 0
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
SaveType_u32number (enum)The behavior of the syslog function
Values:
0: Do not use syslog
1: Only server log
2: Server and Virtual HUB security log
3: Server, Virtual HUB security, and packet log
Hostname_strstring (ASCII)Specify the host name or IP address of the syslog server
Port_u32number (uint32)Specify the port number of the syslog server
+
+

+

"SetHubMsg" RPC API - Set Today's Message of Virtual Hub

+

Description

+

Set Today's Message of Virtual Hub. The message will be displayed on VPN Client UI when a user will establish a connection to the Virtual Hub.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetHubMsg",
+  "params": {
+    "HubName_str": "hubname",
+    "Msg_bin": "SGVsbG8gV29ybGQ="
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "Msg_bin": "SGVsbG8gV29ybGQ="
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
Msg_binstring (Base64 binary)Message (Unicode strings acceptable)
+
+

+

"GetHubMsg" RPC API - Get Today's Message of Virtual Hub

+

Description

+

Get Today's Message of Virtual Hub. The message will be displayed on VPN Client UI when a user will establish a connection to the Virtual Hub.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetHubMsg",
+  "params": {
+    "HubName_str": "hubname"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "Msg_bin": "SGVsbG8gV29ybGQ="
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
Msg_binstring (Base64 binary)Message (Unicode strings acceptable)
+
+

+

"Crash" RPC API - Raise a vital error on the VPN Server / Bridge to terminate the process forcefully

+

Description

+

Raise a vital error on the VPN Server / Bridge to terminate the process forcefully. This API will raise a fatal error (memory access violation) on the VPN Server / Bridge running process in order to crash the process. As the result, VPN Server / Bridge will be terminated and restarted if it is running as a service mode. If the VPN Server is running as a user mode, the process will not automatically restarted. This API is for a situation when the VPN Server / Bridge is under a non-recoverable error or the process is in an infinite loop. This API will disconnect all VPN Sessions on the VPN Server / Bridge. All unsaved settings in the memory of VPN Server / Bridge will be lost. Before run this API, call the Flush API to try to save volatile data to the configuration file. To execute this API, you must have VPN Server / VPN Bridge administrator privileges.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "Crash",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "IntValue_u32": 0,
+    "Int64Value_u64": 0,
+    "StrValue_str": "strvalue",
+    "UniStrValue_utf": "unistrvalue"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
IntValue_u32number (uint32)A 32-bit integer field
Int64Value_u64number (uint64)A 64-bit integer field
StrValue_strstring (ASCII)An Ascii string field
UniStrValue_utfstring (UTF8)An UTF-8 string field
+
+

+

"GetAdminMsg" RPC API - Get the message for administrators

+

Description

+

Get the message for administrators.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetAdminMsg",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "HubName_str": "hubname",
+    "Msg_bin": "SGVsbG8gV29ybGQ="
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
HubName_strstring (ASCII)The Virtual Hub name
Msg_binstring (Base64 binary)Message (Unicode strings acceptable)
+
+

+

"Flush" RPC API - Save All Volatile Data of VPN Server / Bridge to the Configuration File

+

Description

+

Save All Volatile Data of VPN Server / Bridge to the Configuration File. The number of configuration file bytes will be returned as the "IntValue" parameter. Normally, the VPN Server / VPN Bridge retains the volatile configuration data in memory. It is flushed to the disk as vpn_server.config or vpn_bridge.config periodically. The period is 300 seconds (5 minutes) by default. (The period can be altered by modifying the AutoSaveConfigSpan item in the configuration file.) The data will be saved on the timing of shutting down normally of the VPN Server / Bridge. Execute the Flush API to make the VPN Server / Bridge save the settings to the file immediately. The setting data will be stored on the disk drive of the server computer. Use the Flush API in a situation that you do not have an enough time to shut down the server process normally. To call this API, you must have VPN Server administrator privileges. To execute this API, you must have VPN Server / VPN Bridge administrator privileges.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "Flush",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "IntValue_u32": 0,
+    "Int64Value_u64": 0,
+    "StrValue_str": "strvalue",
+    "UniStrValue_utf": "unistrvalue"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
IntValue_u32number (uint32)A 32-bit integer field
Int64Value_u64number (uint64)A 64-bit integer field
StrValue_strstring (ASCII)An Ascii string field
UniStrValue_utfstring (UTF8)An UTF-8 string field
+
+

+

"SetIPsecServices" RPC API - Enable or Disable IPsec VPN Server Function

+

Description

+

Enable or Disable IPsec VPN Server Function. Enable or Disable IPsec VPN Server Function on the VPN Server. If you enable this function, Virtual Hubs on the VPN Server will be able to accept Remote-Access VPN connections from L2TP-compatible PCs, Mac OS X and Smartphones, and also can accept EtherIP Site-to-Site VPN Connection. VPN Connections from Smartphones suchlike iPhone, iPad and Android, and also from native VPN Clients on Mac OS X and Windows can be accepted. To call this API, you must have VPN Server administrator privileges. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetIPsecServices",
+  "params": {
+    "L2TP_Raw_bool": false,
+    "L2TP_IPsec_bool": false,
+    "EtherIP_IPsec_bool": false,
+    "IPsec_Secret_str": "ipsec_secret",
+    "L2TP_DefaultHub_str": "l2tp_defaulthub"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "L2TP_Raw_bool": false,
+    "L2TP_IPsec_bool": false,
+    "EtherIP_IPsec_bool": false,
+    "IPsec_Secret_str": "ipsec_secret",
+    "L2TP_DefaultHub_str": "l2tp_defaulthub"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
L2TP_Raw_boolbooleanEnable or Disable the L2TP Server Function (Raw L2TP with No Encryptions). To accept special VPN clients, enable this option.
L2TP_IPsec_boolbooleanEnable or Disable the L2TP over IPsec Server Function. To accept VPN connections from iPhone, iPad, Android, Windows or Mac OS X, enable this option.
EtherIP_IPsec_boolbooleanEnable or Disable the EtherIP / L2TPv3 over IPsec Server Function (for site-to-site VPN Server function). Router Products which are compatible with EtherIP over IPsec can connect to Virtual Hubs on the VPN Server and establish Layer-2 (Ethernet) Bridging.
IPsec_Secret_strstring (ASCII)Specify the IPsec Pre-Shared Key. An IPsec Pre-Shared Key is also called as "PSK" or "secret". Specify it equal or less than 8 letters, and distribute it to every users who will connect to the VPN Server. Please note: Google Android 4.0 has a bug which a Pre-Shared Key with 10 or more letters causes a unexpected behavior. For that reason, the letters of a Pre-Shared Key should be 9 or less characters.
L2TP_DefaultHub_strstring (ASCII)Specify the default Virtual HUB in a case of omitting the name of HUB on the Username. Users should specify their username such as "Username@Target Virtual HUB Name" to connect this L2TP Server. If the designation of the Virtual Hub is omitted, the above HUB will be used as the target.
+
+

+

"GetIPsecServices" RPC API - Get the Current IPsec VPN Server Settings

+

Description

+

Get the Current IPsec VPN Server Settings. Get and view the current IPsec VPN Server settings on the VPN Server. To call this API, you must have VPN Server administrator privileges. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetIPsecServices",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "L2TP_Raw_bool": false,
+    "L2TP_IPsec_bool": false,
+    "EtherIP_IPsec_bool": false,
+    "IPsec_Secret_str": "ipsec_secret",
+    "L2TP_DefaultHub_str": "l2tp_defaulthub"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
L2TP_Raw_boolbooleanEnable or Disable the L2TP Server Function (Raw L2TP with No Encryptions). To accept special VPN clients, enable this option.
L2TP_IPsec_boolbooleanEnable or Disable the L2TP over IPsec Server Function. To accept VPN connections from iPhone, iPad, Android, Windows or Mac OS X, enable this option.
EtherIP_IPsec_boolbooleanEnable or Disable the EtherIP / L2TPv3 over IPsec Server Function (for site-to-site VPN Server function). Router Products which are compatible with EtherIP over IPsec can connect to Virtual Hubs on the VPN Server and establish Layer-2 (Ethernet) Bridging.
IPsec_Secret_strstring (ASCII)Specify the IPsec Pre-Shared Key. An IPsec Pre-Shared Key is also called as "PSK" or "secret". Specify it equal or less than 8 letters, and distribute it to every users who will connect to the VPN Server. Please note: Google Android 4.0 has a bug which a Pre-Shared Key with 10 or more letters causes a unexpected behavior. For that reason, the letters of a Pre-Shared Key should be 9 or less characters.
L2TP_DefaultHub_strstring (ASCII)Specify the default Virtual HUB in a case of omitting the name of HUB on the Username. Users should specify their username such as "Username@Target Virtual HUB Name" to connect this L2TP Server. If the designation of the Virtual Hub is omitted, the above HUB will be used as the target.
+
+

+

"AddEtherIpId" RPC API - Add New EtherIP / L2TPv3 over IPsec Client Setting to Accept EthreIP / L2TPv3 Client Devices

+

Description

+

Add New EtherIP / L2TPv3 over IPsec Client Setting to Accept EthreIP / L2TPv3 Client Devices. Add a new setting entry to enable the EtherIP / L2TPv3 over IPsec Server Function to accept client devices. In order to accept connections from routers by the EtherIP / L2TPv3 over IPsec Server Function, you have to define the relation table between an IPsec Phase 1 string which is presented by client devices of EtherIP / L2TPv3 over IPsec compatible router, and the designation of the destination Virtual Hub. After you add a definition entry by AddEtherIpId API, the defined connection setting to the Virtual Hub will be applied on the login-attepting session from an EtherIP / L2TPv3 over IPsec client device. The username and password in an entry must be registered on the Virtual Hub. An EtherIP / L2TPv3 client will be regarded as it connected the Virtual HUB with the identification of the above user information. To call this API, you must have VPN Server administrator privileges. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "AddEtherIpId",
+  "params": {
+    "Id_str": "id",
+    "HubName_str": "hubname",
+    "UserName_str": "username",
+    "Password_str": "password"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "Id_str": "id",
+    "HubName_str": "hubname",
+    "UserName_str": "username",
+    "Password_str": "password"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
Id_strstring (ASCII)Specify an ISAKMP Phase 1 ID. The ID must be exactly same as a ID in the configuration of the EtherIP / L2TPv3 Client. You can specify IP address as well as characters as ID, if the EtherIP Client uses IP address as Phase 1 ID. If you specify '*' (asterisk), it will be a wildcard to match any clients which doesn't match other explicit rules.
HubName_strstring (ASCII)Specify the name of the Virtual Hub to connect.
UserName_strstring (ASCII)Specify the username to login to the destination Virtual Hub.
Password_strstring (ASCII)Specify the password to login to the destination Virtual Hub.
+
+

+

"GetEtherIpId" RPC API - Get the Current List of EtherIP / L2TPv3 Client Device Entry Definitions

+

Description

+

Get the Current List of EtherIP / L2TPv3 Client Device Entry Definitions. This API gets and shows the list of entries to accept VPN clients by EtherIP / L2TPv3 over IPsec Function. To call this API, you must have VPN Server administrator privileges. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetEtherIpId",
+  "params": {
+    "Id_str": "id"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "Id_str": "id",
+    "HubName_str": "hubname",
+    "UserName_str": "username",
+    "Password_str": "password"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
Id_strstring (ASCII)Specify an ISAKMP Phase 1 ID. The ID must be exactly same as a ID in the configuration of the EtherIP / L2TPv3 Client. You can specify IP address as well as characters as ID, if the EtherIP Client uses IP address as Phase 1 ID. If you specify '*' (asterisk), it will be a wildcard to match any clients which doesn't match other explicit rules.
HubName_strstring (ASCII)Specify the name of the Virtual Hub to connect.
UserName_strstring (ASCII)Specify the username to login to the destination Virtual Hub.
Password_strstring (ASCII)Specify the password to login to the destination Virtual Hub.
+
+

+

"DeleteEtherIpId" RPC API - Delete an EtherIP / L2TPv3 over IPsec Client Setting

+

Description

+

Delete an EtherIP / L2TPv3 over IPsec Client Setting. This API deletes an entry to accept VPN clients by EtherIP / L2TPv3 over IPsec Function. To call this API, you must have VPN Server administrator privileges. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "DeleteEtherIpId",
+  "params": {
+    "Id_str": "id"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "Id_str": "id",
+    "HubName_str": "hubname",
+    "UserName_str": "username",
+    "Password_str": "password"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
Id_strstring (ASCII)Specify an ISAKMP Phase 1 ID. The ID must be exactly same as a ID in the configuration of the EtherIP / L2TPv3 Client. You can specify IP address as well as characters as ID, if the EtherIP Client uses IP address as Phase 1 ID. If you specify '*' (asterisk), it will be a wildcard to match any clients which doesn't match other explicit rules.
HubName_strstring (ASCII)Specify the name of the Virtual Hub to connect.
UserName_strstring (ASCII)Specify the username to login to the destination Virtual Hub.
Password_strstring (ASCII)Specify the password to login to the destination Virtual Hub.
+
+

+

"EnumEtherIpId" RPC API - Get the Current List of EtherIP / L2TPv3 Client Device Entry Definitions

+

Description

+

Get the Current List of EtherIP / L2TPv3 Client Device Entry Definitions. This API gets and shows the list of entries to accept VPN clients by EtherIP / L2TPv3 over IPsec Function. To call this API, you must have VPN Server administrator privileges. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "EnumEtherIpId",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "Settings": [
+      {
+        "Id_str": "id",
+        "HubName_str": "hubname",
+        "UserName_str": "username",
+        "Password_str": "password"
+      },
+      {
+        "Id_str": "id",
+        "HubName_str": "hubname",
+        "UserName_str": "username",
+        "Password_str": "password"
+      },
+      {
+        "Id_str": "id",
+        "HubName_str": "hubname",
+        "UserName_str": "username",
+        "Password_str": "password"
+      }
+    ]
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
SettingsArray objectSetting list
Id_strstring (ASCII)Specify an ISAKMP Phase 1 ID. The ID must be exactly same as a ID in the configuration of the EtherIP / L2TPv3 Client. You can specify IP address as well as characters as ID, if the EtherIP Client uses IP address as Phase 1 ID. If you specify '*' (asterisk), it will be a wildcard to match any clients which doesn't match other explicit rules.
HubName_strstring (ASCII)Specify the name of the Virtual Hub to connect.
UserName_strstring (ASCII)Specify the username to login to the destination Virtual Hub.
Password_strstring (ASCII)Specify the password to login to the destination Virtual Hub.
+
+

+

"SetOpenVpnSstpConfig" RPC API - Set Settings for OpenVPN Clone Server Function

+

Description

+

Set Settings for OpenVPN Clone Server Function. The VPN Server has the clone functions of OpenVPN software products by OpenVPN Technologies, Inc. Any OpenVPN Clients can connect to this VPN Server. The manner to specify a username to connect to the Virtual Hub, and the selection rule of default Hub by using this clone server functions are same to the IPsec Server functions. To call this API, you must have VPN Server administrator privileges. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetOpenVpnSstpConfig",
+  "params": {
+    "EnableOpenVPN_bool": false,
+    "OpenVPNPortList_str": "openvpnportlist",
+    "EnableSSTP_bool": false
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "EnableOpenVPN_bool": false,
+    "OpenVPNPortList_str": "openvpnportlist",
+    "EnableSSTP_bool": false
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
EnableOpenVPN_boolbooleanSpecify true to enable the OpenVPN Clone Server Function. Specify false to disable.
OpenVPNPortList_strstring (ASCII)Specify UDP ports to listen for OpenVPN. Multiple UDP ports can be specified with splitting by space or comma letters, for example: "1194, 2001, 2010, 2012". The default port for OpenVPN is UDP 1194. You can specify any other UDP ports.
EnableSSTP_boolbooleanpecify true to enable the Microsoft SSTP VPN Clone Server Function. Specify false to disable.
+
+

+

"GetOpenVpnSstpConfig" RPC API - Get the Current Settings of OpenVPN Clone Server Function

+

Description

+

Get the Current Settings of OpenVPN Clone Server Function. Get and show the current settings of OpenVPN Clone Server Function. To call this API, you must have VPN Server administrator privileges. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetOpenVpnSstpConfig",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "EnableOpenVPN_bool": false,
+    "OpenVPNPortList_str": "openvpnportlist",
+    "EnableSSTP_bool": false
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
EnableOpenVPN_boolbooleanSpecify true to enable the OpenVPN Clone Server Function. Specify false to disable.
OpenVPNPortList_strstring (ASCII)Specify UDP ports to listen for OpenVPN. Multiple UDP ports can be specified with splitting by space or comma letters, for example: "1194, 2001, 2010, 2012". The default port for OpenVPN is UDP 1194. You can specify any other UDP ports.
EnableSSTP_boolbooleanpecify true to enable the Microsoft SSTP VPN Clone Server Function. Specify false to disable.
+
+

+

"GetDDnsClientStatus" RPC API - Show the Current Status of Dynamic DNS Function

+

Description

+

Show the Current Status of Dynamic DNS Function. Get and show the current status of the Dynamic DNS function. The Dynamic DNS assigns a unique and permanent DNS hostname for this VPN Server. You can use that hostname to specify this VPN Server on the settings for VPN Client and VPN Bridge. You need not to register and keep a domain name. Also, if your ISP assignes you a dynamic (not-fixed) IP address, the corresponding IP address of your Dynamic DNS hostname will be automatically changed. It enables you to keep running the VPN Server by using only a dynamic IP address. Therefore, you need not any longer to keep static global IP addresses with expenses monthly costs. [Caution] To disable the Dynamic DNS Function, modify the configuration file of VPN Server. The "declare root" directive has the "declare DDnsClient" directive. In this directive, you can switch "bool Disable" from false to true, and reboot the VPN Server, then the Dynamic DNS Function will be disabled. To call this API, you must have VPN Server administrator privileges. This API cannot be invoked on VPN Bridge.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetDDnsClientStatus",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "Err_IPv4_u32": 0,
+    "ErrStr_IPv4_utf": "errstr_ipv4",
+    "Err_IPv6_u32": 0,
+    "ErrStr_IPv6_utf": "errstr_ipv6",
+    "CurrentHostName_str": "currenthostname",
+    "CurrentFqdn_str": "currentfqdn",
+    "DnsSuffix_str": "dnssuffix",
+    "CurrentIPv4_str": "currentipv4",
+    "CurrentIPv6_str": "currentipv6"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
Err_IPv4_u32number (uint32)Last error code (IPv4)
ErrStr_IPv4_utfstring (UTF8)Last error string (IPv4)
Err_IPv6_u32number (uint32)Last error code (IPv6)
ErrStr_IPv6_utfstring (UTF8)Last error string (IPv6)
CurrentHostName_strstring (ASCII)Current DDNS host name
CurrentFqdn_strstring (ASCII)Current FQDN of the DDNS hostname
DnsSuffix_strstring (ASCII)DDNS suffix
CurrentIPv4_strstring (ASCII)Current IPv4 address of the VPN Server
CurrentIPv6_strstring (ASCII)Current IPv6 address of the VPN Server
+
+

+

"ChangeDDnsClientHostname" RPC API - Set the Dynamic DNS Hostname

+

Description

+

Set the Dynamic DNS Hostname. You must specify the new hostname on the StrValue_str field. You can use this API to change the hostname assigned by the Dynamic DNS function. The currently assigned hostname can be showen by the GetDDnsClientStatus API. The Dynamic DNS assigns a unique and permanent DNS hostname for this VPN Server. You can use that hostname to specify this VPN Server on the settings for VPN Client and VPN Bridge. You need not to register and keep a domain name. Also, if your ISP assignes you a dynamic (not-fixed) IP address, the corresponding IP address of your Dynamic DNS hostname will be automatically changed. It enables you to keep running the VPN Server by using only a dynamic IP address. Therefore, you need not any longer to keep static global IP addresses with expenses monthly costs. [Caution] To disable the Dynamic DNS Function, modify the configuration file of VPN Server. The "declare root" directive has the "declare DDnsClient" directive. In this directive, you can switch "bool Disable" from false to true, and reboot the VPN Server, then the Dynamic DNS Function will be disabled. To call this API, you must have VPN Server administrator privileges. This API cannot be invoked on VPN Bridge.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "ChangeDDnsClientHostname",
+  "params": {
+    "StrValue_str": "strvalue"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "IntValue_u32": 0,
+    "Int64Value_u64": 0,
+    "StrValue_str": "strvalue",
+    "UniStrValue_utf": "unistrvalue"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
IntValue_u32number (uint32)A 32-bit integer field
Int64Value_u64number (uint64)A 64-bit integer field
StrValue_strstring (ASCII)An Ascii string field
UniStrValue_utfstring (UTF8)An UTF-8 string field
+
+

+

"RegenerateServerCert" RPC API - Generate New Self-Signed Certificate with Specified CN (Common Name) and Register on VPN Server

+

Description

+

Generate New Self-Signed Certificate with Specified CN (Common Name) and Register on VPN Server. You can specify the new CN (common name) value on the StrValue_str field. You can use this API to replace the current certificate on the VPN Server to a new self-signed certificate which has the CN (Common Name) value in the fields. This API is convenient if you are planning to use Microsoft SSTP VPN Clone Server Function. Because of the value of CN (Common Name) on the SSL certificate of VPN Server must match to the hostname specified on the SSTP VPN client. This API will delete the existing SSL certificate of the VPN Server. It is recommended to backup the current SSL certificate and private key by using the GetServerCert API beforehand. To call this API, you must have VPN Server administrator privileges. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "RegenerateServerCert",
+  "params": {
+    "StrValue_str": "strvalue"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "IntValue_u32": 0,
+    "Int64Value_u64": 0,
+    "StrValue_str": "strvalue",
+    "UniStrValue_utf": "unistrvalue"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
IntValue_u32number (uint32)A 32-bit integer field
Int64Value_u64number (uint64)A 64-bit integer field
StrValue_strstring (ASCII)An Ascii string field
UniStrValue_utfstring (UTF8)An UTF-8 string field
+
+

+

"MakeOpenVpnConfigFile" RPC API - Generate a Sample Setting File for OpenVPN Client

+

Description

+

Generate a Sample Setting File for OpenVPN Client. Originally, the OpenVPN Client requires a user to write a very difficult configuration file manually. This API helps you to make a useful configuration sample. What you need to generate the configuration file for the OpenVPN Client is to run this API. To call this API, you must have VPN Server administrator privileges. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "MakeOpenVpnConfigFile",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "ServerName_str": "servername",
+    "FilePath_str": "filepath",
+    "Offset_u32": 0,
+    "Buffer_bin": "SGVsbG8gV29ybGQ="
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
ServerName_strstring (ASCII)Server name
FilePath_strstring (ASCII)File Path
Offset_u32number (uint32)Offset to download. You have to call the ReadLogFile API multiple times to download the entire log file with requesting a part of the file by specifying the Offset_u32 field.
Buffer_binstring (Base64 binary)Received buffer
+
+

+

"SetSpecialListener" RPC API - Enable / Disable the VPN over ICMP / VPN over DNS Server Function

+

Description

+

Enable / Disable the VPN over ICMP / VPN over DNS Server Function. You can establish a VPN only with ICMP or DNS packets even if there is a firewall or routers which blocks TCP/IP communications. You have to enable the following functions beforehand. Warning: Use this function for emergency only. It is helpful when a firewall or router is misconfigured to blocks TCP/IP, but either ICMP or DNS is not blocked. It is not for long-term stable using. To call this API, you must have VPN Server administrator privileges. This API cannot be invoked on VPN Bridge.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetSpecialListener",
+  "params": {
+    "VpnOverIcmpListener_bool": false,
+    "VpnOverDnsListener_bool": false
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "VpnOverIcmpListener_bool": false,
+    "VpnOverDnsListener_bool": false
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
VpnOverIcmpListener_boolbooleanThe flag to activate the VPN over ICMP server function
VpnOverDnsListener_boolbooleanThe flag to activate the VPN over DNS function
+
+

+

"GetSpecialListener" RPC API - Get Current Setting of the VPN over ICMP / VPN over DNS Function

+

Description

+

Get Current Setting of the VPN over ICMP / VPN over DNS Function. Get and show the current VPN over ICMP / VPN over DNS Function status. To call this API, you must have VPN Server administrator privileges. This API cannot be invoked on VPN Bridge.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetSpecialListener",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "VpnOverIcmpListener_bool": false,
+    "VpnOverDnsListener_bool": false
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
VpnOverIcmpListener_boolbooleanThe flag to activate the VPN over ICMP server function
VpnOverDnsListener_boolbooleanThe flag to activate the VPN over DNS function
+
+

+

"GetAzureStatus" RPC API - Show the current status of VPN Azure function

+

Description

+

Show the current status of VPN Azure function. Get and show the current status of the VPN Azure function. VPN Azure makes it easier to establish a VPN Session from your home PC to your office PC. While a VPN connection is established, you can access to any other servers on the private network of your company. You don't need a global IP address on the office PC (VPN Server). It can work behind firewalls or NATs. No network administrator's configuration required. You can use the built-in SSTP-VPN Client of Windows in your home PC. VPN Azure is a cloud VPN service operated by SoftEther Corporation. VPN Azure is free of charge and available to anyone. Visit http://www.vpnazure.net/ to see details and how-to-use instructions. The VPN Azure hostname is same to the hostname of the Dynamic DNS setting, but altering the domain suffix to "vpnazure.net". To change the hostname use the ChangeDDnsClientHostname API. To call this API, you must have VPN Server administrator privileges. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetAzureStatus",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "IsEnabled_bool": false,
+    "IsConnected_bool": false
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
IsEnabled_boolbooleanWhether VPN Azure Function is Enabled
IsConnected_boolbooleanWhether connection to VPN Azure Cloud Server is established
+
+

+

"SetAzureStatus" RPC API - Enable / Disable VPN Azure Function

+

Description

+

Enable / Disable VPN Azure Function. Enable or disable the VPN Azure function. VPN Azure makes it easier to establish a VPN Session from your home PC to your office PC. While a VPN connection is established, you can access to any other servers on the private network of your company. You don't need a global IP address on the office PC (VPN Server). It can work behind firewalls or NATs. No network administrator's configuration required. You can use the built-in SSTP-VPN Client of Windows in your home PC. VPN Azure is a cloud VPN service operated by SoftEther Corporation. VPN Azure is free of charge and available to anyone. Visit http://www.vpnazure.net/ to see details and how-to-use instructions. The VPN Azure hostname is same to the hostname of the Dynamic DNS setting, but altering the domain suffix to "vpnazure.net". To change the hostname use the ChangeDDnsClientHostname API. To call this API, you must have VPN Server administrator privileges. This API cannot be invoked on VPN Bridge. You cannot execute this API for Virtual Hubs of VPN Servers operating as a cluster.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetAzureStatus",
+  "params": {
+    "IsEnabled_bool": false
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "IsEnabled_bool": false,
+    "IsConnected_bool": false
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
IsEnabled_boolbooleanWhether VPN Azure Function is Enabled
IsConnected_boolbooleanWhether connection to VPN Azure Cloud Server is established
+
+

+

"GetDDnsInternetSettng" RPC API - Get the Proxy Settings for Connecting to the DDNS server

+

Description

+

Get the Proxy Settings for Connecting to the DDNS server.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "GetDDnsInternetSettng",
+  "params": {}
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "ProxyType_u32": 0,
+    "ProxyHostName_str": "proxyhostname",
+    "ProxyPort_u32": 0,
+    "ProxyUsername_str": "proxyusername",
+    "ProxyPassword_str": "proxypassword"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
ProxyType_u32number (enum)Type of proxy server
Values:
0: Direct TCP connection
1: Connection via HTTP proxy server
2: Connection via SOCKS proxy server
ProxyHostName_strstring (ASCII)Proxy server host name
ProxyPort_u32number (uint32)Proxy server port number
ProxyUsername_strstring (ASCII)Proxy server user name
ProxyPassword_strstring (ASCII)Proxy server password
+
+

+

"SetDDnsInternetSettng" RPC API - Set the Proxy Settings for Connecting to the DDNS server

+

Description

+

Set the Proxy Settings for Connecting to the DDNS server.

+

Input JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "method": "SetDDnsInternetSettng",
+  "params": {
+    "ProxyType_u32": 0,
+    "ProxyHostName_str": "proxyhostname",
+    "ProxyPort_u32": 0,
+    "ProxyUsername_str": "proxyusername",
+    "ProxyPassword_str": "proxypassword"
+  }
+}
+
+

Output JSON-RPC Format

+
{
+  "jsonrpc": "2.0",
+  "id": "rpc_call_id",
+  "result": {
+    "ProxyType_u32": 0,
+    "ProxyHostName_str": "proxyhostname",
+    "ProxyPort_u32": 0,
+    "ProxyUsername_str": "proxyusername",
+    "ProxyPassword_str": "proxypassword"
+  }
+}
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescrption
ProxyType_u32number (enum)Type of proxy server
Values:
0: Direct TCP connection
1: Connection via HTTP proxy server
2: Connection via SOCKS proxy server
ProxyHostName_strstring (ASCII)Proxy server host name
ProxyPort_u32number (uint32)Proxy server port number
ProxyUsername_strstring (ASCII)Proxy server user name
ProxyPassword_strstring (ASCII)Proxy server password
+
+

Automatically generated at 2019-06-29 21:13:00 by vpnserver-jsonrpc-codegen.
+Copyright (c) 2014-2019 SoftEther VPN Project under the Apache License 2.0.

+ +
+ + diff --git a/src/bin/hamcore/warning_cn.txt b/src/bin/hamcore/warning_cn.txt index 40372b81..04a17d5b 100644 --- a/src/bin/hamcore/warning_cn.txt +++ b/src/bin/hamcore/warning_cn.txt @@ -24,6 +24,8 @@ SoftEther VPN 具有 UDP 加速功能。如果一个 VPN 是由两个站点组 2. VPN 软件 +The notes in this section are not specific to SoftEther VPN or VPN Gate, but apply to general system software. SoftEther VPN Client, SoftEther VPN Server, SoftEther VPN Bridge, and VPN Gate Relay Service will be installed on your computer as system services. System services always run in the background. System services usually do not appear on the computer display. Then your computer system is booted, system services automatically start in the background even before you or other users log in. To check whether PacketiX-related system service is running, check the process list or the background service list of your OS (called as "Services" in Windows, or "Daemons" in UNIX.) You can activate, deactivate, start, or stop system services using the functions of the OS anytime. PacketiX-related GUI tools for managing system services communicate with these system services. After you terminate these management GUI tools, PacketiX-related system services will continue to run in the background. System services consume CPU time, computer power, memory and disk space. Because system services consume power, your electricity charges and amount of thermal of your computer increase as result. In addition, there is a possibility that the mechanical parts of the life of your computer is reduced. + 2.1. SoftEther VPN 客户端 如果您在 Windows 上使用 SoftEther VPN 客户端,虚拟网络适配器设备驱动程序将安装在 Windows 上。虚拟网络适配器作为一个内核模式驱动程序实施在 Windows 上。驱动程序是数字签名的,由 VeriSign , Inc 所签发的证书,还由 Symantec Corporation (赛门铁克公司) 签署。问你要确保安装驱动程序的一条消息可能会弹出在屏幕上。如果可能的话, SoftEther VPN 客户端可能会响应消息。SoftEther VPN 客户端还优化了在 Windows 上 MMCSS (多媒体类计划程序服务) 的配置。您以后可以撤消 MMCSS 的优化。 diff --git a/src/bin/hamcore/warning_en.txt b/src/bin/hamcore/warning_en.txt index 9ebbf058..30a4a85c 100644 --- a/src/bin/hamcore/warning_en.txt +++ b/src/bin/hamcore/warning_en.txt @@ -24,6 +24,8 @@ SoftEther VPN has the UDP Acceleration Function. If a VPN consists of two sites 2. VPN Software +The notes in this section are not specific to SoftEther VPN or VPN Gate, but apply to general system software. SoftEther VPN Client, SoftEther VPN Server, SoftEther VPN Bridge, and VPN Gate Relay Service will be installed on your computer as system services. System services always run in the background. System services usually do not appear on the computer display. Then your computer system is booted, system services automatically start in the background even before you or other users log in. To check whether PacketiX-related system service is running, check the process list or the background service list of your OS (called as "Services" in Windows, or "Daemons" in UNIX.) You can activate, deactivate, start, or stop system services using the functions of the OS anytime. PacketiX-related GUI tools for managing system services communicate with these system services. After you terminate these management GUI tools, PacketiX-related system services will continue to run in the background. System services consume CPU time, computer power, memory and disk space. Because system services consume power, your electricity charges and amount of thermal of your computer increase as result. In addition, there is a possibility that the mechanical parts of the life of your computer is reduced. + 2.1. SoftEther VPN Client If you use SoftEther VPN Client on Windows, the Virtual Network Adapter device driver will be installed on Windows. The Virtual Network Adapter is implemented as a kernel-mode driver for Windows. The driver is digitally-signed by a certificate issued by VeriSign, Inc. and also sub-signed by Symantec Corporation. A message to ask you want to sure install the driver might be popped up on the screen. SoftEther VPN Client may response the message if possible. SoftEther VPN Client also optimizes the configuration of MMCSS (Multimedia Class Scheduler Service) on Windows. You can undo the optimizations of MMCSS afterwards. diff --git a/src/bin/hamcore/warning_ja.txt b/src/bin/hamcore/warning_ja.txt index 9ed7e2c2..3748f4fd 100644 --- a/src/bin/hamcore/warning_ja.txt +++ b/src/bin/hamcore/warning_ja.txt @@ -24,6 +24,8 @@ SoftEther VPN には UDP 高速化機能が搭載されています。VPN を構 2. VPN ソフトウェアについて +この節で述べる注意事項は、SoftEther VPN および VPN Gate 特有のものではなく、一般的なシステムソフトウェアに当てはまる事項です。VPN ソフトウェアを構成する SoftEther VPN Client, SoftEther VPN Server および SoftEther VPN Bridge ならびに VPN Gate 中継サービスは、バックグラウンドで動作するシステムサービスとしてコンピュータにインストールされます。システムサービスは、通常、ディスプレイに表示されません。また、システムを起動した際に自動的に、ユーザーによるログイン前であっても、バックグラウンドで動作を開始します。システムサービスが稼働しているかどうかを確認するためには、プロセス一覧を確認するか、お使いの OS のバックグラウンドサービス一覧 (Windows においては「サービス」、UNIX においては「デーモン」と呼称されます。) を確認してください。また、OS の有する機能を用いて、システムサービスを有効化、無効化、開始または停止することができます。システムサービスを管理するための GUI ツールは、システムサービスとの間で通信を行ないます。これらの管理 GUI ツールを終了しても、システムサービスは継続してバックグラウンドで動作し続けます。システムサービスは、CPU 時間、コンピュータの消費電力、メモリおよびディスクの容量を消費します。システムサービスは、電力を消費するため、コンピュータに係る電気料金や発熱が増加する可能性があります。さらに、コンピュータの機械部分の寿命が短くなる可能性もあります。 + 2.1. SoftEther VPN Client SoftEther VPN Client を Windows で使用する場合は、仮想 LAN カードをコンピュータにインストールする必要があります。仮想 LAN カードは Windows 上で動作するカーネルモードドライバとして実装されています。当該ドライバは VeriSign 社の発行する証明書によってデジタル署名されており、Symantec 社による副署名もされています。ドライバのインストール時には本当にドライバをインストールするかどうかの確認メッセージが表示される場合があります。SoftEther VPN Client は可能な場合は自動的に当該確認メッセージに応答します。SoftEther VPN Client はインストール時に通信を最適化するため Windows の MMCSS (Multimedia Class Scheduler Service) の設定を最適化します。MMCSS の設定の最適化は後から元に戻すことができます。 diff --git a/src/bin/hamcore/wwwroot/admin/README.md b/src/bin/hamcore/wwwroot/admin/README.md new file mode 100644 index 00000000..49316cba --- /dev/null +++ b/src/bin/hamcore/wwwroot/admin/README.md @@ -0,0 +1,22 @@ +# About "admin" directory (for developers) +This `bin/hamcore/wwwroot/admin/` directory is the web contents root of the embedded HTML5 web administration console: `http://:/admin/`. + +Currently there is only the `default/` sub directory. It is corresponding to `http://:/admin/default/`. + + +The `/admin/index.html` file always redirects all clients to the `/admin/default/`. + + +If you are willing to develop the web-based administration console you have two choices: + +1. Modify and improve the `/admin/default/` project. + + +2. Create your entirely new web project in the `/admin/NEW_PATH_HERE/` directory. You can choose the unique directory name instead of `NEW_PATH_HERE` on the above directory path. + + +If you want to create an independent new web project, the choice #2 is the best way. You can do anything freely in your new directory. In such a case, please edit the `/admin/index.html` not to redirect to the `/admin/default/index.html` automatically. Instead, put the list of the systems for each of sub directories in the `/admin/index.html` so that the user can choose which system to use. + + + + diff --git a/src/bin/hamcore/wwwroot/admin/default/.gitignore b/src/bin/hamcore/wwwroot/admin/default/.gitignore new file mode 100644 index 00000000..bca51b35 --- /dev/null +++ b/src/bin/hamcore/wwwroot/admin/default/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/src/bin/hamcore/wwwroot/admin/default/.vscode/launch.json b/src/bin/hamcore/wwwroot/admin/default/.vscode/launch.json new file mode 100644 index 00000000..ae8930b3 --- /dev/null +++ b/src/bin/hamcore/wwwroot/admin/default/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "type": "chrome", + "request": "launch", + "trace": true, + "sourceMaps": true, + "name": "Launch Chrome", + "preLaunchTask": "webpack build", + "file": "${workspaceFolder}/index.html", + "webRoot": "${workspaceFolder}", + "internalConsoleOptions": "openOnSessionStart" + } + ] +} \ No newline at end of file diff --git a/src/bin/hamcore/wwwroot/admin/default/.vscode/settings.json b/src/bin/hamcore/wwwroot/admin/default/.vscode/settings.json new file mode 100644 index 00000000..bb15d9e4 --- /dev/null +++ b/src/bin/hamcore/wwwroot/admin/default/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "files.associations": { + "tsconfig_webpack.json": "jsonc" + } +} \ No newline at end of file diff --git a/src/bin/hamcore/wwwroot/admin/default/.vscode/tasks.json b/src/bin/hamcore/wwwroot/admin/default/.vscode/tasks.json new file mode 100644 index 00000000..704f1355 --- /dev/null +++ b/src/bin/hamcore/wwwroot/admin/default/.vscode/tasks.json @@ -0,0 +1,45 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "webpack build", + "type": "npm", + "script": "build", + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "webpack watch", + "type": "npm", + "script": "watch", + "isBackground": true, + "problemMatcher": { + "pattern": { + "regexp": "^$" + }, + "background": { + "activeOnStart": true, + "beginsPattern": ".*Version: webpack.*", + "endsPattern": ".*\\[built\\]" + }, + } + }, + { + "label": "tsc build", + "type": "typescript", + "tsconfig": "tsconfig.json", + }, + { + "label": "tsc watch", + "type": "typescript", + "tsconfig": "tsconfig.json", + "option": "watch", + "problemMatcher": [ + "$tsc-watch" + ] + } + ] +} \ No newline at end of file diff --git a/src/bin/hamcore/wwwroot/admin/default/hub.html b/src/bin/hamcore/wwwroot/admin/default/hub.html new file mode 100644 index 00000000..91b46307 --- /dev/null +++ b/src/bin/hamcore/wwwroot/admin/default/hub.html @@ -0,0 +1,23 @@ + + + + + +
+

+ + + +

List of Users

+
    + +

    List of Active VPN Sessions

    +
      + +
      + + + + diff --git a/src/bin/hamcore/wwwroot/admin/default/include_footer.html b/src/bin/hamcore/wwwroot/admin/default/include_footer.html new file mode 100644 index 00000000..d00aa3e6 --- /dev/null +++ b/src/bin/hamcore/wwwroot/admin/default/include_footer.html @@ -0,0 +1,4 @@ +

       

      +

       

      +
      +

      Copyright (c) SoftEther VPN Project under the Apache License 2.0.

      diff --git a/src/bin/hamcore/wwwroot/admin/default/include_head.html b/src/bin/hamcore/wwwroot/admin/default/include_head.html new file mode 100644 index 00000000..157dfec0 --- /dev/null +++ b/src/bin/hamcore/wwwroot/admin/default/include_head.html @@ -0,0 +1,9 @@ + + SoftEther VPN Server HTML5 Web Administration Console (Under construction!) + + + + + + + diff --git a/src/bin/hamcore/wwwroot/admin/default/include_menu.html b/src/bin/hamcore/wwwroot/admin/default/include_menu.html new file mode 100644 index 00000000..3926209a --- /dev/null +++ b/src/bin/hamcore/wwwroot/admin/default/include_menu.html @@ -0,0 +1,29 @@ + + diff --git a/src/bin/hamcore/wwwroot/admin/default/index.html b/src/bin/hamcore/wwwroot/admin/default/index.html new file mode 100644 index 00000000..052ac57f --- /dev/null +++ b/src/bin/hamcore/wwwroot/admin/default/index.html @@ -0,0 +1,45 @@ + + + + + +
      +

      SoftEther VPN Server HTML5 Ajax-based Web Administration Console
      (Under construction!)

      +

      This is the sample of HTML5 Ajax-based VPN Server Web Administration Console.

      +

      The purpose of this HTML5 admin page is to make administrators easy to set up and manage the running VPN Servers.

      +

      Authentication for this page

      +

      You must supply the HTTP basic authentication credential as following.

      +
        +
      • To login to the VPN server as the entire server administrator, specify empty or "administrator" as the username field, + and specify the server administrative password as the password field.
      • +
      • To login to a particular Virtual Hub as the hub administrator, specify the hub name as the username field, and specify + the hub administrative password as the password field.
      • +
      + +

      Your HTML5 development contribution is very appreciated

      +

      This HTML5 page is obviously under construction, and providing very minimum functions as sample.
      This initial page is written by Daiyuu Nobori (the core developer of SoftEther VPN). He is obviously lack of HTML5 development ability.
      Please kindly consider to contribute for SoftEther VPN's development on GitHub. Your code will help every people running SoftEther VPN Server.

      + +

      This HTML5 page's JavaScript codes directly call SoftEther VPN Server JSON-RPC API on the running VPN Server from the web browser.
      You can also call the SoftEther VPN Server JSON-RPC API remotely from your original application. (JavaScript, TypeScript, C#, Java, Python, Ruby, etc.)

      +

      The insanely kindness API reference is available.

      + +

      List of Virtual Hubs

      +
        + +

        Create new Virtual Hub

        + Virtual Hub Name:
        + + +

        VPN Server Information

        +
          + +

          VPN Server Status

          +
            + +
            + + + + diff --git a/src/bin/hamcore/wwwroot/admin/default/out_webpack/bundle.js b/src/bin/hamcore/wwwroot/admin/default/out_webpack/bundle.js new file mode 100644 index 00000000..e9ec0b6d --- /dev/null +++ b/src/bin/hamcore/wwwroot/admin/default/out_webpack/bundle.js @@ -0,0 +1,2144 @@ +var JS = +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = "./src/ts/main.ts"); +/******/ }) +/************************************************************************/ +/******/ ({ + +/***/ "./node_modules/base64-js/index.js": +/*!*****************************************!*\ + !*** ./node_modules/base64-js/index.js ***! + \*****************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\n\nexports.byteLength = byteLength\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nvar code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\nfor (var i = 0, len = code.length; i < len; ++i) {\n lookup[i] = code[i]\n revLookup[code.charCodeAt(i)] = i\n}\n\n// Support decoding URL-safe base64 strings, as Node.js does.\n// See: https://en.wikipedia.org/wiki/Base64#URL_applications\nrevLookup['-'.charCodeAt(0)] = 62\nrevLookup['_'.charCodeAt(0)] = 63\n\nfunction getLens (b64) {\n var len = b64.length\n\n if (len % 4 > 0) {\n throw new Error('Invalid string. Length must be a multiple of 4')\n }\n\n // Trim off extra bytes after placeholder bytes are found\n // See: https://github.com/beatgammit/base64-js/issues/42\n var validLen = b64.indexOf('=')\n if (validLen === -1) validLen = len\n\n var placeHoldersLen = validLen === len\n ? 0\n : 4 - (validLen % 4)\n\n return [validLen, placeHoldersLen]\n}\n\n// base64 is 4/3 + up to two characters of the original data\nfunction byteLength (b64) {\n var lens = getLens(b64)\n var validLen = lens[0]\n var placeHoldersLen = lens[1]\n return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction _byteLength (b64, validLen, placeHoldersLen) {\n return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction toByteArray (b64) {\n var tmp\n var lens = getLens(b64)\n var validLen = lens[0]\n var placeHoldersLen = lens[1]\n\n var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))\n\n var curByte = 0\n\n // if there are placeholders, only get up to the last complete 4 chars\n var len = placeHoldersLen > 0\n ? validLen - 4\n : validLen\n\n for (var i = 0; i < len; i += 4) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 18) |\n (revLookup[b64.charCodeAt(i + 1)] << 12) |\n (revLookup[b64.charCodeAt(i + 2)] << 6) |\n revLookup[b64.charCodeAt(i + 3)]\n arr[curByte++] = (tmp >> 16) & 0xFF\n arr[curByte++] = (tmp >> 8) & 0xFF\n arr[curByte++] = tmp & 0xFF\n }\n\n if (placeHoldersLen === 2) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 2) |\n (revLookup[b64.charCodeAt(i + 1)] >> 4)\n arr[curByte++] = tmp & 0xFF\n }\n\n if (placeHoldersLen === 1) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 10) |\n (revLookup[b64.charCodeAt(i + 1)] << 4) |\n (revLookup[b64.charCodeAt(i + 2)] >> 2)\n arr[curByte++] = (tmp >> 8) & 0xFF\n arr[curByte++] = tmp & 0xFF\n }\n\n return arr\n}\n\nfunction tripletToBase64 (num) {\n return lookup[num >> 18 & 0x3F] +\n lookup[num >> 12 & 0x3F] +\n lookup[num >> 6 & 0x3F] +\n lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n var tmp\n var output = []\n for (var i = start; i < end; i += 3) {\n tmp =\n ((uint8[i] << 16) & 0xFF0000) +\n ((uint8[i + 1] << 8) & 0xFF00) +\n (uint8[i + 2] & 0xFF)\n output.push(tripletToBase64(tmp))\n }\n return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n var tmp\n var len = uint8.length\n var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n var parts = []\n var maxChunkLength = 16383 // must be multiple of 3\n\n // go through the array every three bytes, we'll deal with trailing stuff later\n for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n parts.push(encodeChunk(\n uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)\n ))\n }\n\n // pad the end with zeros, but make sure to not forget the extra bytes\n if (extraBytes === 1) {\n tmp = uint8[len - 1]\n parts.push(\n lookup[tmp >> 2] +\n lookup[(tmp << 4) & 0x3F] +\n '=='\n )\n } else if (extraBytes === 2) {\n tmp = (uint8[len - 2] << 8) + uint8[len - 1]\n parts.push(\n lookup[tmp >> 10] +\n lookup[(tmp >> 4) & 0x3F] +\n lookup[(tmp << 2) & 0x3F] +\n '='\n )\n }\n\n return parts.join('')\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYmFzZTY0LWpzL2luZGV4LmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvYmFzZTY0LWpzL2luZGV4LmpzPzFmYjUiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnXG5cbmV4cG9ydHMuYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGhcbmV4cG9ydHMudG9CeXRlQXJyYXkgPSB0b0J5dGVBcnJheVxuZXhwb3J0cy5mcm9tQnl0ZUFycmF5ID0gZnJvbUJ5dGVBcnJheVxuXG52YXIgbG9va3VwID0gW11cbnZhciByZXZMb29rdXAgPSBbXVxudmFyIEFyciA9IHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJyA/IFVpbnQ4QXJyYXkgOiBBcnJheVxuXG52YXIgY29kZSA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvJ1xuZm9yICh2YXIgaSA9IDAsIGxlbiA9IGNvZGUubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgbG9va3VwW2ldID0gY29kZVtpXVxuICByZXZMb29rdXBbY29kZS5jaGFyQ29kZUF0KGkpXSA9IGlcbn1cblxuLy8gU3VwcG9ydCBkZWNvZGluZyBVUkwtc2FmZSBiYXNlNjQgc3RyaW5ncywgYXMgTm9kZS5qcyBkb2VzLlxuLy8gU2VlOiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9CYXNlNjQjVVJMX2FwcGxpY2F0aW9uc1xucmV2TG9va3VwWyctJy5jaGFyQ29kZUF0KDApXSA9IDYyXG5yZXZMb29rdXBbJ18nLmNoYXJDb2RlQXQoMCldID0gNjNcblxuZnVuY3Rpb24gZ2V0TGVucyAoYjY0KSB7XG4gIHZhciBsZW4gPSBiNjQubGVuZ3RoXG5cbiAgaWYgKGxlbiAlIDQgPiAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHN0cmluZy4gTGVuZ3RoIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA0JylcbiAgfVxuXG4gIC8vIFRyaW0gb2ZmIGV4dHJhIGJ5dGVzIGFmdGVyIHBsYWNlaG9sZGVyIGJ5dGVzIGFyZSBmb3VuZFxuICAvLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9iZWF0Z2FtbWl0L2Jhc2U2NC1qcy9pc3N1ZXMvNDJcbiAgdmFyIHZhbGlkTGVuID0gYjY0LmluZGV4T2YoJz0nKVxuICBpZiAodmFsaWRMZW4gPT09IC0xKSB2YWxpZExlbiA9IGxlblxuXG4gIHZhciBwbGFjZUhvbGRlcnNMZW4gPSB2YWxpZExlbiA9PT0gbGVuXG4gICAgPyAwXG4gICAgOiA0IC0gKHZhbGlkTGVuICUgNClcblxuICByZXR1cm4gW3ZhbGlkTGVuLCBwbGFjZUhvbGRlcnNMZW5dXG59XG5cbi8vIGJhc2U2NCBpcyA0LzMgKyB1cCB0byB0d28gY2hhcmFjdGVycyBvZiB0aGUgb3JpZ2luYWwgZGF0YVxuZnVuY3Rpb24gYnl0ZUxlbmd0aCAoYjY0KSB7XG4gIHZhciBsZW5zID0gZ2V0TGVucyhiNjQpXG4gIHZhciB2YWxpZExlbiA9IGxlbnNbMF1cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IGxlbnNbMV1cbiAgcmV0dXJuICgodmFsaWRMZW4gKyBwbGFjZUhvbGRlcnNMZW4pICogMyAvIDQpIC0gcGxhY2VIb2xkZXJzTGVuXG59XG5cbmZ1bmN0aW9uIF9ieXRlTGVuZ3RoIChiNjQsIHZhbGlkTGVuLCBwbGFjZUhvbGRlcnNMZW4pIHtcbiAgcmV0dXJuICgodmFsaWRMZW4gKyBwbGFjZUhvbGRlcnNMZW4pICogMyAvIDQpIC0gcGxhY2VIb2xkZXJzTGVuXG59XG5cbmZ1bmN0aW9uIHRvQnl0ZUFycmF5IChiNjQpIHtcbiAgdmFyIHRtcFxuICB2YXIgbGVucyA9IGdldExlbnMoYjY0KVxuICB2YXIgdmFsaWRMZW4gPSBsZW5zWzBdXG4gIHZhciBwbGFjZUhvbGRlcnNMZW4gPSBsZW5zWzFdXG5cbiAgdmFyIGFyciA9IG5ldyBBcnIoX2J5dGVMZW5ndGgoYjY0LCB2YWxpZExlbiwgcGxhY2VIb2xkZXJzTGVuKSlcblxuICB2YXIgY3VyQnl0ZSA9IDBcblxuICAvLyBpZiB0aGVyZSBhcmUgcGxhY2Vob2xkZXJzLCBvbmx5IGdldCB1cCB0byB0aGUgbGFzdCBjb21wbGV0ZSA0IGNoYXJzXG4gIHZhciBsZW4gPSBwbGFjZUhvbGRlcnNMZW4gPiAwXG4gICAgPyB2YWxpZExlbiAtIDRcbiAgICA6IHZhbGlkTGVuXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gNCkge1xuICAgIHRtcCA9XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAxOCkgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMSldIDw8IDEyKSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAyKV0gPDwgNikgfFxuICAgICAgcmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAzKV1cbiAgICBhcnJbY3VyQnl0ZSsrXSA9ICh0bXAgPj4gMTYpICYgMHhGRlxuICAgIGFycltjdXJCeXRlKytdID0gKHRtcCA+PiA4KSAmIDB4RkZcbiAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIGlmIChwbGFjZUhvbGRlcnNMZW4gPT09IDIpIHtcbiAgICB0bXAgPVxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMikgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMSldID4+IDQpXG4gICAgYXJyW2N1ckJ5dGUrK10gPSB0bXAgJiAweEZGXG4gIH1cblxuICBpZiAocGxhY2VIb2xkZXJzTGVuID09PSAxKSB7XG4gICAgdG1wID1cbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDEwKSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPDwgNCkgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMildID4+IDIpXG4gICAgYXJyW2N1ckJ5dGUrK10gPSAodG1wID4+IDgpICYgMHhGRlxuICAgIGFycltjdXJCeXRlKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIGFyclxufVxuXG5mdW5jdGlvbiB0cmlwbGV0VG9CYXNlNjQgKG51bSkge1xuICByZXR1cm4gbG9va3VwW251bSA+PiAxOCAmIDB4M0ZdICtcbiAgICBsb29rdXBbbnVtID4+IDEyICYgMHgzRl0gK1xuICAgIGxvb2t1cFtudW0gPj4gNiAmIDB4M0ZdICtcbiAgICBsb29rdXBbbnVtICYgMHgzRl1cbn1cblxuZnVuY3Rpb24gZW5jb2RlQ2h1bmsgKHVpbnQ4LCBzdGFydCwgZW5kKSB7XG4gIHZhciB0bXBcbiAgdmFyIG91dHB1dCA9IFtdXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSArPSAzKSB7XG4gICAgdG1wID1cbiAgICAgICgodWludDhbaV0gPDwgMTYpICYgMHhGRjAwMDApICtcbiAgICAgICgodWludDhbaSArIDFdIDw8IDgpICYgMHhGRjAwKSArXG4gICAgICAodWludDhbaSArIDJdICYgMHhGRilcbiAgICBvdXRwdXQucHVzaCh0cmlwbGV0VG9CYXNlNjQodG1wKSlcbiAgfVxuICByZXR1cm4gb3V0cHV0LmpvaW4oJycpXG59XG5cbmZ1bmN0aW9uIGZyb21CeXRlQXJyYXkgKHVpbnQ4KSB7XG4gIHZhciB0bXBcbiAgdmFyIGxlbiA9IHVpbnQ4Lmxlbmd0aFxuICB2YXIgZXh0cmFCeXRlcyA9IGxlbiAlIDMgLy8gaWYgd2UgaGF2ZSAxIGJ5dGUgbGVmdCwgcGFkIDIgYnl0ZXNcbiAgdmFyIHBhcnRzID0gW11cbiAgdmFyIG1heENodW5rTGVuZ3RoID0gMTYzODMgLy8gbXVzdCBiZSBtdWx0aXBsZSBvZiAzXG5cbiAgLy8gZ28gdGhyb3VnaCB0aGUgYXJyYXkgZXZlcnkgdGhyZWUgYnl0ZXMsIHdlJ2xsIGRlYWwgd2l0aCB0cmFpbGluZyBzdHVmZiBsYXRlclxuICBmb3IgKHZhciBpID0gMCwgbGVuMiA9IGxlbiAtIGV4dHJhQnl0ZXM7IGkgPCBsZW4yOyBpICs9IG1heENodW5rTGVuZ3RoKSB7XG4gICAgcGFydHMucHVzaChlbmNvZGVDaHVuayhcbiAgICAgIHVpbnQ4LCBpLCAoaSArIG1heENodW5rTGVuZ3RoKSA+IGxlbjIgPyBsZW4yIDogKGkgKyBtYXhDaHVua0xlbmd0aClcbiAgICApKVxuICB9XG5cbiAgLy8gcGFkIHRoZSBlbmQgd2l0aCB6ZXJvcywgYnV0IG1ha2Ugc3VyZSB0byBub3QgZm9yZ2V0IHRoZSBleHRyYSBieXRlc1xuICBpZiAoZXh0cmFCeXRlcyA9PT0gMSkge1xuICAgIHRtcCA9IHVpbnQ4W2xlbiAtIDFdXG4gICAgcGFydHMucHVzaChcbiAgICAgIGxvb2t1cFt0bXAgPj4gMl0gK1xuICAgICAgbG9va3VwWyh0bXAgPDwgNCkgJiAweDNGXSArXG4gICAgICAnPT0nXG4gICAgKVxuICB9IGVsc2UgaWYgKGV4dHJhQnl0ZXMgPT09IDIpIHtcbiAgICB0bXAgPSAodWludDhbbGVuIC0gMl0gPDwgOCkgKyB1aW50OFtsZW4gLSAxXVxuICAgIHBhcnRzLnB1c2goXG4gICAgICBsb29rdXBbdG1wID4+IDEwXSArXG4gICAgICBsb29rdXBbKHRtcCA+PiA0KSAmIDB4M0ZdICtcbiAgICAgIGxvb2t1cFsodG1wIDw8IDIpICYgMHgzRl0gK1xuICAgICAgJz0nXG4gICAgKVxuICB9XG5cbiAgcmV0dXJuIHBhcnRzLmpvaW4oJycpXG59XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/base64-js/index.js\n"); + +/***/ }), + +/***/ "./node_modules/buffer/index.js": +/*!**************************************!*\ + !*** ./node_modules/buffer/index.js ***! + \**************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("/* WEBPACK VAR INJECTION */(function(global) {/*!\n * The buffer module from node.js, for the browser.\n *\n * @author Feross Aboukhadijeh \n * @license MIT\n */\n/* eslint-disable no-proto */\n\n\n\nvar base64 = __webpack_require__(/*! base64-js */ \"./node_modules/base64-js/index.js\")\nvar ieee754 = __webpack_require__(/*! ieee754 */ \"./node_modules/ieee754/index.js\")\nvar isArray = __webpack_require__(/*! isarray */ \"./node_modules/isarray/index.js\")\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n * === true Use Uint8Array implementation (fastest)\n * === false Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n * incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined\n ? global.TYPED_ARRAY_SUPPORT\n : typedArraySupport()\n\n/*\n * Export kMaxLength after typed array support is determined.\n */\nexports.kMaxLength = kMaxLength()\n\nfunction typedArraySupport () {\n try {\n var arr = new Uint8Array(1)\n arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}\n return arr.foo() === 42 && // typed array instances can be augmented\n typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\n arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\n } catch (e) {\n return false\n }\n}\n\nfunction kMaxLength () {\n return Buffer.TYPED_ARRAY_SUPPORT\n ? 0x7fffffff\n : 0x3fffffff\n}\n\nfunction createBuffer (that, length) {\n if (kMaxLength() < length) {\n throw new RangeError('Invalid typed array length')\n }\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n // Return an augmented `Uint8Array` instance, for best performance\n that = new Uint8Array(length)\n that.__proto__ = Buffer.prototype\n } else {\n // Fallback: Return an object instance of the Buffer class\n if (that === null) {\n that = new Buffer(length)\n }\n that.length = length\n }\n\n return that\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {\n return new Buffer(arg, encodingOrOffset, length)\n }\n\n // Common case.\n if (typeof arg === 'number') {\n if (typeof encodingOrOffset === 'string') {\n throw new Error(\n 'If encoding is specified then the first argument must be a string'\n )\n }\n return allocUnsafe(this, arg)\n }\n return from(this, arg, encodingOrOffset, length)\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\n// TODO: Legacy, not needed anymore. Remove in next major version.\nBuffer._augment = function (arr) {\n arr.__proto__ = Buffer.prototype\n return arr\n}\n\nfunction from (that, value, encodingOrOffset, length) {\n if (typeof value === 'number') {\n throw new TypeError('\"value\" argument must not be a number')\n }\n\n if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n return fromArrayBuffer(that, value, encodingOrOffset, length)\n }\n\n if (typeof value === 'string') {\n return fromString(that, value, encodingOrOffset)\n }\n\n return fromObject(that, value)\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n return from(null, value, encodingOrOffset, length)\n}\n\nif (Buffer.TYPED_ARRAY_SUPPORT) {\n Buffer.prototype.__proto__ = Uint8Array.prototype\n Buffer.__proto__ = Uint8Array\n if (typeof Symbol !== 'undefined' && Symbol.species &&\n Buffer[Symbol.species] === Buffer) {\n // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97\n Object.defineProperty(Buffer, Symbol.species, {\n value: null,\n configurable: true\n })\n }\n}\n\nfunction assertSize (size) {\n if (typeof size !== 'number') {\n throw new TypeError('\"size\" argument must be a number')\n } else if (size < 0) {\n throw new RangeError('\"size\" argument must not be negative')\n }\n}\n\nfunction alloc (that, size, fill, encoding) {\n assertSize(size)\n if (size <= 0) {\n return createBuffer(that, size)\n }\n if (fill !== undefined) {\n // Only pay attention to encoding if it's a string. This\n // prevents accidentally sending in a number that would\n // be interpretted as a start offset.\n return typeof encoding === 'string'\n ? createBuffer(that, size).fill(fill, encoding)\n : createBuffer(that, size).fill(fill)\n }\n return createBuffer(that, size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n return alloc(null, size, fill, encoding)\n}\n\nfunction allocUnsafe (that, size) {\n assertSize(size)\n that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)\n if (!Buffer.TYPED_ARRAY_SUPPORT) {\n for (var i = 0; i < size; ++i) {\n that[i] = 0\n }\n }\n return that\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n return allocUnsafe(null, size)\n}\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n return allocUnsafe(null, size)\n}\n\nfunction fromString (that, string, encoding) {\n if (typeof encoding !== 'string' || encoding === '') {\n encoding = 'utf8'\n }\n\n if (!Buffer.isEncoding(encoding)) {\n throw new TypeError('\"encoding\" must be a valid string encoding')\n }\n\n var length = byteLength(string, encoding) | 0\n that = createBuffer(that, length)\n\n var actual = that.write(string, encoding)\n\n if (actual !== length) {\n // Writing a hex string, for example, that contains invalid characters will\n // cause everything after the first invalid character to be ignored. (e.g.\n // 'abxxcd' will be treated as 'ab')\n that = that.slice(0, actual)\n }\n\n return that\n}\n\nfunction fromArrayLike (that, array) {\n var length = array.length < 0 ? 0 : checked(array.length) | 0\n that = createBuffer(that, length)\n for (var i = 0; i < length; i += 1) {\n that[i] = array[i] & 255\n }\n return that\n}\n\nfunction fromArrayBuffer (that, array, byteOffset, length) {\n array.byteLength // this throws if `array` is not a valid ArrayBuffer\n\n if (byteOffset < 0 || array.byteLength < byteOffset) {\n throw new RangeError('\\'offset\\' is out of bounds')\n }\n\n if (array.byteLength < byteOffset + (length || 0)) {\n throw new RangeError('\\'length\\' is out of bounds')\n }\n\n if (byteOffset === undefined && length === undefined) {\n array = new Uint8Array(array)\n } else if (length === undefined) {\n array = new Uint8Array(array, byteOffset)\n } else {\n array = new Uint8Array(array, byteOffset, length)\n }\n\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n // Return an augmented `Uint8Array` instance, for best performance\n that = array\n that.__proto__ = Buffer.prototype\n } else {\n // Fallback: Return an object instance of the Buffer class\n that = fromArrayLike(that, array)\n }\n return that\n}\n\nfunction fromObject (that, obj) {\n if (Buffer.isBuffer(obj)) {\n var len = checked(obj.length) | 0\n that = createBuffer(that, len)\n\n if (that.length === 0) {\n return that\n }\n\n obj.copy(that, 0, 0, len)\n return that\n }\n\n if (obj) {\n if ((typeof ArrayBuffer !== 'undefined' &&\n obj.buffer instanceof ArrayBuffer) || 'length' in obj) {\n if (typeof obj.length !== 'number' || isnan(obj.length)) {\n return createBuffer(that, 0)\n }\n return fromArrayLike(that, obj)\n }\n\n if (obj.type === 'Buffer' && isArray(obj.data)) {\n return fromArrayLike(that, obj.data)\n }\n }\n\n throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n}\n\nfunction checked (length) {\n // Note: cannot use `length < kMaxLength()` here because that fails when\n // length is NaN (which is otherwise coerced to zero.)\n if (length >= kMaxLength()) {\n throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n 'size: 0x' + kMaxLength().toString(16) + ' bytes')\n }\n return length | 0\n}\n\nfunction SlowBuffer (length) {\n if (+length != length) { // eslint-disable-line eqeqeq\n length = 0\n }\n return Buffer.alloc(+length)\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n throw new TypeError('Arguments must be Buffers')\n }\n\n if (a === b) return 0\n\n var x = a.length\n var y = b.length\n\n for (var i = 0, len = Math.min(x, y); i < len; ++i) {\n if (a[i] !== b[i]) {\n x = a[i]\n y = b[i]\n break\n }\n }\n\n if (x < y) return -1\n if (y < x) return 1\n return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n switch (String(encoding).toLowerCase()) {\n case 'hex':\n case 'utf8':\n case 'utf-8':\n case 'ascii':\n case 'latin1':\n case 'binary':\n case 'base64':\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return true\n default:\n return false\n }\n}\n\nBuffer.concat = function concat (list, length) {\n if (!isArray(list)) {\n throw new TypeError('\"list\" argument must be an Array of Buffers')\n }\n\n if (list.length === 0) {\n return Buffer.alloc(0)\n }\n\n var i\n if (length === undefined) {\n length = 0\n for (i = 0; i < list.length; ++i) {\n length += list[i].length\n }\n }\n\n var buffer = Buffer.allocUnsafe(length)\n var pos = 0\n for (i = 0; i < list.length; ++i) {\n var buf = list[i]\n if (!Buffer.isBuffer(buf)) {\n throw new TypeError('\"list\" argument must be an Array of Buffers')\n }\n buf.copy(buffer, pos)\n pos += buf.length\n }\n return buffer\n}\n\nfunction byteLength (string, encoding) {\n if (Buffer.isBuffer(string)) {\n return string.length\n }\n if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&\n (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {\n return string.byteLength\n }\n if (typeof string !== 'string') {\n string = '' + string\n }\n\n var len = string.length\n if (len === 0) return 0\n\n // Use a for loop to avoid recursion\n var loweredCase = false\n for (;;) {\n switch (encoding) {\n case 'ascii':\n case 'latin1':\n case 'binary':\n return len\n case 'utf8':\n case 'utf-8':\n case undefined:\n return utf8ToBytes(string).length\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return len * 2\n case 'hex':\n return len >>> 1\n case 'base64':\n return base64ToBytes(string).length\n default:\n if (loweredCase) return utf8ToBytes(string).length // assume utf8\n encoding = ('' + encoding).toLowerCase()\n loweredCase = true\n }\n }\n}\nBuffer.byteLength = byteLength\n\nfunction slowToString (encoding, start, end) {\n var loweredCase = false\n\n // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n // property of a typed array.\n\n // This behaves neither like String nor Uint8Array in that we set start/end\n // to their upper/lower bounds if the value passed is out of range.\n // undefined is handled specially as per ECMA-262 6th Edition,\n // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n if (start === undefined || start < 0) {\n start = 0\n }\n // Return early if start > this.length. Done here to prevent potential uint32\n // coercion fail below.\n if (start > this.length) {\n return ''\n }\n\n if (end === undefined || end > this.length) {\n end = this.length\n }\n\n if (end <= 0) {\n return ''\n }\n\n // Force coersion to uint32. This will also coerce falsey/NaN values to 0.\n end >>>= 0\n start >>>= 0\n\n if (end <= start) {\n return ''\n }\n\n if (!encoding) encoding = 'utf8'\n\n while (true) {\n switch (encoding) {\n case 'hex':\n return hexSlice(this, start, end)\n\n case 'utf8':\n case 'utf-8':\n return utf8Slice(this, start, end)\n\n case 'ascii':\n return asciiSlice(this, start, end)\n\n case 'latin1':\n case 'binary':\n return latin1Slice(this, start, end)\n\n case 'base64':\n return base64Slice(this, start, end)\n\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return utf16leSlice(this, start, end)\n\n default:\n if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n encoding = (encoding + '').toLowerCase()\n loweredCase = true\n }\n }\n}\n\n// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect\n// Buffer instances.\nBuffer.prototype._isBuffer = true\n\nfunction swap (b, n, m) {\n var i = b[n]\n b[n] = b[m]\n b[m] = i\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n var len = this.length\n if (len % 2 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 16-bits')\n }\n for (var i = 0; i < len; i += 2) {\n swap(this, i, i + 1)\n }\n return this\n}\n\nBuffer.prototype.swap32 = function swap32 () {\n var len = this.length\n if (len % 4 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 32-bits')\n }\n for (var i = 0; i < len; i += 4) {\n swap(this, i, i + 3)\n swap(this, i + 1, i + 2)\n }\n return this\n}\n\nBuffer.prototype.swap64 = function swap64 () {\n var len = this.length\n if (len % 8 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 64-bits')\n }\n for (var i = 0; i < len; i += 8) {\n swap(this, i, i + 7)\n swap(this, i + 1, i + 6)\n swap(this, i + 2, i + 5)\n swap(this, i + 3, i + 4)\n }\n return this\n}\n\nBuffer.prototype.toString = function toString () {\n var length = this.length | 0\n if (length === 0) return ''\n if (arguments.length === 0) return utf8Slice(this, 0, length)\n return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.equals = function equals (b) {\n if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n if (this === b) return true\n return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n var str = ''\n var max = exports.INSPECT_MAX_BYTES\n if (this.length > 0) {\n str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\n if (this.length > max) str += ' ... '\n }\n return ''\n}\n\nBuffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {\n if (!Buffer.isBuffer(target)) {\n throw new TypeError('Argument must be a Buffer')\n }\n\n if (start === undefined) {\n start = 0\n }\n if (end === undefined) {\n end = target ? target.length : 0\n }\n if (thisStart === undefined) {\n thisStart = 0\n }\n if (thisEnd === undefined) {\n thisEnd = this.length\n }\n\n if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {\n throw new RangeError('out of range index')\n }\n\n if (thisStart >= thisEnd && start >= end) {\n return 0\n }\n if (thisStart >= thisEnd) {\n return -1\n }\n if (start >= end) {\n return 1\n }\n\n start >>>= 0\n end >>>= 0\n thisStart >>>= 0\n thisEnd >>>= 0\n\n if (this === target) return 0\n\n var x = thisEnd - thisStart\n var y = end - start\n var len = Math.min(x, y)\n\n var thisCopy = this.slice(thisStart, thisEnd)\n var targetCopy = target.slice(start, end)\n\n for (var i = 0; i < len; ++i) {\n if (thisCopy[i] !== targetCopy[i]) {\n x = thisCopy[i]\n y = targetCopy[i]\n break\n }\n }\n\n if (x < y) return -1\n if (y < x) return 1\n return 0\n}\n\n// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,\n// OR the last index of `val` in `buffer` at offset <= `byteOffset`.\n//\n// Arguments:\n// - buffer - a Buffer to search\n// - val - a string, Buffer, or number\n// - byteOffset - an index into `buffer`; will be clamped to an int32\n// - encoding - an optional encoding, relevant is val is a string\n// - dir - true for indexOf, false for lastIndexOf\nfunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {\n // Empty buffer means no match\n if (buffer.length === 0) return -1\n\n // Normalize byteOffset\n if (typeof byteOffset === 'string') {\n encoding = byteOffset\n byteOffset = 0\n } else if (byteOffset > 0x7fffffff) {\n byteOffset = 0x7fffffff\n } else if (byteOffset < -0x80000000) {\n byteOffset = -0x80000000\n }\n byteOffset = +byteOffset // Coerce to Number.\n if (isNaN(byteOffset)) {\n // byteOffset: it it's undefined, null, NaN, \"foo\", etc, search whole buffer\n byteOffset = dir ? 0 : (buffer.length - 1)\n }\n\n // Normalize byteOffset: negative offsets start from the end of the buffer\n if (byteOffset < 0) byteOffset = buffer.length + byteOffset\n if (byteOffset >= buffer.length) {\n if (dir) return -1\n else byteOffset = buffer.length - 1\n } else if (byteOffset < 0) {\n if (dir) byteOffset = 0\n else return -1\n }\n\n // Normalize val\n if (typeof val === 'string') {\n val = Buffer.from(val, encoding)\n }\n\n // Finally, search either indexOf (if dir is true) or lastIndexOf\n if (Buffer.isBuffer(val)) {\n // Special case: looking for empty string/buffer always fails\n if (val.length === 0) {\n return -1\n }\n return arrayIndexOf(buffer, val, byteOffset, encoding, dir)\n } else if (typeof val === 'number') {\n val = val & 0xFF // Search for a byte value [0-255]\n if (Buffer.TYPED_ARRAY_SUPPORT &&\n typeof Uint8Array.prototype.indexOf === 'function') {\n if (dir) {\n return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)\n } else {\n return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)\n }\n }\n return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)\n }\n\n throw new TypeError('val must be string, number or Buffer')\n}\n\nfunction arrayIndexOf (arr, val, byteOffset, encoding, dir) {\n var indexSize = 1\n var arrLength = arr.length\n var valLength = val.length\n\n if (encoding !== undefined) {\n encoding = String(encoding).toLowerCase()\n if (encoding === 'ucs2' || encoding === 'ucs-2' ||\n encoding === 'utf16le' || encoding === 'utf-16le') {\n if (arr.length < 2 || val.length < 2) {\n return -1\n }\n indexSize = 2\n arrLength /= 2\n valLength /= 2\n byteOffset /= 2\n }\n }\n\n function read (buf, i) {\n if (indexSize === 1) {\n return buf[i]\n } else {\n return buf.readUInt16BE(i * indexSize)\n }\n }\n\n var i\n if (dir) {\n var foundIndex = -1\n for (i = byteOffset; i < arrLength; i++) {\n if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {\n if (foundIndex === -1) foundIndex = i\n if (i - foundIndex + 1 === valLength) return foundIndex * indexSize\n } else {\n if (foundIndex !== -1) i -= i - foundIndex\n foundIndex = -1\n }\n }\n } else {\n if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength\n for (i = byteOffset; i >= 0; i--) {\n var found = true\n for (var j = 0; j < valLength; j++) {\n if (read(arr, i + j) !== read(val, j)) {\n found = false\n break\n }\n }\n if (found) return i\n }\n }\n\n return -1\n}\n\nBuffer.prototype.includes = function includes (val, byteOffset, encoding) {\n return this.indexOf(val, byteOffset, encoding) !== -1\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {\n return bidirectionalIndexOf(this, val, byteOffset, encoding, true)\n}\n\nBuffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {\n return bidirectionalIndexOf(this, val, byteOffset, encoding, false)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n offset = Number(offset) || 0\n var remaining = buf.length - offset\n if (!length) {\n length = remaining\n } else {\n length = Number(length)\n if (length > remaining) {\n length = remaining\n }\n }\n\n // must be an even number of digits\n var strLen = string.length\n if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')\n\n if (length > strLen / 2) {\n length = strLen / 2\n }\n for (var i = 0; i < length; ++i) {\n var parsed = parseInt(string.substr(i * 2, 2), 16)\n if (isNaN(parsed)) return i\n buf[offset + i] = parsed\n }\n return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction latin1Write (buf, string, offset, length) {\n return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n // Buffer#write(string)\n if (offset === undefined) {\n encoding = 'utf8'\n length = this.length\n offset = 0\n // Buffer#write(string, encoding)\n } else if (length === undefined && typeof offset === 'string') {\n encoding = offset\n length = this.length\n offset = 0\n // Buffer#write(string, offset[, length][, encoding])\n } else if (isFinite(offset)) {\n offset = offset | 0\n if (isFinite(length)) {\n length = length | 0\n if (encoding === undefined) encoding = 'utf8'\n } else {\n encoding = length\n length = undefined\n }\n // legacy write(string, encoding, offset, length) - remove in v0.13\n } else {\n throw new Error(\n 'Buffer.write(string, encoding, offset[, length]) is no longer supported'\n )\n }\n\n var remaining = this.length - offset\n if (length === undefined || length > remaining) length = remaining\n\n if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n throw new RangeError('Attempt to write outside buffer bounds')\n }\n\n if (!encoding) encoding = 'utf8'\n\n var loweredCase = false\n for (;;) {\n switch (encoding) {\n case 'hex':\n return hexWrite(this, string, offset, length)\n\n case 'utf8':\n case 'utf-8':\n return utf8Write(this, string, offset, length)\n\n case 'ascii':\n return asciiWrite(this, string, offset, length)\n\n case 'latin1':\n case 'binary':\n return latin1Write(this, string, offset, length)\n\n case 'base64':\n // Warning: maxLength not taken into account in base64Write\n return base64Write(this, string, offset, length)\n\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return ucs2Write(this, string, offset, length)\n\n default:\n if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n encoding = ('' + encoding).toLowerCase()\n loweredCase = true\n }\n }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n return {\n type: 'Buffer',\n data: Array.prototype.slice.call(this._arr || this, 0)\n }\n}\n\nfunction base64Slice (buf, start, end) {\n if (start === 0 && end === buf.length) {\n return base64.fromByteArray(buf)\n } else {\n return base64.fromByteArray(buf.slice(start, end))\n }\n}\n\nfunction utf8Slice (buf, start, end) {\n end = Math.min(buf.length, end)\n var res = []\n\n var i = start\n while (i < end) {\n var firstByte = buf[i]\n var codePoint = null\n var bytesPerSequence = (firstByte > 0xEF) ? 4\n : (firstByte > 0xDF) ? 3\n : (firstByte > 0xBF) ? 2\n : 1\n\n if (i + bytesPerSequence <= end) {\n var secondByte, thirdByte, fourthByte, tempCodePoint\n\n switch (bytesPerSequence) {\n case 1:\n if (firstByte < 0x80) {\n codePoint = firstByte\n }\n break\n case 2:\n secondByte = buf[i + 1]\n if ((secondByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n if (tempCodePoint > 0x7F) {\n codePoint = tempCodePoint\n }\n }\n break\n case 3:\n secondByte = buf[i + 1]\n thirdByte = buf[i + 2]\n if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n codePoint = tempCodePoint\n }\n }\n break\n case 4:\n secondByte = buf[i + 1]\n thirdByte = buf[i + 2]\n fourthByte = buf[i + 3]\n if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n codePoint = tempCodePoint\n }\n }\n }\n }\n\n if (codePoint === null) {\n // we did not generate a valid codePoint so insert a\n // replacement char (U+FFFD) and advance only 1 byte\n codePoint = 0xFFFD\n bytesPerSequence = 1\n } else if (codePoint > 0xFFFF) {\n // encode to utf16 (surrogate pair dance)\n codePoint -= 0x10000\n res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n codePoint = 0xDC00 | codePoint & 0x3FF\n }\n\n res.push(codePoint)\n i += bytesPerSequence\n }\n\n return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n var len = codePoints.length\n if (len <= MAX_ARGUMENTS_LENGTH) {\n return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n }\n\n // Decode in chunks to avoid \"call stack size exceeded\".\n var res = ''\n var i = 0\n while (i < len) {\n res += String.fromCharCode.apply(\n String,\n codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n )\n }\n return res\n}\n\nfunction asciiSlice (buf, start, end) {\n var ret = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; ++i) {\n ret += String.fromCharCode(buf[i] & 0x7F)\n }\n return ret\n}\n\nfunction latin1Slice (buf, start, end) {\n var ret = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; ++i) {\n ret += String.fromCharCode(buf[i])\n }\n return ret\n}\n\nfunction hexSlice (buf, start, end) {\n var len = buf.length\n\n if (!start || start < 0) start = 0\n if (!end || end < 0 || end > len) end = len\n\n var out = ''\n for (var i = start; i < end; ++i) {\n out += toHex(buf[i])\n }\n return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n var bytes = buf.slice(start, end)\n var res = ''\n for (var i = 0; i < bytes.length; i += 2) {\n res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n }\n return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n var len = this.length\n start = ~~start\n end = end === undefined ? len : ~~end\n\n if (start < 0) {\n start += len\n if (start < 0) start = 0\n } else if (start > len) {\n start = len\n }\n\n if (end < 0) {\n end += len\n if (end < 0) end = 0\n } else if (end > len) {\n end = len\n }\n\n if (end < start) end = start\n\n var newBuf\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n newBuf = this.subarray(start, end)\n newBuf.__proto__ = Buffer.prototype\n } else {\n var sliceLen = end - start\n newBuf = new Buffer(sliceLen, undefined)\n for (var i = 0; i < sliceLen; ++i) {\n newBuf[i] = this[i + start]\n }\n }\n\n return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var val = this[offset]\n var mul = 1\n var i = 0\n while (++i < byteLength && (mul *= 0x100)) {\n val += this[offset + i] * mul\n }\n\n return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n checkOffset(offset, byteLength, this.length)\n }\n\n var val = this[offset + --byteLength]\n var mul = 1\n while (byteLength > 0 && (mul *= 0x100)) {\n val += this[offset + --byteLength] * mul\n }\n\n return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 1, this.length)\n return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return ((this[offset]) |\n (this[offset + 1] << 8) |\n (this[offset + 2] << 16)) +\n (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset] * 0x1000000) +\n ((this[offset + 1] << 16) |\n (this[offset + 2] << 8) |\n this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var val = this[offset]\n var mul = 1\n var i = 0\n while (++i < byteLength && (mul *= 0x100)) {\n val += this[offset + i] * mul\n }\n mul *= 0x80\n\n if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var i = byteLength\n var mul = 1\n var val = this[offset + --i]\n while (i > 0 && (mul *= 0x100)) {\n val += this[offset + --i] * mul\n }\n mul *= 0x80\n\n if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 1, this.length)\n if (!(this[offset] & 0x80)) return (this[offset])\n return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n var val = this[offset] | (this[offset + 1] << 8)\n return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n var val = this[offset + 1] | (this[offset] << 8)\n return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset]) |\n (this[offset + 1] << 8) |\n (this[offset + 2] << 16) |\n (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset] << 24) |\n (this[offset + 1] << 16) |\n (this[offset + 2] << 8) |\n (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 8, this.length)\n return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 8, this.length)\n return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n if (!Buffer.isBuffer(buf)) throw new TypeError('\"buffer\" argument must be a Buffer instance')\n if (value > max || value < min) throw new RangeError('\"value\" argument is out of bounds')\n if (offset + ext > buf.length) throw new RangeError('Index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n var maxBytes = Math.pow(2, 8 * byteLength) - 1\n checkInt(this, value, offset, byteLength, maxBytes, 0)\n }\n\n var mul = 1\n var i = 0\n this[offset] = value & 0xFF\n while (++i < byteLength && (mul *= 0x100)) {\n this[offset + i] = (value / mul) & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n var maxBytes = Math.pow(2, 8 * byteLength) - 1\n checkInt(this, value, offset, byteLength, maxBytes, 0)\n }\n\n var i = byteLength - 1\n var mul = 1\n this[offset + i] = value & 0xFF\n while (--i >= 0 && (mul *= 0x100)) {\n this[offset + i] = (value / mul) & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n this[offset] = (value & 0xff)\n return offset + 1\n}\n\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\n if (value < 0) value = 0xffff + value + 1\n for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {\n buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n (littleEndian ? i : 1 - i) * 8\n }\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n } else {\n objectWriteUInt16(this, value, offset, true)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 8)\n this[offset + 1] = (value & 0xff)\n } else {\n objectWriteUInt16(this, value, offset, false)\n }\n return offset + 2\n}\n\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\n if (value < 0) value = 0xffffffff + value + 1\n for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {\n buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n }\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset + 3] = (value >>> 24)\n this[offset + 2] = (value >>> 16)\n this[offset + 1] = (value >>> 8)\n this[offset] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, true)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 24)\n this[offset + 1] = (value >>> 16)\n this[offset + 2] = (value >>> 8)\n this[offset + 3] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, false)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) {\n var limit = Math.pow(2, 8 * byteLength - 1)\n\n checkInt(this, value, offset, byteLength, limit - 1, -limit)\n }\n\n var i = 0\n var mul = 1\n var sub = 0\n this[offset] = value & 0xFF\n while (++i < byteLength && (mul *= 0x100)) {\n if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {\n sub = 1\n }\n this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) {\n var limit = Math.pow(2, 8 * byteLength - 1)\n\n checkInt(this, value, offset, byteLength, limit - 1, -limit)\n }\n\n var i = byteLength - 1\n var mul = 1\n var sub = 0\n this[offset + i] = value & 0xFF\n while (--i >= 0 && (mul *= 0x100)) {\n if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {\n sub = 1\n }\n this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n if (value < 0) value = 0xff + value + 1\n this[offset] = (value & 0xff)\n return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n } else {\n objectWriteUInt16(this, value, offset, true)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 8)\n this[offset + 1] = (value & 0xff)\n } else {\n objectWriteUInt16(this, value, offset, false)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n this[offset + 2] = (value >>> 16)\n this[offset + 3] = (value >>> 24)\n } else {\n objectWriteUInt32(this, value, offset, true)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n if (value < 0) value = 0xffffffff + value + 1\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 24)\n this[offset + 1] = (value >>> 16)\n this[offset + 2] = (value >>> 8)\n this[offset + 3] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, false)\n }\n return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n if (offset + ext > buf.length) throw new RangeError('Index out of range')\n if (offset < 0) throw new RangeError('Index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n }\n ieee754.write(buf, value, offset, littleEndian, 23, 4)\n return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n }\n ieee754.write(buf, value, offset, littleEndian, 52, 8)\n return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n if (!start) start = 0\n if (!end && end !== 0) end = this.length\n if (targetStart >= target.length) targetStart = target.length\n if (!targetStart) targetStart = 0\n if (end > 0 && end < start) end = start\n\n // Copy 0 bytes; we're done\n if (end === start) return 0\n if (target.length === 0 || this.length === 0) return 0\n\n // Fatal error conditions\n if (targetStart < 0) {\n throw new RangeError('targetStart out of bounds')\n }\n if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\n if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n // Are we oob?\n if (end > this.length) end = this.length\n if (target.length - targetStart < end - start) {\n end = target.length - targetStart + start\n }\n\n var len = end - start\n var i\n\n if (this === target && start < targetStart && targetStart < end) {\n // descending copy from end\n for (i = len - 1; i >= 0; --i) {\n target[i + targetStart] = this[i + start]\n }\n } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\n // ascending copy from start\n for (i = 0; i < len; ++i) {\n target[i + targetStart] = this[i + start]\n }\n } else {\n Uint8Array.prototype.set.call(\n target,\n this.subarray(start, start + len),\n targetStart\n )\n }\n\n return len\n}\n\n// Usage:\n// buffer.fill(number[, offset[, end]])\n// buffer.fill(buffer[, offset[, end]])\n// buffer.fill(string[, offset[, end]][, encoding])\nBuffer.prototype.fill = function fill (val, start, end, encoding) {\n // Handle string cases:\n if (typeof val === 'string') {\n if (typeof start === 'string') {\n encoding = start\n start = 0\n end = this.length\n } else if (typeof end === 'string') {\n encoding = end\n end = this.length\n }\n if (val.length === 1) {\n var code = val.charCodeAt(0)\n if (code < 256) {\n val = code\n }\n }\n if (encoding !== undefined && typeof encoding !== 'string') {\n throw new TypeError('encoding must be a string')\n }\n if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {\n throw new TypeError('Unknown encoding: ' + encoding)\n }\n } else if (typeof val === 'number') {\n val = val & 255\n }\n\n // Invalid ranges are not set to a default, so can range check early.\n if (start < 0 || this.length < start || this.length < end) {\n throw new RangeError('Out of range index')\n }\n\n if (end <= start) {\n return this\n }\n\n start = start >>> 0\n end = end === undefined ? this.length : end >>> 0\n\n if (!val) val = 0\n\n var i\n if (typeof val === 'number') {\n for (i = start; i < end; ++i) {\n this[i] = val\n }\n } else {\n var bytes = Buffer.isBuffer(val)\n ? val\n : utf8ToBytes(new Buffer(val, encoding).toString())\n var len = bytes.length\n for (i = 0; i < end - start; ++i) {\n this[i + start] = bytes[i % len]\n }\n }\n\n return this\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n str = stringtrim(str).replace(INVALID_BASE64_RE, '')\n // Node converts strings with length < 2 to ''\n if (str.length < 2) return ''\n // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n while (str.length % 4 !== 0) {\n str = str + '='\n }\n return str\n}\n\nfunction stringtrim (str) {\n if (str.trim) return str.trim()\n return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nfunction toHex (n) {\n if (n < 16) return '0' + n.toString(16)\n return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n units = units || Infinity\n var codePoint\n var length = string.length\n var leadSurrogate = null\n var bytes = []\n\n for (var i = 0; i < length; ++i) {\n codePoint = string.charCodeAt(i)\n\n // is surrogate component\n if (codePoint > 0xD7FF && codePoint < 0xE000) {\n // last char was a lead\n if (!leadSurrogate) {\n // no lead yet\n if (codePoint > 0xDBFF) {\n // unexpected trail\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n continue\n } else if (i + 1 === length) {\n // unpaired lead\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n continue\n }\n\n // valid lead\n leadSurrogate = codePoint\n\n continue\n }\n\n // 2 leads in a row\n if (codePoint < 0xDC00) {\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n leadSurrogate = codePoint\n continue\n }\n\n // valid surrogate pair\n codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000\n } else if (leadSurrogate) {\n // valid bmp char, but last char was a lead\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n }\n\n leadSurrogate = null\n\n // encode utf8\n if (codePoint < 0x80) {\n if ((units -= 1) < 0) break\n bytes.push(codePoint)\n } else if (codePoint < 0x800) {\n if ((units -= 2) < 0) break\n bytes.push(\n codePoint >> 0x6 | 0xC0,\n codePoint & 0x3F | 0x80\n )\n } else if (codePoint < 0x10000) {\n if ((units -= 3) < 0) break\n bytes.push(\n codePoint >> 0xC | 0xE0,\n codePoint >> 0x6 & 0x3F | 0x80,\n codePoint & 0x3F | 0x80\n )\n } else if (codePoint < 0x110000) {\n if ((units -= 4) < 0) break\n bytes.push(\n codePoint >> 0x12 | 0xF0,\n codePoint >> 0xC & 0x3F | 0x80,\n codePoint >> 0x6 & 0x3F | 0x80,\n codePoint & 0x3F | 0x80\n )\n } else {\n throw new Error('Invalid code point')\n }\n }\n\n return bytes\n}\n\nfunction asciiToBytes (str) {\n var byteArray = []\n for (var i = 0; i < str.length; ++i) {\n // Node's code seems to be doing this and not & 0x7F..\n byteArray.push(str.charCodeAt(i) & 0xFF)\n }\n return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n var c, hi, lo\n var byteArray = []\n for (var i = 0; i < str.length; ++i) {\n if ((units -= 2) < 0) break\n\n c = str.charCodeAt(i)\n hi = c >> 8\n lo = c % 256\n byteArray.push(lo)\n byteArray.push(hi)\n }\n\n return byteArray\n}\n\nfunction base64ToBytes (str) {\n return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n for (var i = 0; i < length; ++i) {\n if ((i + offset >= dst.length) || (i >= src.length)) break\n dst[i + offset] = src[i]\n }\n return i\n}\n\nfunction isnan (val) {\n return val !== val // eslint-disable-line no-self-compare\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYnVmZmVyL2luZGV4LmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvYnVmZmVyL2luZGV4LmpzP2I2MzkiXSwic291cmNlc0NvbnRlbnQiOlsiLyohXG4gKiBUaGUgYnVmZmVyIG1vZHVsZSBmcm9tIG5vZGUuanMsIGZvciB0aGUgYnJvd3Nlci5cbiAqXG4gKiBAYXV0aG9yICAgRmVyb3NzIEFib3VraGFkaWplaCA8ZmVyb3NzQGZlcm9zcy5vcmc+IDxodHRwOi8vZmVyb3NzLm9yZz5cbiAqIEBsaWNlbnNlICBNSVRcbiAqL1xuLyogZXNsaW50LWRpc2FibGUgbm8tcHJvdG8gKi9cblxuJ3VzZSBzdHJpY3QnXG5cbnZhciBiYXNlNjQgPSByZXF1aXJlKCdiYXNlNjQtanMnKVxudmFyIGllZWU3NTQgPSByZXF1aXJlKCdpZWVlNzU0JylcbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnaXNhcnJheScpXG5cbmV4cG9ydHMuQnVmZmVyID0gQnVmZmVyXG5leHBvcnRzLlNsb3dCdWZmZXIgPSBTbG93QnVmZmVyXG5leHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTID0gNTBcblxuLyoqXG4gKiBJZiBgQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRgOlxuICogICA9PT0gdHJ1ZSAgICBVc2UgVWludDhBcnJheSBpbXBsZW1lbnRhdGlvbiAoZmFzdGVzdClcbiAqICAgPT09IGZhbHNlICAgVXNlIE9iamVjdCBpbXBsZW1lbnRhdGlvbiAobW9zdCBjb21wYXRpYmxlLCBldmVuIElFNilcbiAqXG4gKiBCcm93c2VycyB0aGF0IHN1cHBvcnQgdHlwZWQgYXJyYXlzIGFyZSBJRSAxMCssIEZpcmVmb3ggNCssIENocm9tZSA3KywgU2FmYXJpIDUuMSssXG4gKiBPcGVyYSAxMS42KywgaU9TIDQuMisuXG4gKlxuICogRHVlIHRvIHZhcmlvdXMgYnJvd3NlciBidWdzLCBzb21ldGltZXMgdGhlIE9iamVjdCBpbXBsZW1lbnRhdGlvbiB3aWxsIGJlIHVzZWQgZXZlblxuICogd2hlbiB0aGUgYnJvd3NlciBzdXBwb3J0cyB0eXBlZCBhcnJheXMuXG4gKlxuICogTm90ZTpcbiAqXG4gKiAgIC0gRmlyZWZveCA0LTI5IGxhY2tzIHN1cHBvcnQgZm9yIGFkZGluZyBuZXcgcHJvcGVydGllcyB0byBgVWludDhBcnJheWAgaW5zdGFuY2VzLFxuICogICAgIFNlZTogaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9Njk1NDM4LlxuICpcbiAqICAgLSBDaHJvbWUgOS0xMCBpcyBtaXNzaW5nIHRoZSBgVHlwZWRBcnJheS5wcm90b3R5cGUuc3ViYXJyYXlgIGZ1bmN0aW9uLlxuICpcbiAqICAgLSBJRTEwIGhhcyBhIGJyb2tlbiBgVHlwZWRBcnJheS5wcm90b3R5cGUuc3ViYXJyYXlgIGZ1bmN0aW9uIHdoaWNoIHJldHVybnMgYXJyYXlzIG9mXG4gKiAgICAgaW5jb3JyZWN0IGxlbmd0aCBpbiBzb21lIHNpdHVhdGlvbnMuXG5cbiAqIFdlIGRldGVjdCB0aGVzZSBidWdneSBicm93c2VycyBhbmQgc2V0IGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGAgdG8gYGZhbHNlYCBzbyB0aGV5XG4gKiBnZXQgdGhlIE9iamVjdCBpbXBsZW1lbnRhdGlvbiwgd2hpY2ggaXMgc2xvd2VyIGJ1dCBiZWhhdmVzIGNvcnJlY3RseS5cbiAqL1xuQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgPSBnbG9iYWwuVFlQRURfQVJSQVlfU1VQUE9SVCAhPT0gdW5kZWZpbmVkXG4gID8gZ2xvYmFsLlRZUEVEX0FSUkFZX1NVUFBPUlRcbiAgOiB0eXBlZEFycmF5U3VwcG9ydCgpXG5cbi8qXG4gKiBFeHBvcnQga01heExlbmd0aCBhZnRlciB0eXBlZCBhcnJheSBzdXBwb3J0IGlzIGRldGVybWluZWQuXG4gKi9cbmV4cG9ydHMua01heExlbmd0aCA9IGtNYXhMZW5ndGgoKVxuXG5mdW5jdGlvbiB0eXBlZEFycmF5U3VwcG9ydCAoKSB7XG4gIHRyeSB7XG4gICAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KDEpXG4gICAgYXJyLl9fcHJvdG9fXyA9IHtfX3Byb3RvX186IFVpbnQ4QXJyYXkucHJvdG90eXBlLCBmb286IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDQyIH19XG4gICAgcmV0dXJuIGFyci5mb28oKSA9PT0gNDIgJiYgLy8gdHlwZWQgYXJyYXkgaW5zdGFuY2VzIGNhbiBiZSBhdWdtZW50ZWRcbiAgICAgICAgdHlwZW9mIGFyci5zdWJhcnJheSA9PT0gJ2Z1bmN0aW9uJyAmJiAvLyBjaHJvbWUgOS0xMCBsYWNrIGBzdWJhcnJheWBcbiAgICAgICAgYXJyLnN1YmFycmF5KDEsIDEpLmJ5dGVMZW5ndGggPT09IDAgLy8gaWUxMCBoYXMgYnJva2VuIGBzdWJhcnJheWBcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbmZ1bmN0aW9uIGtNYXhMZW5ndGggKCkge1xuICByZXR1cm4gQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRcbiAgICA/IDB4N2ZmZmZmZmZcbiAgICA6IDB4M2ZmZmZmZmZcbn1cblxuZnVuY3Rpb24gY3JlYXRlQnVmZmVyICh0aGF0LCBsZW5ndGgpIHtcbiAgaWYgKGtNYXhMZW5ndGgoKSA8IGxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbnZhbGlkIHR5cGVkIGFycmF5IGxlbmd0aCcpXG4gIH1cbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2UsIGZvciBiZXN0IHBlcmZvcm1hbmNlXG4gICAgdGhhdCA9IG5ldyBVaW50OEFycmF5KGxlbmd0aClcbiAgICB0aGF0Ll9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgfSBlbHNlIHtcbiAgICAvLyBGYWxsYmFjazogUmV0dXJuIGFuIG9iamVjdCBpbnN0YW5jZSBvZiB0aGUgQnVmZmVyIGNsYXNzXG4gICAgaWYgKHRoYXQgPT09IG51bGwpIHtcbiAgICAgIHRoYXQgPSBuZXcgQnVmZmVyKGxlbmd0aClcbiAgICB9XG4gICAgdGhhdC5sZW5ndGggPSBsZW5ndGhcbiAgfVxuXG4gIHJldHVybiB0aGF0XG59XG5cbi8qKlxuICogVGhlIEJ1ZmZlciBjb25zdHJ1Y3RvciByZXR1cm5zIGluc3RhbmNlcyBvZiBgVWludDhBcnJheWAgdGhhdCBoYXZlIHRoZWlyXG4gKiBwcm90b3R5cGUgY2hhbmdlZCB0byBgQnVmZmVyLnByb3RvdHlwZWAuIEZ1cnRoZXJtb3JlLCBgQnVmZmVyYCBpcyBhIHN1YmNsYXNzIG9mXG4gKiBgVWludDhBcnJheWAsIHNvIHRoZSByZXR1cm5lZCBpbnN0YW5jZXMgd2lsbCBoYXZlIGFsbCB0aGUgbm9kZSBgQnVmZmVyYCBtZXRob2RzXG4gKiBhbmQgdGhlIGBVaW50OEFycmF5YCBtZXRob2RzLiBTcXVhcmUgYnJhY2tldCBub3RhdGlvbiB3b3JrcyBhcyBleHBlY3RlZCAtLSBpdFxuICogcmV0dXJucyBhIHNpbmdsZSBvY3RldC5cbiAqXG4gKiBUaGUgYFVpbnQ4QXJyYXlgIHByb3RvdHlwZSByZW1haW5zIHVubW9kaWZpZWQuXG4gKi9cblxuZnVuY3Rpb24gQnVmZmVyIChhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUICYmICEodGhpcyBpbnN0YW5jZW9mIEJ1ZmZlcikpIHtcbiAgICByZXR1cm4gbmV3IEJ1ZmZlcihhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIC8vIENvbW1vbiBjYXNlLlxuICBpZiAodHlwZW9mIGFyZyA9PT0gJ251bWJlcicpIHtcbiAgICBpZiAodHlwZW9mIGVuY29kaW5nT3JPZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdJZiBlbmNvZGluZyBpcyBzcGVjaWZpZWQgdGhlbiB0aGUgZmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZydcbiAgICAgIClcbiAgICB9XG4gICAgcmV0dXJuIGFsbG9jVW5zYWZlKHRoaXMsIGFyZylcbiAgfVxuICByZXR1cm4gZnJvbSh0aGlzLCBhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuQnVmZmVyLnBvb2xTaXplID0gODE5MiAvLyBub3QgdXNlZCBieSB0aGlzIGltcGxlbWVudGF0aW9uXG5cbi8vIFRPRE86IExlZ2FjeSwgbm90IG5lZWRlZCBhbnltb3JlLiBSZW1vdmUgaW4gbmV4dCBtYWpvciB2ZXJzaW9uLlxuQnVmZmVyLl9hdWdtZW50ID0gZnVuY3Rpb24gKGFycikge1xuICBhcnIuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICByZXR1cm4gYXJyXG59XG5cbmZ1bmN0aW9uIGZyb20gKHRoYXQsIHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcInZhbHVlXCIgYXJndW1lbnQgbXVzdCBub3QgYmUgYSBudW1iZXInKVxuICB9XG5cbiAgaWYgKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcgJiYgdmFsdWUgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuICAgIHJldHVybiBmcm9tQXJyYXlCdWZmZXIodGhhdCwgdmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGZyb21TdHJpbmcodGhhdCwgdmFsdWUsIGVuY29kaW5nT3JPZmZzZXQpXG4gIH1cblxuICByZXR1cm4gZnJvbU9iamVjdCh0aGF0LCB2YWx1ZSlcbn1cblxuLyoqXG4gKiBGdW5jdGlvbmFsbHkgZXF1aXZhbGVudCB0byBCdWZmZXIoYXJnLCBlbmNvZGluZykgYnV0IHRocm93cyBhIFR5cGVFcnJvclxuICogaWYgdmFsdWUgaXMgYSBudW1iZXIuXG4gKiBCdWZmZXIuZnJvbShzdHJbLCBlbmNvZGluZ10pXG4gKiBCdWZmZXIuZnJvbShhcnJheSlcbiAqIEJ1ZmZlci5mcm9tKGJ1ZmZlcilcbiAqIEJ1ZmZlci5mcm9tKGFycmF5QnVmZmVyWywgYnl0ZU9mZnNldFssIGxlbmd0aF1dKVxuICoqL1xuQnVmZmVyLmZyb20gPSBmdW5jdGlvbiAodmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gZnJvbShudWxsLCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxufVxuXG5pZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgQnVmZmVyLnByb3RvdHlwZS5fX3Byb3RvX18gPSBVaW50OEFycmF5LnByb3RvdHlwZVxuICBCdWZmZXIuX19wcm90b19fID0gVWludDhBcnJheVxuICBpZiAodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnNwZWNpZXMgJiZcbiAgICAgIEJ1ZmZlcltTeW1ib2wuc3BlY2llc10gPT09IEJ1ZmZlcikge1xuICAgIC8vIEZpeCBzdWJhcnJheSgpIGluIEVTMjAxNi4gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlci9wdWxsLzk3XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEJ1ZmZlciwgU3ltYm9sLnNwZWNpZXMsIHtcbiAgICAgIHZhbHVlOiBudWxsLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSlcbiAgfVxufVxuXG5mdW5jdGlvbiBhc3NlcnRTaXplIChzaXplKSB7XG4gIGlmICh0eXBlb2Ygc2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcInNpemVcIiBhcmd1bWVudCBtdXN0IGJlIGEgbnVtYmVyJylcbiAgfSBlbHNlIGlmIChzaXplIDwgMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcInNpemVcIiBhcmd1bWVudCBtdXN0IG5vdCBiZSBuZWdhdGl2ZScpXG4gIH1cbn1cblxuZnVuY3Rpb24gYWxsb2MgKHRoYXQsIHNpemUsIGZpbGwsIGVuY29kaW5nKSB7XG4gIGFzc2VydFNpemUoc2l6ZSlcbiAgaWYgKHNpemUgPD0gMCkge1xuICAgIHJldHVybiBjcmVhdGVCdWZmZXIodGhhdCwgc2l6ZSlcbiAgfVxuICBpZiAoZmlsbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gT25seSBwYXkgYXR0ZW50aW9uIHRvIGVuY29kaW5nIGlmIGl0J3MgYSBzdHJpbmcuIFRoaXNcbiAgICAvLyBwcmV2ZW50cyBhY2NpZGVudGFsbHkgc2VuZGluZyBpbiBhIG51bWJlciB0aGF0IHdvdWxkXG4gICAgLy8gYmUgaW50ZXJwcmV0dGVkIGFzIGEgc3RhcnQgb2Zmc2V0LlxuICAgIHJldHVybiB0eXBlb2YgZW5jb2RpbmcgPT09ICdzdHJpbmcnXG4gICAgICA/IGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplKS5maWxsKGZpbGwsIGVuY29kaW5nKVxuICAgICAgOiBjcmVhdGVCdWZmZXIodGhhdCwgc2l6ZSkuZmlsbChmaWxsKVxuICB9XG4gIHJldHVybiBjcmVhdGVCdWZmZXIodGhhdCwgc2l6ZSlcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKiBhbGxvYyhzaXplWywgZmlsbFssIGVuY29kaW5nXV0pXG4gKiovXG5CdWZmZXIuYWxsb2MgPSBmdW5jdGlvbiAoc2l6ZSwgZmlsbCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIGFsbG9jKG51bGwsIHNpemUsIGZpbGwsIGVuY29kaW5nKVxufVxuXG5mdW5jdGlvbiBhbGxvY1Vuc2FmZSAodGhhdCwgc2l6ZSkge1xuICBhc3NlcnRTaXplKHNpemUpXG4gIHRoYXQgPSBjcmVhdGVCdWZmZXIodGhhdCwgc2l6ZSA8IDAgPyAwIDogY2hlY2tlZChzaXplKSB8IDApXG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNpemU7ICsraSkge1xuICAgICAgdGhhdFtpXSA9IDBcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuLyoqXG4gKiBFcXVpdmFsZW50IHRvIEJ1ZmZlcihudW0pLCBieSBkZWZhdWx0IGNyZWF0ZXMgYSBub24temVyby1maWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICogKi9cbkJ1ZmZlci5hbGxvY1Vuc2FmZSA9IGZ1bmN0aW9uIChzaXplKSB7XG4gIHJldHVybiBhbGxvY1Vuc2FmZShudWxsLCBzaXplKVxufVxuLyoqXG4gKiBFcXVpdmFsZW50IHRvIFNsb3dCdWZmZXIobnVtKSwgYnkgZGVmYXVsdCBjcmVhdGVzIGEgbm9uLXplcm8tZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqL1xuQnVmZmVyLmFsbG9jVW5zYWZlU2xvdyA9IGZ1bmN0aW9uIChzaXplKSB7XG4gIHJldHVybiBhbGxvY1Vuc2FmZShudWxsLCBzaXplKVxufVxuXG5mdW5jdGlvbiBmcm9tU3RyaW5nICh0aGF0LCBzdHJpbmcsIGVuY29kaW5nKSB7XG4gIGlmICh0eXBlb2YgZW5jb2RpbmcgIT09ICdzdHJpbmcnIHx8IGVuY29kaW5nID09PSAnJykge1xuICAgIGVuY29kaW5nID0gJ3V0ZjgnXG4gIH1cblxuICBpZiAoIUJ1ZmZlci5pc0VuY29kaW5nKGVuY29kaW5nKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiZW5jb2RpbmdcIiBtdXN0IGJlIGEgdmFsaWQgc3RyaW5nIGVuY29kaW5nJylcbiAgfVxuXG4gIHZhciBsZW5ndGggPSBieXRlTGVuZ3RoKHN0cmluZywgZW5jb2RpbmcpIHwgMFxuICB0aGF0ID0gY3JlYXRlQnVmZmVyKHRoYXQsIGxlbmd0aClcblxuICB2YXIgYWN0dWFsID0gdGhhdC53cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuXG4gIGlmIChhY3R1YWwgIT09IGxlbmd0aCkge1xuICAgIC8vIFdyaXRpbmcgYSBoZXggc3RyaW5nLCBmb3IgZXhhbXBsZSwgdGhhdCBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlcnMgd2lsbFxuICAgIC8vIGNhdXNlIGV2ZXJ5dGhpbmcgYWZ0ZXIgdGhlIGZpcnN0IGludmFsaWQgY2hhcmFjdGVyIHRvIGJlIGlnbm9yZWQuIChlLmcuXG4gICAgLy8gJ2FieHhjZCcgd2lsbCBiZSB0cmVhdGVkIGFzICdhYicpXG4gICAgdGhhdCA9IHRoYXQuc2xpY2UoMCwgYWN0dWFsKVxuICB9XG5cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5TGlrZSAodGhhdCwgYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCA8IDAgPyAwIDogY2hlY2tlZChhcnJheS5sZW5ndGgpIHwgMFxuICB0aGF0ID0gY3JlYXRlQnVmZmVyKHRoYXQsIGxlbmd0aClcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoYXRbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUJ1ZmZlciAodGhhdCwgYXJyYXksIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICBhcnJheS5ieXRlTGVuZ3RoIC8vIHRoaXMgdGhyb3dzIGlmIGBhcnJheWAgaXMgbm90IGEgdmFsaWQgQXJyYXlCdWZmZXJcblxuICBpZiAoYnl0ZU9mZnNldCA8IDAgfHwgYXJyYXkuYnl0ZUxlbmd0aCA8IGJ5dGVPZmZzZXQpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXFwnb2Zmc2V0XFwnIGlzIG91dCBvZiBib3VuZHMnKVxuICB9XG5cbiAgaWYgKGFycmF5LmJ5dGVMZW5ndGggPCBieXRlT2Zmc2V0ICsgKGxlbmd0aCB8fCAwKSkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcXCdsZW5ndGhcXCcgaXMgb3V0IG9mIGJvdW5kcycpXG4gIH1cblxuICBpZiAoYnl0ZU9mZnNldCA9PT0gdW5kZWZpbmVkICYmIGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgYXJyYXkgPSBuZXcgVWludDhBcnJheShhcnJheSlcbiAgfSBlbHNlIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXksIGJ5dGVPZmZzZXQpXG4gIH0gZWxzZSB7XG4gICAgYXJyYXkgPSBuZXcgVWludDhBcnJheShhcnJheSwgYnl0ZU9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2UsIGZvciBiZXN0IHBlcmZvcm1hbmNlXG4gICAgdGhhdCA9IGFycmF5XG4gICAgdGhhdC5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIH0gZWxzZSB7XG4gICAgLy8gRmFsbGJhY2s6IFJldHVybiBhbiBvYmplY3QgaW5zdGFuY2Ugb2YgdGhlIEJ1ZmZlciBjbGFzc1xuICAgIHRoYXQgPSBmcm9tQXJyYXlMaWtlKHRoYXQsIGFycmF5KVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21PYmplY3QgKHRoYXQsIG9iaikge1xuICBpZiAoQnVmZmVyLmlzQnVmZmVyKG9iaikpIHtcbiAgICB2YXIgbGVuID0gY2hlY2tlZChvYmoubGVuZ3RoKSB8IDBcbiAgICB0aGF0ID0gY3JlYXRlQnVmZmVyKHRoYXQsIGxlbilcblxuICAgIGlmICh0aGF0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHRoYXRcbiAgICB9XG5cbiAgICBvYmouY29weSh0aGF0LCAwLCAwLCBsZW4pXG4gICAgcmV0dXJuIHRoYXRcbiAgfVxuXG4gIGlmIChvYmopIHtcbiAgICBpZiAoKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgICAgb2JqLmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB8fCAnbGVuZ3RoJyBpbiBvYmopIHtcbiAgICAgIGlmICh0eXBlb2Ygb2JqLmxlbmd0aCAhPT0gJ251bWJlcicgfHwgaXNuYW4ob2JqLmxlbmd0aCkpIHtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcih0aGF0LCAwKVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZyb21BcnJheUxpa2UodGhhdCwgb2JqKVxuICAgIH1cblxuICAgIGlmIChvYmoudHlwZSA9PT0gJ0J1ZmZlcicgJiYgaXNBcnJheShvYmouZGF0YSkpIHtcbiAgICAgIHJldHVybiBmcm9tQXJyYXlMaWtlKHRoYXQsIG9iai5kYXRhKVxuICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYSBzdHJpbmcsIEJ1ZmZlciwgQXJyYXlCdWZmZXIsIEFycmF5LCBvciBhcnJheS1saWtlIG9iamVjdC4nKVxufVxuXG5mdW5jdGlvbiBjaGVja2VkIChsZW5ndGgpIHtcbiAgLy8gTm90ZTogY2Fubm90IHVzZSBgbGVuZ3RoIDwga01heExlbmd0aCgpYCBoZXJlIGJlY2F1c2UgdGhhdCBmYWlscyB3aGVuXG4gIC8vIGxlbmd0aCBpcyBOYU4gKHdoaWNoIGlzIG90aGVyd2lzZSBjb2VyY2VkIHRvIHplcm8uKVxuICBpZiAobGVuZ3RoID49IGtNYXhMZW5ndGgoKSkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBdHRlbXB0IHRvIGFsbG9jYXRlIEJ1ZmZlciBsYXJnZXIgdGhhbiBtYXhpbXVtICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICdzaXplOiAweCcgKyBrTWF4TGVuZ3RoKCkudG9TdHJpbmcoMTYpICsgJyBieXRlcycpXG4gIH1cbiAgcmV0dXJuIGxlbmd0aCB8IDBcbn1cblxuZnVuY3Rpb24gU2xvd0J1ZmZlciAobGVuZ3RoKSB7XG4gIGlmICgrbGVuZ3RoICE9IGxlbmd0aCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGVxZXFlcVxuICAgIGxlbmd0aCA9IDBcbiAgfVxuICByZXR1cm4gQnVmZmVyLmFsbG9jKCtsZW5ndGgpXG59XG5cbkJ1ZmZlci5pc0J1ZmZlciA9IGZ1bmN0aW9uIGlzQnVmZmVyIChiKSB7XG4gIHJldHVybiAhIShiICE9IG51bGwgJiYgYi5faXNCdWZmZXIpXG59XG5cbkJ1ZmZlci5jb21wYXJlID0gZnVuY3Rpb24gY29tcGFyZSAoYSwgYikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihhKSB8fCAhQnVmZmVyLmlzQnVmZmVyKGIpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnRzIG11c3QgYmUgQnVmZmVycycpXG4gIH1cblxuICBpZiAoYSA9PT0gYikgcmV0dXJuIDBcblxuICB2YXIgeCA9IGEubGVuZ3RoXG4gIHZhciB5ID0gYi5sZW5ndGhcblxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gTWF0aC5taW4oeCwgeSk7IGkgPCBsZW47ICsraSkge1xuICAgIGlmIChhW2ldICE9PSBiW2ldKSB7XG4gICAgICB4ID0gYVtpXVxuICAgICAgeSA9IGJbaV1cbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG5cbiAgaWYgKHggPCB5KSByZXR1cm4gLTFcbiAgaWYgKHkgPCB4KSByZXR1cm4gMVxuICByZXR1cm4gMFxufVxuXG5CdWZmZXIuaXNFbmNvZGluZyA9IGZ1bmN0aW9uIGlzRW5jb2RpbmcgKGVuY29kaW5nKSB7XG4gIHN3aXRjaCAoU3RyaW5nKGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgY2FzZSAnYXNjaWknOlxuICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuXG5CdWZmZXIuY29uY2F0ID0gZnVuY3Rpb24gY29uY2F0IChsaXN0LCBsZW5ndGgpIHtcbiAgaWYgKCFpc0FycmF5KGxpc3QpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0XCIgYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheSBvZiBCdWZmZXJzJylcbiAgfVxuXG4gIGlmIChsaXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBCdWZmZXIuYWxsb2MoMClcbiAgfVxuXG4gIHZhciBpXG4gIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGxlbmd0aCA9IDBcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7ICsraSkge1xuICAgICAgbGVuZ3RoICs9IGxpc3RbaV0ubGVuZ3RoXG4gICAgfVxuICB9XG5cbiAgdmFyIGJ1ZmZlciA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShsZW5ndGgpXG4gIHZhciBwb3MgPSAwXG4gIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgKytpKSB7XG4gICAgdmFyIGJ1ZiA9IGxpc3RbaV1cbiAgICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RcIiBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMnKVxuICAgIH1cbiAgICBidWYuY29weShidWZmZXIsIHBvcylcbiAgICBwb3MgKz0gYnVmLmxlbmd0aFxuICB9XG4gIHJldHVybiBidWZmZXJcbn1cblxuZnVuY3Rpb24gYnl0ZUxlbmd0aCAoc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHN0cmluZykpIHtcbiAgICByZXR1cm4gc3RyaW5nLmxlbmd0aFxuICB9XG4gIGlmICh0eXBlb2YgQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBBcnJheUJ1ZmZlci5pc1ZpZXcgPT09ICdmdW5jdGlvbicgJiZcbiAgICAgIChBcnJheUJ1ZmZlci5pc1ZpZXcoc3RyaW5nKSB8fCBzdHJpbmcgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikpIHtcbiAgICByZXR1cm4gc3RyaW5nLmJ5dGVMZW5ndGhcbiAgfVxuICBpZiAodHlwZW9mIHN0cmluZyAhPT0gJ3N0cmluZycpIHtcbiAgICBzdHJpbmcgPSAnJyArIHN0cmluZ1xuICB9XG5cbiAgdmFyIGxlbiA9IHN0cmluZy5sZW5ndGhcbiAgaWYgKGxlbiA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBVc2UgYSBmb3IgbG9vcCB0byBhdm9pZCByZWN1cnNpb25cbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gbGVuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgIGNhc2UgdW5kZWZpbmVkOlxuICAgICAgICByZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiBsZW4gKiAyXG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gbGVuID4+PiAxXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0VG9CeXRlcyhzdHJpbmcpLmxlbmd0aFxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSByZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGggLy8gYXNzdW1lIHV0ZjhcbiAgICAgICAgZW5jb2RpbmcgPSAoJycgKyBlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cbkJ1ZmZlci5ieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aFxuXG5mdW5jdGlvbiBzbG93VG9TdHJpbmcgKGVuY29kaW5nLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG5cbiAgLy8gTm8gbmVlZCB0byB2ZXJpZnkgdGhhdCBcInRoaXMubGVuZ3RoIDw9IE1BWF9VSU5UMzJcIiBzaW5jZSBpdCdzIGEgcmVhZC1vbmx5XG4gIC8vIHByb3BlcnR5IG9mIGEgdHlwZWQgYXJyYXkuXG5cbiAgLy8gVGhpcyBiZWhhdmVzIG5laXRoZXIgbGlrZSBTdHJpbmcgbm9yIFVpbnQ4QXJyYXkgaW4gdGhhdCB3ZSBzZXQgc3RhcnQvZW5kXG4gIC8vIHRvIHRoZWlyIHVwcGVyL2xvd2VyIGJvdW5kcyBpZiB0aGUgdmFsdWUgcGFzc2VkIGlzIG91dCBvZiByYW5nZS5cbiAgLy8gdW5kZWZpbmVkIGlzIGhhbmRsZWQgc3BlY2lhbGx5IGFzIHBlciBFQ01BLTI2MiA2dGggRWRpdGlvbixcbiAgLy8gU2VjdGlvbiAxMy4zLjMuNyBSdW50aW1lIFNlbWFudGljczogS2V5ZWRCaW5kaW5nSW5pdGlhbGl6YXRpb24uXG4gIGlmIChzdGFydCA9PT0gdW5kZWZpbmVkIHx8IHN0YXJ0IDwgMCkge1xuICAgIHN0YXJ0ID0gMFxuICB9XG4gIC8vIFJldHVybiBlYXJseSBpZiBzdGFydCA+IHRoaXMubGVuZ3RoLiBEb25lIGhlcmUgdG8gcHJldmVudCBwb3RlbnRpYWwgdWludDMyXG4gIC8vIGNvZXJjaW9uIGZhaWwgYmVsb3cuXG4gIGlmIChzdGFydCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICBpZiAoZW5kID09PSB1bmRlZmluZWQgfHwgZW5kID4gdGhpcy5sZW5ndGgpIHtcbiAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICB9XG5cbiAgaWYgKGVuZCA8PSAwKSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICAvLyBGb3JjZSBjb2Vyc2lvbiB0byB1aW50MzIuIFRoaXMgd2lsbCBhbHNvIGNvZXJjZSBmYWxzZXkvTmFOIHZhbHVlcyB0byAwLlxuICBlbmQgPj4+PSAwXG4gIHN0YXJ0ID4+Pj0gMFxuXG4gIGlmIChlbmQgPD0gc3RhcnQpIHtcbiAgICByZXR1cm4gJydcbiAgfVxuXG4gIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gJ3V0ZjgnXG5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxhdGluMVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIHJldHVybiBiYXNlNjRTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gdXRmMTZsZVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgICAgICBlbmNvZGluZyA9IChlbmNvZGluZyArICcnKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuXG4vLyBUaGUgcHJvcGVydHkgaXMgdXNlZCBieSBgQnVmZmVyLmlzQnVmZmVyYCBhbmQgYGlzLWJ1ZmZlcmAgKGluIFNhZmFyaSA1LTcpIHRvIGRldGVjdFxuLy8gQnVmZmVyIGluc3RhbmNlcy5cbkJ1ZmZlci5wcm90b3R5cGUuX2lzQnVmZmVyID0gdHJ1ZVxuXG5mdW5jdGlvbiBzd2FwIChiLCBuLCBtKSB7XG4gIHZhciBpID0gYltuXVxuICBiW25dID0gYlttXVxuICBiW21dID0gaVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXAxNiA9IGZ1bmN0aW9uIHN3YXAxNiAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgMiAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgMTYtYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gMikge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDEpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwMzIgPSBmdW5jdGlvbiBzd2FwMzIgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDQgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDMyLWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDQpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyAzKVxuICAgIHN3YXAodGhpcywgaSArIDEsIGkgKyAyKVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc3dhcDY0ID0gZnVuY3Rpb24gc3dhcDY0ICgpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW4gJSA4ICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0J1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA2NC1iaXRzJylcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSA4KSB7XG4gICAgc3dhcCh0aGlzLCBpLCBpICsgNylcbiAgICBzd2FwKHRoaXMsIGkgKyAxLCBpICsgNilcbiAgICBzd2FwKHRoaXMsIGkgKyAyLCBpICsgNSlcbiAgICBzd2FwKHRoaXMsIGkgKyAzLCBpICsgNClcbiAgfVxuICByZXR1cm4gdGhpc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcgKCkge1xuICB2YXIgbGVuZ3RoID0gdGhpcy5sZW5ndGggfCAwXG4gIGlmIChsZW5ndGggPT09IDApIHJldHVybiAnJ1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHV0ZjhTbGljZSh0aGlzLCAwLCBsZW5ndGgpXG4gIHJldHVybiBzbG93VG9TdHJpbmcuYXBwbHkodGhpcywgYXJndW1lbnRzKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIGVxdWFscyAoYikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihiKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlcicpXG4gIGlmICh0aGlzID09PSBiKSByZXR1cm4gdHJ1ZVxuICByZXR1cm4gQnVmZmVyLmNvbXBhcmUodGhpcywgYikgPT09IDBcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24gaW5zcGVjdCAoKSB7XG4gIHZhciBzdHIgPSAnJ1xuICB2YXIgbWF4ID0gZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFU1xuICBpZiAodGhpcy5sZW5ndGggPiAwKSB7XG4gICAgc3RyID0gdGhpcy50b1N0cmluZygnaGV4JywgMCwgbWF4KS5tYXRjaCgvLnsyfS9nKS5qb2luKCcgJylcbiAgICBpZiAodGhpcy5sZW5ndGggPiBtYXgpIHN0ciArPSAnIC4uLiAnXG4gIH1cbiAgcmV0dXJuICc8QnVmZmVyICcgKyBzdHIgKyAnPidcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5jb21wYXJlID0gZnVuY3Rpb24gY29tcGFyZSAodGFyZ2V0LCBzdGFydCwgZW5kLCB0aGlzU3RhcnQsIHRoaXNFbmQpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIodGFyZ2V0KSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICB9XG5cbiAgaWYgKHN0YXJ0ID09PSB1bmRlZmluZWQpIHtcbiAgICBzdGFydCA9IDBcbiAgfVxuICBpZiAoZW5kID09PSB1bmRlZmluZWQpIHtcbiAgICBlbmQgPSB0YXJnZXQgPyB0YXJnZXQubGVuZ3RoIDogMFxuICB9XG4gIGlmICh0aGlzU3RhcnQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRoaXNTdGFydCA9IDBcbiAgfVxuICBpZiAodGhpc0VuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhpc0VuZCA9IHRoaXMubGVuZ3RoXG4gIH1cblxuICBpZiAoc3RhcnQgPCAwIHx8IGVuZCA+IHRhcmdldC5sZW5ndGggfHwgdGhpc1N0YXJ0IDwgMCB8fCB0aGlzRW5kID4gdGhpcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignb3V0IG9mIHJhbmdlIGluZGV4JylcbiAgfVxuXG4gIGlmICh0aGlzU3RhcnQgPj0gdGhpc0VuZCAmJiBzdGFydCA+PSBlbmQpIHtcbiAgICByZXR1cm4gMFxuICB9XG4gIGlmICh0aGlzU3RhcnQgPj0gdGhpc0VuZCkge1xuICAgIHJldHVybiAtMVxuICB9XG4gIGlmIChzdGFydCA+PSBlbmQpIHtcbiAgICByZXR1cm4gMVxuICB9XG5cbiAgc3RhcnQgPj4+PSAwXG4gIGVuZCA+Pj49IDBcbiAgdGhpc1N0YXJ0ID4+Pj0gMFxuICB0aGlzRW5kID4+Pj0gMFxuXG4gIGlmICh0aGlzID09PSB0YXJnZXQpIHJldHVybiAwXG5cbiAgdmFyIHggPSB0aGlzRW5kIC0gdGhpc1N0YXJ0XG4gIHZhciB5ID0gZW5kIC0gc3RhcnRcbiAgdmFyIGxlbiA9IE1hdGgubWluKHgsIHkpXG5cbiAgdmFyIHRoaXNDb3B5ID0gdGhpcy5zbGljZSh0aGlzU3RhcnQsIHRoaXNFbmQpXG4gIHZhciB0YXJnZXRDb3B5ID0gdGFyZ2V0LnNsaWNlKHN0YXJ0LCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSkge1xuICAgIGlmICh0aGlzQ29weVtpXSAhPT0gdGFyZ2V0Q29weVtpXSkge1xuICAgICAgeCA9IHRoaXNDb3B5W2ldXG4gICAgICB5ID0gdGFyZ2V0Q29weVtpXVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICBpZiAoeCA8IHkpIHJldHVybiAtMVxuICBpZiAoeSA8IHgpIHJldHVybiAxXG4gIHJldHVybiAwXG59XG5cbi8vIEZpbmRzIGVpdGhlciB0aGUgZmlyc3QgaW5kZXggb2YgYHZhbGAgaW4gYGJ1ZmZlcmAgYXQgb2Zmc2V0ID49IGBieXRlT2Zmc2V0YCxcbi8vIE9SIHRoZSBsYXN0IGluZGV4IG9mIGB2YWxgIGluIGBidWZmZXJgIGF0IG9mZnNldCA8PSBgYnl0ZU9mZnNldGAuXG4vL1xuLy8gQXJndW1lbnRzOlxuLy8gLSBidWZmZXIgLSBhIEJ1ZmZlciB0byBzZWFyY2hcbi8vIC0gdmFsIC0gYSBzdHJpbmcsIEJ1ZmZlciwgb3IgbnVtYmVyXG4vLyAtIGJ5dGVPZmZzZXQgLSBhbiBpbmRleCBpbnRvIGBidWZmZXJgOyB3aWxsIGJlIGNsYW1wZWQgdG8gYW4gaW50MzJcbi8vIC0gZW5jb2RpbmcgLSBhbiBvcHRpb25hbCBlbmNvZGluZywgcmVsZXZhbnQgaXMgdmFsIGlzIGEgc3RyaW5nXG4vLyAtIGRpciAtIHRydWUgZm9yIGluZGV4T2YsIGZhbHNlIGZvciBsYXN0SW5kZXhPZlxuZnVuY3Rpb24gYmlkaXJlY3Rpb25hbEluZGV4T2YgKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKSB7XG4gIC8vIEVtcHR5IGJ1ZmZlciBtZWFucyBubyBtYXRjaFxuICBpZiAoYnVmZmVyLmxlbmd0aCA9PT0gMCkgcmV0dXJuIC0xXG5cbiAgLy8gTm9ybWFsaXplIGJ5dGVPZmZzZXRcbiAgaWYgKHR5cGVvZiBieXRlT2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgIGVuY29kaW5nID0gYnl0ZU9mZnNldFxuICAgIGJ5dGVPZmZzZXQgPSAwXG4gIH0gZWxzZSBpZiAoYnl0ZU9mZnNldCA+IDB4N2ZmZmZmZmYpIHtcbiAgICBieXRlT2Zmc2V0ID0gMHg3ZmZmZmZmZlxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPCAtMHg4MDAwMDAwMCkge1xuICAgIGJ5dGVPZmZzZXQgPSAtMHg4MDAwMDAwMFxuICB9XG4gIGJ5dGVPZmZzZXQgPSArYnl0ZU9mZnNldCAgLy8gQ29lcmNlIHRvIE51bWJlci5cbiAgaWYgKGlzTmFOKGJ5dGVPZmZzZXQpKSB7XG4gICAgLy8gYnl0ZU9mZnNldDogaXQgaXQncyB1bmRlZmluZWQsIG51bGwsIE5hTiwgXCJmb29cIiwgZXRjLCBzZWFyY2ggd2hvbGUgYnVmZmVyXG4gICAgYnl0ZU9mZnNldCA9IGRpciA/IDAgOiAoYnVmZmVyLmxlbmd0aCAtIDEpXG4gIH1cblxuICAvLyBOb3JtYWxpemUgYnl0ZU9mZnNldDogbmVnYXRpdmUgb2Zmc2V0cyBzdGFydCBmcm9tIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlclxuICBpZiAoYnl0ZU9mZnNldCA8IDApIGJ5dGVPZmZzZXQgPSBidWZmZXIubGVuZ3RoICsgYnl0ZU9mZnNldFxuICBpZiAoYnl0ZU9mZnNldCA+PSBidWZmZXIubGVuZ3RoKSB7XG4gICAgaWYgKGRpcikgcmV0dXJuIC0xXG4gICAgZWxzZSBieXRlT2Zmc2V0ID0gYnVmZmVyLmxlbmd0aCAtIDFcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0IDwgMCkge1xuICAgIGlmIChkaXIpIGJ5dGVPZmZzZXQgPSAwXG4gICAgZWxzZSByZXR1cm4gLTFcbiAgfVxuXG4gIC8vIE5vcm1hbGl6ZSB2YWxcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFsID0gQnVmZmVyLmZyb20odmFsLCBlbmNvZGluZylcbiAgfVxuXG4gIC8vIEZpbmFsbHksIHNlYXJjaCBlaXRoZXIgaW5kZXhPZiAoaWYgZGlyIGlzIHRydWUpIG9yIGxhc3RJbmRleE9mXG4gIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsKSkge1xuICAgIC8vIFNwZWNpYWwgY2FzZTogbG9va2luZyBmb3IgZW1wdHkgc3RyaW5nL2J1ZmZlciBhbHdheXMgZmFpbHNcbiAgICBpZiAodmFsLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIC0xXG4gICAgfVxuICAgIHJldHVybiBhcnJheUluZGV4T2YoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpXG4gIH0gZWxzZSBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICB2YWwgPSB2YWwgJiAweEZGIC8vIFNlYXJjaCBmb3IgYSBieXRlIHZhbHVlIFswLTI1NV1cbiAgICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgJiZcbiAgICAgICAgdHlwZW9mIFVpbnQ4QXJyYXkucHJvdG90eXBlLmluZGV4T2YgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGlmIChkaXIpIHtcbiAgICAgICAgcmV0dXJuIFVpbnQ4QXJyYXkucHJvdG90eXBlLmluZGV4T2YuY2FsbChidWZmZXIsIHZhbCwgYnl0ZU9mZnNldClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBVaW50OEFycmF5LnByb3RvdHlwZS5sYXN0SW5kZXhPZi5jYWxsKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0KVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKGJ1ZmZlciwgWyB2YWwgXSwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcilcbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoJ3ZhbCBtdXN0IGJlIHN0cmluZywgbnVtYmVyIG9yIEJ1ZmZlcicpXG59XG5cbmZ1bmN0aW9uIGFycmF5SW5kZXhPZiAoYXJyLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpIHtcbiAgdmFyIGluZGV4U2l6ZSA9IDFcbiAgdmFyIGFyckxlbmd0aCA9IGFyci5sZW5ndGhcbiAgdmFyIHZhbExlbmd0aCA9IHZhbC5sZW5ndGhcblxuICBpZiAoZW5jb2RpbmcgIT09IHVuZGVmaW5lZCkge1xuICAgIGVuY29kaW5nID0gU3RyaW5nKGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgaWYgKGVuY29kaW5nID09PSAndWNzMicgfHwgZW5jb2RpbmcgPT09ICd1Y3MtMicgfHxcbiAgICAgICAgZW5jb2RpbmcgPT09ICd1dGYxNmxlJyB8fCBlbmNvZGluZyA9PT0gJ3V0Zi0xNmxlJykge1xuICAgICAgaWYgKGFyci5sZW5ndGggPCAyIHx8IHZhbC5sZW5ndGggPCAyKSB7XG4gICAgICAgIHJldHVybiAtMVxuICAgICAgfVxuICAgICAgaW5kZXhTaXplID0gMlxuICAgICAgYXJyTGVuZ3RoIC89IDJcbiAgICAgIHZhbExlbmd0aCAvPSAyXG4gICAgICBieXRlT2Zmc2V0IC89IDJcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZWFkIChidWYsIGkpIHtcbiAgICBpZiAoaW5kZXhTaXplID09PSAxKSB7XG4gICAgICByZXR1cm4gYnVmW2ldXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBidWYucmVhZFVJbnQxNkJFKGkgKiBpbmRleFNpemUpXG4gICAgfVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKGRpcikge1xuICAgIHZhciBmb3VuZEluZGV4ID0gLTFcbiAgICBmb3IgKGkgPSBieXRlT2Zmc2V0OyBpIDwgYXJyTGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChyZWFkKGFyciwgaSkgPT09IHJlYWQodmFsLCBmb3VuZEluZGV4ID09PSAtMSA/IDAgOiBpIC0gZm91bmRJbmRleCkpIHtcbiAgICAgICAgaWYgKGZvdW5kSW5kZXggPT09IC0xKSBmb3VuZEluZGV4ID0gaVxuICAgICAgICBpZiAoaSAtIGZvdW5kSW5kZXggKyAxID09PSB2YWxMZW5ndGgpIHJldHVybiBmb3VuZEluZGV4ICogaW5kZXhTaXplXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZm91bmRJbmRleCAhPT0gLTEpIGkgLT0gaSAtIGZvdW5kSW5kZXhcbiAgICAgICAgZm91bmRJbmRleCA9IC0xXG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChieXRlT2Zmc2V0ICsgdmFsTGVuZ3RoID4gYXJyTGVuZ3RoKSBieXRlT2Zmc2V0ID0gYXJyTGVuZ3RoIC0gdmFsTGVuZ3RoXG4gICAgZm9yIChpID0gYnl0ZU9mZnNldDsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHZhciBmb3VuZCA9IHRydWVcbiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgdmFsTGVuZ3RoOyBqKyspIHtcbiAgICAgICAgaWYgKHJlYWQoYXJyLCBpICsgaikgIT09IHJlYWQodmFsLCBqKSkge1xuICAgICAgICAgIGZvdW5kID0gZmFsc2VcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZm91bmQpIHJldHVybiBpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIC0xXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5jbHVkZXMgPSBmdW5jdGlvbiBpbmNsdWRlcyAodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykge1xuICByZXR1cm4gdGhpcy5pbmRleE9mKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpICE9PSAtMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluZGV4T2YgPSBmdW5jdGlvbiBpbmRleE9mICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiBiaWRpcmVjdGlvbmFsSW5kZXhPZih0aGlzLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCB0cnVlKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmxhc3RJbmRleE9mID0gZnVuY3Rpb24gbGFzdEluZGV4T2YgKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIGJpZGlyZWN0aW9uYWxJbmRleE9mKHRoaXMsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGZhbHNlKVxufVxuXG5mdW5jdGlvbiBoZXhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIG9mZnNldCA9IE51bWJlcihvZmZzZXQpIHx8IDBcbiAgdmFyIHJlbWFpbmluZyA9IGJ1Zi5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKCFsZW5ndGgpIHtcbiAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgfSBlbHNlIHtcbiAgICBsZW5ndGggPSBOdW1iZXIobGVuZ3RoKVxuICAgIGlmIChsZW5ndGggPiByZW1haW5pbmcpIHtcbiAgICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICAgIH1cbiAgfVxuXG4gIC8vIG11c3QgYmUgYW4gZXZlbiBudW1iZXIgb2YgZGlnaXRzXG4gIHZhciBzdHJMZW4gPSBzdHJpbmcubGVuZ3RoXG4gIGlmIChzdHJMZW4gJSAyICE9PSAwKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIGhleCBzdHJpbmcnKVxuXG4gIGlmIChsZW5ndGggPiBzdHJMZW4gLyAyKSB7XG4gICAgbGVuZ3RoID0gc3RyTGVuIC8gMlxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgcGFyc2VkID0gcGFyc2VJbnQoc3RyaW5nLnN1YnN0cihpICogMiwgMiksIDE2KVxuICAgIGlmIChpc05hTihwYXJzZWQpKSByZXR1cm4gaVxuICAgIGJ1ZltvZmZzZXQgKyBpXSA9IHBhcnNlZFxuICB9XG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIHV0ZjhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjhUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGFzY2lpV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihhc2NpaVRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gbGF0aW4xV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYXNjaWlXcml0ZShidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGJhc2U2NFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIoYmFzZTY0VG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiB1Y3MyV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcih1dGYxNmxlVG9CeXRlcyhzdHJpbmcsIGJ1Zi5sZW5ndGggLSBvZmZzZXQpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gd3JpdGUgKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nKSB7XG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcpXG4gIGlmIChvZmZzZXQgPT09IHVuZGVmaW5lZCkge1xuICAgIGVuY29kaW5nID0gJ3V0ZjgnXG4gICAgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgICBvZmZzZXQgPSAwXG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuICB9IGVsc2UgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkICYmIHR5cGVvZiBvZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jb2RpbmcgPSBvZmZzZXRcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgb2Zmc2V0WywgbGVuZ3RoXVssIGVuY29kaW5nXSlcbiAgfSBlbHNlIGlmIChpc0Zpbml0ZShvZmZzZXQpKSB7XG4gICAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICAgIGlmIChpc0Zpbml0ZShsZW5ndGgpKSB7XG4gICAgICBsZW5ndGggPSBsZW5ndGggfCAwXG4gICAgICBpZiAoZW5jb2RpbmcgPT09IHVuZGVmaW5lZCkgZW5jb2RpbmcgPSAndXRmOCdcbiAgICB9IGVsc2Uge1xuICAgICAgZW5jb2RpbmcgPSBsZW5ndGhcbiAgICAgIGxlbmd0aCA9IHVuZGVmaW5lZFxuICAgIH1cbiAgLy8gbGVnYWN5IHdyaXRlKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldCwgbGVuZ3RoKSAtIHJlbW92ZSBpbiB2MC4xM1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICdCdWZmZXIud3JpdGUoc3RyaW5nLCBlbmNvZGluZywgb2Zmc2V0WywgbGVuZ3RoXSkgaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZCdcbiAgICApXG4gIH1cblxuICB2YXIgcmVtYWluaW5nID0gdGhpcy5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkIHx8IGxlbmd0aCA+IHJlbWFpbmluZykgbGVuZ3RoID0gcmVtYWluaW5nXG5cbiAgaWYgKChzdHJpbmcubGVuZ3RoID4gMCAmJiAobGVuZ3RoIDwgMCB8fCBvZmZzZXQgPCAwKSkgfHwgb2Zmc2V0ID4gdGhpcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQXR0ZW1wdCB0byB3cml0ZSBvdXRzaWRlIGJ1ZmZlciBib3VuZHMnKVxuICB9XG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcblxuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGhleFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgcmV0dXJuIGFzY2lpV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBsYXRpbjFXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICAvLyBXYXJuaW5nOiBtYXhMZW5ndGggbm90IHRha2VuIGludG8gYWNjb3VudCBpbiBiYXNlNjRXcml0ZVxuICAgICAgICByZXR1cm4gYmFzZTY0V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHVjczJXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoJycgKyBlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04gKCkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6ICdCdWZmZXInLFxuICAgIGRhdGE6IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKHRoaXMuX2FyciB8fCB0aGlzLCAwKVxuICB9XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKHN0YXJ0ID09PSAwICYmIGVuZCA9PT0gYnVmLmxlbmd0aCkge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYpXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1Zi5zbGljZShzdGFydCwgZW5kKSlcbiAgfVxufVxuXG5mdW5jdGlvbiB1dGY4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG4gIHZhciByZXMgPSBbXVxuXG4gIHZhciBpID0gc3RhcnRcbiAgd2hpbGUgKGkgPCBlbmQpIHtcbiAgICB2YXIgZmlyc3RCeXRlID0gYnVmW2ldXG4gICAgdmFyIGNvZGVQb2ludCA9IG51bGxcbiAgICB2YXIgYnl0ZXNQZXJTZXF1ZW5jZSA9IChmaXJzdEJ5dGUgPiAweEVGKSA/IDRcbiAgICAgIDogKGZpcnN0Qnl0ZSA+IDB4REYpID8gM1xuICAgICAgOiAoZmlyc3RCeXRlID4gMHhCRikgPyAyXG4gICAgICA6IDFcblxuICAgIGlmIChpICsgYnl0ZXNQZXJTZXF1ZW5jZSA8PSBlbmQpIHtcbiAgICAgIHZhciBzZWNvbmRCeXRlLCB0aGlyZEJ5dGUsIGZvdXJ0aEJ5dGUsIHRlbXBDb2RlUG9pbnRcblxuICAgICAgc3dpdGNoIChieXRlc1BlclNlcXVlbmNlKSB7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICBpZiAoZmlyc3RCeXRlIDwgMHg4MCkge1xuICAgICAgICAgICAgY29kZVBvaW50ID0gZmlyc3RCeXRlXG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4MUYpIDw8IDB4NiB8IChzZWNvbmRCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHg3Rikge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgMzpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIHRoaXJkQnl0ZSA9IGJ1ZltpICsgMl1cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAodGhpcmRCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHhGKSA8PCAweEMgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpIDw8IDB4NiB8ICh0aGlyZEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweDdGRiAmJiAodGVtcENvZGVQb2ludCA8IDB4RDgwMCB8fCB0ZW1wQ29kZVBvaW50ID4gMHhERkZGKSkge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgNDpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIHRoaXJkQnl0ZSA9IGJ1ZltpICsgMl1cbiAgICAgICAgICBmb3VydGhCeXRlID0gYnVmW2kgKyAzXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwICYmICh0aGlyZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAoZm91cnRoQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4RikgPDwgMHgxMiB8IChzZWNvbmRCeXRlICYgMHgzRikgPDwgMHhDIHwgKHRoaXJkQnl0ZSAmIDB4M0YpIDw8IDB4NiB8IChmb3VydGhCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHhGRkZGICYmIHRlbXBDb2RlUG9pbnQgPCAweDExMDAwMCkge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjb2RlUG9pbnQgPT09IG51bGwpIHtcbiAgICAgIC8vIHdlIGRpZCBub3QgZ2VuZXJhdGUgYSB2YWxpZCBjb2RlUG9pbnQgc28gaW5zZXJ0IGFcbiAgICAgIC8vIHJlcGxhY2VtZW50IGNoYXIgKFUrRkZGRCkgYW5kIGFkdmFuY2Ugb25seSAxIGJ5dGVcbiAgICAgIGNvZGVQb2ludCA9IDB4RkZGRFxuICAgICAgYnl0ZXNQZXJTZXF1ZW5jZSA9IDFcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA+IDB4RkZGRikge1xuICAgICAgLy8gZW5jb2RlIHRvIHV0ZjE2IChzdXJyb2dhdGUgcGFpciBkYW5jZSlcbiAgICAgIGNvZGVQb2ludCAtPSAweDEwMDAwXG4gICAgICByZXMucHVzaChjb2RlUG9pbnQgPj4+IDEwICYgMHgzRkYgfCAweEQ4MDApXG4gICAgICBjb2RlUG9pbnQgPSAweERDMDAgfCBjb2RlUG9pbnQgJiAweDNGRlxuICAgIH1cblxuICAgIHJlcy5wdXNoKGNvZGVQb2ludClcbiAgICBpICs9IGJ5dGVzUGVyU2VxdWVuY2VcbiAgfVxuXG4gIHJldHVybiBkZWNvZGVDb2RlUG9pbnRzQXJyYXkocmVzKVxufVxuXG4vLyBCYXNlZCBvbiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yMjc0NzI3Mi82ODA3NDIsIHRoZSBicm93c2VyIHdpdGhcbi8vIHRoZSBsb3dlc3QgbGltaXQgaXMgQ2hyb21lLCB3aXRoIDB4MTAwMDAgYXJncy5cbi8vIFdlIGdvIDEgbWFnbml0dWRlIGxlc3MsIGZvciBzYWZldHlcbnZhciBNQVhfQVJHVU1FTlRTX0xFTkdUSCA9IDB4MTAwMFxuXG5mdW5jdGlvbiBkZWNvZGVDb2RlUG9pbnRzQXJyYXkgKGNvZGVQb2ludHMpIHtcbiAgdmFyIGxlbiA9IGNvZGVQb2ludHMubGVuZ3RoXG4gIGlmIChsZW4gPD0gTUFYX0FSR1VNRU5UU19MRU5HVEgpIHtcbiAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsIGNvZGVQb2ludHMpIC8vIGF2b2lkIGV4dHJhIHNsaWNlKClcbiAgfVxuXG4gIC8vIERlY29kZSBpbiBjaHVua3MgdG8gYXZvaWQgXCJjYWxsIHN0YWNrIHNpemUgZXhjZWVkZWRcIi5cbiAgdmFyIHJlcyA9ICcnXG4gIHZhciBpID0gMFxuICB3aGlsZSAoaSA8IGxlbikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFxuICAgICAgU3RyaW5nLFxuICAgICAgY29kZVBvaW50cy5zbGljZShpLCBpICs9IE1BWF9BUkdVTUVOVFNfTEVOR1RIKVxuICAgIClcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmV0ID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldICYgMHg3RilcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbmZ1bmN0aW9uIGxhdGluMVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbmZ1bmN0aW9uIGhleFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcblxuICBpZiAoIXN0YXJ0IHx8IHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIGlmICghZW5kIHx8IGVuZCA8IDAgfHwgZW5kID4gbGVuKSBlbmQgPSBsZW5cblxuICB2YXIgb3V0ID0gJydcbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICBvdXQgKz0gdG9IZXgoYnVmW2ldKVxuICB9XG4gIHJldHVybiBvdXRcbn1cblxuZnVuY3Rpb24gdXRmMTZsZVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGJ5dGVzID0gYnVmLnNsaWNlKHN0YXJ0LCBlbmQpXG4gIHZhciByZXMgPSAnJ1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0gKyBieXRlc1tpICsgMV0gKiAyNTYpXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnNsaWNlID0gZnVuY3Rpb24gc2xpY2UgKHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIHN0YXJ0ID0gfn5zdGFydFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IGxlbiA6IH5+ZW5kXG5cbiAgaWYgKHN0YXJ0IDwgMCkge1xuICAgIHN0YXJ0ICs9IGxlblxuICAgIGlmIChzdGFydCA8IDApIHN0YXJ0ID0gMFxuICB9IGVsc2UgaWYgKHN0YXJ0ID4gbGVuKSB7XG4gICAgc3RhcnQgPSBsZW5cbiAgfVxuXG4gIGlmIChlbmQgPCAwKSB7XG4gICAgZW5kICs9IGxlblxuICAgIGlmIChlbmQgPCAwKSBlbmQgPSAwXG4gIH0gZWxzZSBpZiAoZW5kID4gbGVuKSB7XG4gICAgZW5kID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgc3RhcnQpIGVuZCA9IHN0YXJ0XG5cbiAgdmFyIG5ld0J1ZlxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICBuZXdCdWYgPSB0aGlzLnN1YmFycmF5KHN0YXJ0LCBlbmQpXG4gICAgbmV3QnVmLl9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgfSBlbHNlIHtcbiAgICB2YXIgc2xpY2VMZW4gPSBlbmQgLSBzdGFydFxuICAgIG5ld0J1ZiA9IG5ldyBCdWZmZXIoc2xpY2VMZW4sIHVuZGVmaW5lZClcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNsaWNlTGVuOyArK2kpIHtcbiAgICAgIG5ld0J1ZltpXSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuZXdCdWZcbn1cblxuLypcbiAqIE5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgYnVmZmVyIGlzbid0IHRyeWluZyB0byB3cml0ZSBvdXQgb2YgYm91bmRzLlxuICovXG5mdW5jdGlvbiBjaGVja09mZnNldCAob2Zmc2V0LCBleHQsIGxlbmd0aCkge1xuICBpZiAoKG9mZnNldCAlIDEpICE9PSAwIHx8IG9mZnNldCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdvZmZzZXQgaXMgbm90IHVpbnQnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gbGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVHJ5aW5nIHRvIGFjY2VzcyBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRMRSA9IGZ1bmN0aW9uIHJlYWRVSW50TEUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIGldICogbXVsXG4gIH1cblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRCRSA9IGZ1bmN0aW9uIHJlYWRVSW50QkUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG4gIH1cblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAtLWJ5dGVMZW5ndGhdXG4gIHZhciBtdWwgPSAxXG4gIHdoaWxlIChieXRlTGVuZ3RoID4gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIC0tYnl0ZUxlbmd0aF0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDggPSBmdW5jdGlvbiByZWFkVUludDggKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAxLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZMRSA9IGZ1bmN0aW9uIHJlYWRVSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2QkUgPSBmdW5jdGlvbiByZWFkVUludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgOCkgfCB0aGlzW29mZnNldCArIDFdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkxFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICgodGhpc1tvZmZzZXRdKSB8XG4gICAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCAxNikpICtcbiAgICAgICh0aGlzW29mZnNldCArIDNdICogMHgxMDAwMDAwKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRVSW50MzJCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdICogMHgxMDAwMDAwKSArXG4gICAgKCh0aGlzW29mZnNldCArIDFdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgIHRoaXNbb2Zmc2V0ICsgM10pXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludExFID0gZnVuY3Rpb24gcmVhZEludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XVxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyBpXSAqIG11bFxuICB9XG4gIG11bCAqPSAweDgwXG5cbiAgaWYgKHZhbCA+PSBtdWwpIHZhbCAtPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aClcblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludEJFID0gZnVuY3Rpb24gcmVhZEludEJFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoXG4gIHZhciBtdWwgPSAxXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIC0taV1cbiAgd2hpbGUgKGkgPiAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1pXSAqIG11bFxuICB9XG4gIG11bCAqPSAweDgwXG5cbiAgaWYgKHZhbCA+PSBtdWwpIHZhbCAtPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aClcblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDggPSBmdW5jdGlvbiByZWFkSW50OCAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDEsIHRoaXMubGVuZ3RoKVxuICBpZiAoISh0aGlzW29mZnNldF0gJiAweDgwKSkgcmV0dXJuICh0aGlzW29mZnNldF0pXG4gIHJldHVybiAoKDB4ZmYgLSB0aGlzW29mZnNldF0gKyAxKSAqIC0xKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkxFID0gZnVuY3Rpb24gcmVhZEludDE2TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XSB8ICh0aGlzW29mZnNldCArIDFdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZCRSA9IGZ1bmN0aW9uIHJlYWRJbnQxNkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIDFdIHwgKHRoaXNbb2Zmc2V0XSA8PCA4KVxuICByZXR1cm4gKHZhbCAmIDB4ODAwMCkgPyB2YWwgfCAweEZGRkYwMDAwIDogdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyTEUgPSBmdW5jdGlvbiByZWFkSW50MzJMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdKSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOCkgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgM10gPDwgMjQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyQkUgPSBmdW5jdGlvbiByZWFkSW50MzJCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDI0KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCA4KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgM10pXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0TEUgPSBmdW5jdGlvbiByZWFkRmxvYXRMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgdHJ1ZSwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0QkUgPSBmdW5jdGlvbiByZWFkRmxvYXRCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgZmFsc2UsIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVMRSA9IGZ1bmN0aW9uIHJlYWREb3VibGVMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDgsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgdHJ1ZSwgNTIsIDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUJFID0gZnVuY3Rpb24gcmVhZERvdWJsZUJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgNTIsIDgpXG59XG5cbmZ1bmN0aW9uIGNoZWNrSW50IChidWYsIHZhbHVlLCBvZmZzZXQsIGV4dCwgbWF4LCBtaW4pIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJidWZmZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyIGluc3RhbmNlJylcbiAgaWYgKHZhbHVlID4gbWF4IHx8IHZhbHVlIDwgbWluKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJ2YWx1ZVwiIGFyZ3VtZW50IGlzIG91dCBvZiBib3VuZHMnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnRMRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBtYXhCeXRlcyA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKSAtIDFcbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBtYXhCeXRlcywgMClcbiAgfVxuXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBtYXhCeXRlcyA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKSAtIDFcbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBtYXhCeXRlcywgMClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50OCA9IGZ1bmN0aW9uIHdyaXRlVUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHhmZiwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkgdmFsdWUgPSBNYXRoLmZsb29yKHZhbHVlKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5mdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQxNiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmYgKyB2YWx1ZSArIDFcbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihidWYubGVuZ3RoIC0gb2Zmc2V0LCAyKTsgaSA8IGo7ICsraSkge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9ICh2YWx1ZSAmICgweGZmIDw8ICg4ICogKGxpdHRsZUVuZGlhbiA/IGkgOiAxIC0gaSkpKSkgPj4+XG4gICAgICAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSAqIDhcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweGZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5mdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQzMiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIGZvciAodmFyIGkgPSAwLCBqID0gTWF0aC5taW4oYnVmLmxlbmd0aCAtIG9mZnNldCwgNCk7IGkgPCBqOyArK2kpIHtcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSAodmFsdWUgPj4+IChsaXR0bGVFbmRpYW4gPyBpIDogMyAtIGkpICogOCkgJiAweGZmXG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweGZmZmZmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50TEUgPSBmdW5jdGlvbiB3cml0ZUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gMFxuICB2YXIgbXVsID0gMVxuICB2YXIgc3ViID0gMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICBpZiAodmFsdWUgPCAwICYmIHN1YiA9PT0gMCAmJiB0aGlzW29mZnNldCArIGkgLSAxXSAhPT0gMCkge1xuICAgICAgc3ViID0gMVxuICAgIH1cbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50QkUgPSBmdW5jdGlvbiB3cml0ZUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IDBcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICBpZiAodmFsdWUgPCAwICYmIHN1YiA9PT0gMCAmJiB0aGlzW29mZnNldCArIGkgKyAxXSAhPT0gMCkge1xuICAgICAgc3ViID0gMVxuICAgIH1cbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50OCA9IGZ1bmN0aW9uIHdyaXRlSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweDdmLCAtMHg4MClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkgdmFsdWUgPSBNYXRoLmZsb29yKHZhbHVlKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmYgKyB2YWx1ZSArIDFcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZCRSA9IGZ1bmN0aW9uIHdyaXRlSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJMRSA9IGZ1bmN0aW9uIHdyaXRlSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZmZmZmZmZiArIHZhbHVlICsgMVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDI0KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuZnVuY3Rpb24gY2hlY2tJRUVFNzU0IChidWYsIHZhbHVlLCBvZmZzZXQsIGV4dCwgbWF4LCBtaW4pIHtcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxuICBpZiAob2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvYXQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgNCwgMy40MDI4MjM0NjYzODUyODg2ZSszOCwgLTMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgMjMsIDQpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdExFID0gZnVuY3Rpb24gd3JpdGVGbG9hdExFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0QkUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gd3JpdGVEb3VibGUgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgOCwgMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgsIC0xLjc5NzY5MzEzNDg2MjMxNTdFKzMwOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCA1MiwgOClcbiAgcmV0dXJuIG9mZnNldCArIDhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUxFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlQkUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG4vLyBjb3B5KHRhcmdldEJ1ZmZlciwgdGFyZ2V0U3RhcnQ9MCwgc291cmNlU3RhcnQ9MCwgc291cmNlRW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiBjb3B5ICh0YXJnZXQsIHRhcmdldFN0YXJ0LCBzdGFydCwgZW5kKSB7XG4gIGlmICghc3RhcnQpIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCAmJiBlbmQgIT09IDApIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXRTdGFydCA+PSB0YXJnZXQubGVuZ3RoKSB0YXJnZXRTdGFydCA9IHRhcmdldC5sZW5ndGhcbiAgaWYgKCF0YXJnZXRTdGFydCkgdGFyZ2V0U3RhcnQgPSAwXG4gIGlmIChlbmQgPiAwICYmIGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIC8vIENvcHkgMCBieXRlczsgd2UncmUgZG9uZVxuICBpZiAoZW5kID09PSBzdGFydCkgcmV0dXJuIDBcbiAgaWYgKHRhcmdldC5sZW5ndGggPT09IDAgfHwgdGhpcy5sZW5ndGggPT09IDApIHJldHVybiAwXG5cbiAgLy8gRmF0YWwgZXJyb3IgY29uZGl0aW9uc1xuICBpZiAodGFyZ2V0U3RhcnQgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3RhcmdldFN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICB9XG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgaWYgKGVuZCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VFbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgLy8gQXJlIHdlIG9vYj9cbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0IDwgZW5kIC0gc3RhcnQpIHtcbiAgICBlbmQgPSB0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgKyBzdGFydFxuICB9XG5cbiAgdmFyIGxlbiA9IGVuZCAtIHN0YXJ0XG4gIHZhciBpXG5cbiAgaWYgKHRoaXMgPT09IHRhcmdldCAmJiBzdGFydCA8IHRhcmdldFN0YXJ0ICYmIHRhcmdldFN0YXJ0IDwgZW5kKSB7XG4gICAgLy8gZGVzY2VuZGluZyBjb3B5IGZyb20gZW5kXG4gICAgZm9yIChpID0gbGVuIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHRhcmdldFtpICsgdGFyZ2V0U3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9IGVsc2UgaWYgKGxlbiA8IDEwMDAgfHwgIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gYXNjZW5kaW5nIGNvcHkgZnJvbSBzdGFydFxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47ICsraSkge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgVWludDhBcnJheS5wcm90b3R5cGUuc2V0LmNhbGwoXG4gICAgICB0YXJnZXQsXG4gICAgICB0aGlzLnN1YmFycmF5KHN0YXJ0LCBzdGFydCArIGxlbiksXG4gICAgICB0YXJnZXRTdGFydFxuICAgIClcbiAgfVxuXG4gIHJldHVybiBsZW5cbn1cblxuLy8gVXNhZ2U6XG4vLyAgICBidWZmZXIuZmlsbChudW1iZXJbLCBvZmZzZXRbLCBlbmRdXSlcbi8vICAgIGJ1ZmZlci5maWxsKGJ1ZmZlclssIG9mZnNldFssIGVuZF1dKVxuLy8gICAgYnVmZmVyLmZpbGwoc3RyaW5nWywgb2Zmc2V0WywgZW5kXV1bLCBlbmNvZGluZ10pXG5CdWZmZXIucHJvdG90eXBlLmZpbGwgPSBmdW5jdGlvbiBmaWxsICh2YWwsIHN0YXJ0LCBlbmQsIGVuY29kaW5nKSB7XG4gIC8vIEhhbmRsZSBzdHJpbmcgY2FzZXM6XG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIGlmICh0eXBlb2Ygc3RhcnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlbmNvZGluZyA9IHN0YXJ0XG4gICAgICBzdGFydCA9IDBcbiAgICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZW5kID09PSAnc3RyaW5nJykge1xuICAgICAgZW5jb2RpbmcgPSBlbmRcbiAgICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gICAgfVxuICAgIGlmICh2YWwubGVuZ3RoID09PSAxKSB7XG4gICAgICB2YXIgY29kZSA9IHZhbC5jaGFyQ29kZUF0KDApXG4gICAgICBpZiAoY29kZSA8IDI1Nikge1xuICAgICAgICB2YWwgPSBjb2RlXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlbmNvZGluZyAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2VuY29kaW5nIG11c3QgYmUgYSBzdHJpbmcnKVxuICAgIH1cbiAgICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJyAmJiAhQnVmZmVyLmlzRW5jb2RpbmcoZW5jb2RpbmcpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgdmFsID0gdmFsICYgMjU1XG4gIH1cblxuICAvLyBJbnZhbGlkIHJhbmdlcyBhcmUgbm90IHNldCB0byBhIGRlZmF1bHQsIHNvIGNhbiByYW5nZSBjaGVjayBlYXJseS5cbiAgaWYgKHN0YXJ0IDwgMCB8fCB0aGlzLmxlbmd0aCA8IHN0YXJ0IHx8IHRoaXMubGVuZ3RoIDwgZW5kKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ091dCBvZiByYW5nZSBpbmRleCcpXG4gIH1cblxuICBpZiAoZW5kIDw9IHN0YXJ0KSB7XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIHN0YXJ0ID0gc3RhcnQgPj4+IDBcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyB0aGlzLmxlbmd0aCA6IGVuZCA+Pj4gMFxuXG4gIGlmICghdmFsKSB2YWwgPSAwXG5cbiAgdmFyIGlcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgICAgdGhpc1tpXSA9IHZhbFxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgYnl0ZXMgPSBCdWZmZXIuaXNCdWZmZXIodmFsKVxuICAgICAgPyB2YWxcbiAgICAgIDogdXRmOFRvQnl0ZXMobmV3IEJ1ZmZlcih2YWwsIGVuY29kaW5nKS50b1N0cmluZygpKVxuICAgIHZhciBsZW4gPSBieXRlcy5sZW5ndGhcbiAgICBmb3IgKGkgPSAwOyBpIDwgZW5kIC0gc3RhcnQ7ICsraSkge1xuICAgICAgdGhpc1tpICsgc3RhcnRdID0gYnl0ZXNbaSAlIGxlbl1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpc1xufVxuXG4vLyBIRUxQRVIgRlVOQ1RJT05TXG4vLyA9PT09PT09PT09PT09PT09XG5cbnZhciBJTlZBTElEX0JBU0U2NF9SRSA9IC9bXitcXC8wLTlBLVphLXotX10vZ1xuXG5mdW5jdGlvbiBiYXNlNjRjbGVhbiAoc3RyKSB7XG4gIC8vIE5vZGUgc3RyaXBzIG91dCBpbnZhbGlkIGNoYXJhY3RlcnMgbGlrZSBcXG4gYW5kIFxcdCBmcm9tIHRoZSBzdHJpbmcsIGJhc2U2NC1qcyBkb2VzIG5vdFxuICBzdHIgPSBzdHJpbmd0cmltKHN0cikucmVwbGFjZShJTlZBTElEX0JBU0U2NF9SRSwgJycpXG4gIC8vIE5vZGUgY29udmVydHMgc3RyaW5ncyB3aXRoIGxlbmd0aCA8IDIgdG8gJydcbiAgaWYgKHN0ci5sZW5ndGggPCAyKSByZXR1cm4gJydcbiAgLy8gTm9kZSBhbGxvd3MgZm9yIG5vbi1wYWRkZWQgYmFzZTY0IHN0cmluZ3MgKG1pc3NpbmcgdHJhaWxpbmcgPT09KSwgYmFzZTY0LWpzIGRvZXMgbm90XG4gIHdoaWxlIChzdHIubGVuZ3RoICUgNCAhPT0gMCkge1xuICAgIHN0ciA9IHN0ciArICc9J1xuICB9XG4gIHJldHVybiBzdHJcbn1cblxuZnVuY3Rpb24gc3RyaW5ndHJpbSAoc3RyKSB7XG4gIGlmIChzdHIudHJpbSkgcmV0dXJuIHN0ci50cmltKClcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9eXFxzK3xcXHMrJC9nLCAnJylcbn1cblxuZnVuY3Rpb24gdG9IZXggKG4pIHtcbiAgaWYgKG4gPCAxNikgcmV0dXJuICcwJyArIG4udG9TdHJpbmcoMTYpXG4gIHJldHVybiBuLnRvU3RyaW5nKDE2KVxufVxuXG5mdW5jdGlvbiB1dGY4VG9CeXRlcyAoc3RyaW5nLCB1bml0cykge1xuICB1bml0cyA9IHVuaXRzIHx8IEluZmluaXR5XG4gIHZhciBjb2RlUG9pbnRcbiAgdmFyIGxlbmd0aCA9IHN0cmluZy5sZW5ndGhcbiAgdmFyIGxlYWRTdXJyb2dhdGUgPSBudWxsXG4gIHZhciBieXRlcyA9IFtdXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIGNvZGVQb2ludCA9IHN0cmluZy5jaGFyQ29kZUF0KGkpXG5cbiAgICAvLyBpcyBzdXJyb2dhdGUgY29tcG9uZW50XG4gICAgaWYgKGNvZGVQb2ludCA+IDB4RDdGRiAmJiBjb2RlUG9pbnQgPCAweEUwMDApIHtcbiAgICAgIC8vIGxhc3QgY2hhciB3YXMgYSBsZWFkXG4gICAgICBpZiAoIWxlYWRTdXJyb2dhdGUpIHtcbiAgICAgICAgLy8gbm8gbGVhZCB5ZXRcbiAgICAgICAgaWYgKGNvZGVQb2ludCA+IDB4REJGRikge1xuICAgICAgICAgIC8vIHVuZXhwZWN0ZWQgdHJhaWxcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9IGVsc2UgaWYgKGkgKyAxID09PSBsZW5ndGgpIHtcbiAgICAgICAgICAvLyB1bnBhaXJlZCBsZWFkXG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHZhbGlkIGxlYWRcbiAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIDIgbGVhZHMgaW4gYSByb3dcbiAgICAgIGlmIChjb2RlUG9pbnQgPCAweERDMDApIHtcbiAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgIGxlYWRTdXJyb2dhdGUgPSBjb2RlUG9pbnRcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgLy8gdmFsaWQgc3Vycm9nYXRlIHBhaXJcbiAgICAgIGNvZGVQb2ludCA9IChsZWFkU3Vycm9nYXRlIC0gMHhEODAwIDw8IDEwIHwgY29kZVBvaW50IC0gMHhEQzAwKSArIDB4MTAwMDBcbiAgICB9IGVsc2UgaWYgKGxlYWRTdXJyb2dhdGUpIHtcbiAgICAgIC8vIHZhbGlkIGJtcCBjaGFyLCBidXQgbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgIH1cblxuICAgIGxlYWRTdXJyb2dhdGUgPSBudWxsXG5cbiAgICAvLyBlbmNvZGUgdXRmOFxuICAgIGlmIChjb2RlUG9pbnQgPCAweDgwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDEpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goY29kZVBvaW50KVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHg4MDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiB8IDB4QzAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDMpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgfCAweEUwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDExMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSA0KSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHgxMiB8IDB4RjAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29kZSBwb2ludCcpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpVG9CeXRlcyAoc3RyKSB7XG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7ICsraSkge1xuICAgIC8vIE5vZGUncyBjb2RlIHNlZW1zIHRvIGJlIGRvaW5nIHRoaXMgYW5kIG5vdCAmIDB4N0YuLlxuICAgIGJ5dGVBcnJheS5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpICYgMHhGRilcbiAgfVxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVUb0J5dGVzIChzdHIsIHVuaXRzKSB7XG4gIHZhciBjLCBoaSwgbG9cbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG5cbiAgICBjID0gc3RyLmNoYXJDb2RlQXQoaSlcbiAgICBoaSA9IGMgPj4gOFxuICAgIGxvID0gYyAlIDI1NlxuICAgIGJ5dGVBcnJheS5wdXNoKGxvKVxuICAgIGJ5dGVBcnJheS5wdXNoKGhpKVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiBiYXNlNjRUb0J5dGVzIChzdHIpIHtcbiAgcmV0dXJuIGJhc2U2NC50b0J5dGVBcnJheShiYXNlNjRjbGVhbihzdHIpKVxufVxuXG5mdW5jdGlvbiBibGl0QnVmZmVyIChzcmMsIGRzdCwgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIGlmICgoaSArIG9mZnNldCA+PSBkc3QubGVuZ3RoKSB8fCAoaSA+PSBzcmMubGVuZ3RoKSkgYnJlYWtcbiAgICBkc3RbaSArIG9mZnNldF0gPSBzcmNbaV1cbiAgfVxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiBpc25hbiAodmFsKSB7XG4gIHJldHVybiB2YWwgIT09IHZhbCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNlbGYtY29tcGFyZVxufVxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/buffer/index.js\n"); + +/***/ }), + +/***/ "./node_modules/builtin-status-codes/browser.js": +/*!******************************************************!*\ + !*** ./node_modules/builtin-status-codes/browser.js ***! + \******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("module.exports = {\n \"100\": \"Continue\",\n \"101\": \"Switching Protocols\",\n \"102\": \"Processing\",\n \"200\": \"OK\",\n \"201\": \"Created\",\n \"202\": \"Accepted\",\n \"203\": \"Non-Authoritative Information\",\n \"204\": \"No Content\",\n \"205\": \"Reset Content\",\n \"206\": \"Partial Content\",\n \"207\": \"Multi-Status\",\n \"208\": \"Already Reported\",\n \"226\": \"IM Used\",\n \"300\": \"Multiple Choices\",\n \"301\": \"Moved Permanently\",\n \"302\": \"Found\",\n \"303\": \"See Other\",\n \"304\": \"Not Modified\",\n \"305\": \"Use Proxy\",\n \"307\": \"Temporary Redirect\",\n \"308\": \"Permanent Redirect\",\n \"400\": \"Bad Request\",\n \"401\": \"Unauthorized\",\n \"402\": \"Payment Required\",\n \"403\": \"Forbidden\",\n \"404\": \"Not Found\",\n \"405\": \"Method Not Allowed\",\n \"406\": \"Not Acceptable\",\n \"407\": \"Proxy Authentication Required\",\n \"408\": \"Request Timeout\",\n \"409\": \"Conflict\",\n \"410\": \"Gone\",\n \"411\": \"Length Required\",\n \"412\": \"Precondition Failed\",\n \"413\": \"Payload Too Large\",\n \"414\": \"URI Too Long\",\n \"415\": \"Unsupported Media Type\",\n \"416\": \"Range Not Satisfiable\",\n \"417\": \"Expectation Failed\",\n \"418\": \"I'm a teapot\",\n \"421\": \"Misdirected Request\",\n \"422\": \"Unprocessable Entity\",\n \"423\": \"Locked\",\n \"424\": \"Failed Dependency\",\n \"425\": \"Unordered Collection\",\n \"426\": \"Upgrade Required\",\n \"428\": \"Precondition Required\",\n \"429\": \"Too Many Requests\",\n \"431\": \"Request Header Fields Too Large\",\n \"451\": \"Unavailable For Legal Reasons\",\n \"500\": \"Internal Server Error\",\n \"501\": \"Not Implemented\",\n \"502\": \"Bad Gateway\",\n \"503\": \"Service Unavailable\",\n \"504\": \"Gateway Timeout\",\n \"505\": \"HTTP Version Not Supported\",\n \"506\": \"Variant Also Negotiates\",\n \"507\": \"Insufficient Storage\",\n \"508\": \"Loop Detected\",\n \"509\": \"Bandwidth Limit Exceeded\",\n \"510\": \"Not Extended\",\n \"511\": \"Network Authentication Required\"\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYnVpbHRpbi1zdGF0dXMtY29kZXMvYnJvd3Nlci5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2J1aWx0aW4tc3RhdHVzLWNvZGVzL2Jyb3dzZXIuanM/OGMwNSJdLCJzb3VyY2VzQ29udGVudCI6WyJtb2R1bGUuZXhwb3J0cyA9IHtcbiAgXCIxMDBcIjogXCJDb250aW51ZVwiLFxuICBcIjEwMVwiOiBcIlN3aXRjaGluZyBQcm90b2NvbHNcIixcbiAgXCIxMDJcIjogXCJQcm9jZXNzaW5nXCIsXG4gIFwiMjAwXCI6IFwiT0tcIixcbiAgXCIyMDFcIjogXCJDcmVhdGVkXCIsXG4gIFwiMjAyXCI6IFwiQWNjZXB0ZWRcIixcbiAgXCIyMDNcIjogXCJOb24tQXV0aG9yaXRhdGl2ZSBJbmZvcm1hdGlvblwiLFxuICBcIjIwNFwiOiBcIk5vIENvbnRlbnRcIixcbiAgXCIyMDVcIjogXCJSZXNldCBDb250ZW50XCIsXG4gIFwiMjA2XCI6IFwiUGFydGlhbCBDb250ZW50XCIsXG4gIFwiMjA3XCI6IFwiTXVsdGktU3RhdHVzXCIsXG4gIFwiMjA4XCI6IFwiQWxyZWFkeSBSZXBvcnRlZFwiLFxuICBcIjIyNlwiOiBcIklNIFVzZWRcIixcbiAgXCIzMDBcIjogXCJNdWx0aXBsZSBDaG9pY2VzXCIsXG4gIFwiMzAxXCI6IFwiTW92ZWQgUGVybWFuZW50bHlcIixcbiAgXCIzMDJcIjogXCJGb3VuZFwiLFxuICBcIjMwM1wiOiBcIlNlZSBPdGhlclwiLFxuICBcIjMwNFwiOiBcIk5vdCBNb2RpZmllZFwiLFxuICBcIjMwNVwiOiBcIlVzZSBQcm94eVwiLFxuICBcIjMwN1wiOiBcIlRlbXBvcmFyeSBSZWRpcmVjdFwiLFxuICBcIjMwOFwiOiBcIlBlcm1hbmVudCBSZWRpcmVjdFwiLFxuICBcIjQwMFwiOiBcIkJhZCBSZXF1ZXN0XCIsXG4gIFwiNDAxXCI6IFwiVW5hdXRob3JpemVkXCIsXG4gIFwiNDAyXCI6IFwiUGF5bWVudCBSZXF1aXJlZFwiLFxuICBcIjQwM1wiOiBcIkZvcmJpZGRlblwiLFxuICBcIjQwNFwiOiBcIk5vdCBGb3VuZFwiLFxuICBcIjQwNVwiOiBcIk1ldGhvZCBOb3QgQWxsb3dlZFwiLFxuICBcIjQwNlwiOiBcIk5vdCBBY2NlcHRhYmxlXCIsXG4gIFwiNDA3XCI6IFwiUHJveHkgQXV0aGVudGljYXRpb24gUmVxdWlyZWRcIixcbiAgXCI0MDhcIjogXCJSZXF1ZXN0IFRpbWVvdXRcIixcbiAgXCI0MDlcIjogXCJDb25mbGljdFwiLFxuICBcIjQxMFwiOiBcIkdvbmVcIixcbiAgXCI0MTFcIjogXCJMZW5ndGggUmVxdWlyZWRcIixcbiAgXCI0MTJcIjogXCJQcmVjb25kaXRpb24gRmFpbGVkXCIsXG4gIFwiNDEzXCI6IFwiUGF5bG9hZCBUb28gTGFyZ2VcIixcbiAgXCI0MTRcIjogXCJVUkkgVG9vIExvbmdcIixcbiAgXCI0MTVcIjogXCJVbnN1cHBvcnRlZCBNZWRpYSBUeXBlXCIsXG4gIFwiNDE2XCI6IFwiUmFuZ2UgTm90IFNhdGlzZmlhYmxlXCIsXG4gIFwiNDE3XCI6IFwiRXhwZWN0YXRpb24gRmFpbGVkXCIsXG4gIFwiNDE4XCI6IFwiSSdtIGEgdGVhcG90XCIsXG4gIFwiNDIxXCI6IFwiTWlzZGlyZWN0ZWQgUmVxdWVzdFwiLFxuICBcIjQyMlwiOiBcIlVucHJvY2Vzc2FibGUgRW50aXR5XCIsXG4gIFwiNDIzXCI6IFwiTG9ja2VkXCIsXG4gIFwiNDI0XCI6IFwiRmFpbGVkIERlcGVuZGVuY3lcIixcbiAgXCI0MjVcIjogXCJVbm9yZGVyZWQgQ29sbGVjdGlvblwiLFxuICBcIjQyNlwiOiBcIlVwZ3JhZGUgUmVxdWlyZWRcIixcbiAgXCI0MjhcIjogXCJQcmVjb25kaXRpb24gUmVxdWlyZWRcIixcbiAgXCI0MjlcIjogXCJUb28gTWFueSBSZXF1ZXN0c1wiLFxuICBcIjQzMVwiOiBcIlJlcXVlc3QgSGVhZGVyIEZpZWxkcyBUb28gTGFyZ2VcIixcbiAgXCI0NTFcIjogXCJVbmF2YWlsYWJsZSBGb3IgTGVnYWwgUmVhc29uc1wiLFxuICBcIjUwMFwiOiBcIkludGVybmFsIFNlcnZlciBFcnJvclwiLFxuICBcIjUwMVwiOiBcIk5vdCBJbXBsZW1lbnRlZFwiLFxuICBcIjUwMlwiOiBcIkJhZCBHYXRld2F5XCIsXG4gIFwiNTAzXCI6IFwiU2VydmljZSBVbmF2YWlsYWJsZVwiLFxuICBcIjUwNFwiOiBcIkdhdGV3YXkgVGltZW91dFwiLFxuICBcIjUwNVwiOiBcIkhUVFAgVmVyc2lvbiBOb3QgU3VwcG9ydGVkXCIsXG4gIFwiNTA2XCI6IFwiVmFyaWFudCBBbHNvIE5lZ290aWF0ZXNcIixcbiAgXCI1MDdcIjogXCJJbnN1ZmZpY2llbnQgU3RvcmFnZVwiLFxuICBcIjUwOFwiOiBcIkxvb3AgRGV0ZWN0ZWRcIixcbiAgXCI1MDlcIjogXCJCYW5kd2lkdGggTGltaXQgRXhjZWVkZWRcIixcbiAgXCI1MTBcIjogXCJOb3QgRXh0ZW5kZWRcIixcbiAgXCI1MTFcIjogXCJOZXR3b3JrIEF1dGhlbnRpY2F0aW9uIFJlcXVpcmVkXCJcbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/builtin-status-codes/browser.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/es/promise/index.js": +/*!**************************************************!*\ + !*** ./node_modules/core-js/es/promise/index.js ***! + \**************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("__webpack_require__(/*! ../../modules/es.object.to-string */ \"./node_modules/core-js/modules/es.object.to-string.js\");\n__webpack_require__(/*! ../../modules/es.string.iterator */ \"./node_modules/core-js/modules/es.string.iterator.js\");\n__webpack_require__(/*! ../../modules/web.dom-collections.iterator */ \"./node_modules/core-js/modules/web.dom-collections.iterator.js\");\n__webpack_require__(/*! ../../modules/es.promise */ \"./node_modules/core-js/modules/es.promise.js\");\n__webpack_require__(/*! ../../modules/es.promise.finally */ \"./node_modules/core-js/modules/es.promise.finally.js\");\nvar path = __webpack_require__(/*! ../../internals/path */ \"./node_modules/core-js/internals/path.js\");\n\nmodule.exports = path.Promise;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9lcy9wcm9taXNlL2luZGV4LmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9lcy9wcm9taXNlL2luZGV4LmpzPzM5ODAiXSwic291cmNlc0NvbnRlbnQiOlsicmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lcy5vYmplY3QudG8tc3RyaW5nJyk7XG5yZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzLnN0cmluZy5pdGVyYXRvcicpO1xucmVxdWlyZSgnLi4vLi4vbW9kdWxlcy93ZWIuZG9tLWNvbGxlY3Rpb25zLml0ZXJhdG9yJyk7XG5yZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzLnByb21pc2UnKTtcbnJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXMucHJvbWlzZS5maW5hbGx5Jyk7XG52YXIgcGF0aCA9IHJlcXVpcmUoJy4uLy4uL2ludGVybmFscy9wYXRoJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gcGF0aC5Qcm9taXNlO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/es/promise/index.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/es/string/index.js": +/*!*************************************************!*\ + !*** ./node_modules/core-js/es/string/index.js ***! + \*************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("__webpack_require__(/*! ../../modules/es.string.from-code-point */ \"./node_modules/core-js/modules/es.string.from-code-point.js\");\n__webpack_require__(/*! ../../modules/es.string.raw */ \"./node_modules/core-js/modules/es.string.raw.js\");\n__webpack_require__(/*! ../../modules/es.string.code-point-at */ \"./node_modules/core-js/modules/es.string.code-point-at.js\");\n__webpack_require__(/*! ../../modules/es.string.ends-with */ \"./node_modules/core-js/modules/es.string.ends-with.js\");\n__webpack_require__(/*! ../../modules/es.string.includes */ \"./node_modules/core-js/modules/es.string.includes.js\");\n__webpack_require__(/*! ../../modules/es.string.match */ \"./node_modules/core-js/modules/es.string.match.js\");\n__webpack_require__(/*! ../../modules/es.string.match-all */ \"./node_modules/core-js/modules/es.string.match-all.js\");\n__webpack_require__(/*! ../../modules/es.string.pad-end */ \"./node_modules/core-js/modules/es.string.pad-end.js\");\n__webpack_require__(/*! ../../modules/es.string.pad-start */ \"./node_modules/core-js/modules/es.string.pad-start.js\");\n__webpack_require__(/*! ../../modules/es.string.repeat */ \"./node_modules/core-js/modules/es.string.repeat.js\");\n__webpack_require__(/*! ../../modules/es.string.replace */ \"./node_modules/core-js/modules/es.string.replace.js\");\n__webpack_require__(/*! ../../modules/es.string.search */ \"./node_modules/core-js/modules/es.string.search.js\");\n__webpack_require__(/*! ../../modules/es.string.split */ \"./node_modules/core-js/modules/es.string.split.js\");\n__webpack_require__(/*! ../../modules/es.string.starts-with */ \"./node_modules/core-js/modules/es.string.starts-with.js\");\n__webpack_require__(/*! ../../modules/es.string.trim */ \"./node_modules/core-js/modules/es.string.trim.js\");\n__webpack_require__(/*! ../../modules/es.string.trim-start */ \"./node_modules/core-js/modules/es.string.trim-start.js\");\n__webpack_require__(/*! ../../modules/es.string.trim-end */ \"./node_modules/core-js/modules/es.string.trim-end.js\");\n__webpack_require__(/*! ../../modules/es.string.iterator */ \"./node_modules/core-js/modules/es.string.iterator.js\");\n__webpack_require__(/*! ../../modules/es.string.anchor */ \"./node_modules/core-js/modules/es.string.anchor.js\");\n__webpack_require__(/*! ../../modules/es.string.big */ \"./node_modules/core-js/modules/es.string.big.js\");\n__webpack_require__(/*! ../../modules/es.string.blink */ \"./node_modules/core-js/modules/es.string.blink.js\");\n__webpack_require__(/*! ../../modules/es.string.bold */ \"./node_modules/core-js/modules/es.string.bold.js\");\n__webpack_require__(/*! ../../modules/es.string.fixed */ \"./node_modules/core-js/modules/es.string.fixed.js\");\n__webpack_require__(/*! ../../modules/es.string.fontcolor */ \"./node_modules/core-js/modules/es.string.fontcolor.js\");\n__webpack_require__(/*! ../../modules/es.string.fontsize */ \"./node_modules/core-js/modules/es.string.fontsize.js\");\n__webpack_require__(/*! ../../modules/es.string.italics */ \"./node_modules/core-js/modules/es.string.italics.js\");\n__webpack_require__(/*! ../../modules/es.string.link */ \"./node_modules/core-js/modules/es.string.link.js\");\n__webpack_require__(/*! ../../modules/es.string.small */ \"./node_modules/core-js/modules/es.string.small.js\");\n__webpack_require__(/*! ../../modules/es.string.strike */ \"./node_modules/core-js/modules/es.string.strike.js\");\n__webpack_require__(/*! ../../modules/es.string.sub */ \"./node_modules/core-js/modules/es.string.sub.js\");\n__webpack_require__(/*! ../../modules/es.string.sup */ \"./node_modules/core-js/modules/es.string.sup.js\");\nvar path = __webpack_require__(/*! ../../internals/path */ \"./node_modules/core-js/internals/path.js\");\n\nmodule.exports = path.String;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9lcy9zdHJpbmcvaW5kZXguanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2VzL3N0cmluZy9pbmRleC5qcz85ODI1Il0sInNvdXJjZXNDb250ZW50IjpbInJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXMuc3RyaW5nLmZyb20tY29kZS1wb2ludCcpO1xucmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lcy5zdHJpbmcucmF3Jyk7XG5yZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzLnN0cmluZy5jb2RlLXBvaW50LWF0Jyk7XG5yZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzLnN0cmluZy5lbmRzLXdpdGgnKTtcbnJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXMuc3RyaW5nLmluY2x1ZGVzJyk7XG5yZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzLnN0cmluZy5tYXRjaCcpO1xucmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lcy5zdHJpbmcubWF0Y2gtYWxsJyk7XG5yZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzLnN0cmluZy5wYWQtZW5kJyk7XG5yZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzLnN0cmluZy5wYWQtc3RhcnQnKTtcbnJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXMuc3RyaW5nLnJlcGVhdCcpO1xucmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lcy5zdHJpbmcucmVwbGFjZScpO1xucmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lcy5zdHJpbmcuc2VhcmNoJyk7XG5yZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzLnN0cmluZy5zcGxpdCcpO1xucmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lcy5zdHJpbmcuc3RhcnRzLXdpdGgnKTtcbnJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXMuc3RyaW5nLnRyaW0nKTtcbnJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXMuc3RyaW5nLnRyaW0tc3RhcnQnKTtcbnJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXMuc3RyaW5nLnRyaW0tZW5kJyk7XG5yZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzLnN0cmluZy5pdGVyYXRvcicpO1xucmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lcy5zdHJpbmcuYW5jaG9yJyk7XG5yZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzLnN0cmluZy5iaWcnKTtcbnJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXMuc3RyaW5nLmJsaW5rJyk7XG5yZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzLnN0cmluZy5ib2xkJyk7XG5yZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzLnN0cmluZy5maXhlZCcpO1xucmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lcy5zdHJpbmcuZm9udGNvbG9yJyk7XG5yZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzLnN0cmluZy5mb250c2l6ZScpO1xucmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lcy5zdHJpbmcuaXRhbGljcycpO1xucmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lcy5zdHJpbmcubGluaycpO1xucmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lcy5zdHJpbmcuc21hbGwnKTtcbnJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXMuc3RyaW5nLnN0cmlrZScpO1xucmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lcy5zdHJpbmcuc3ViJyk7XG5yZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzLnN0cmluZy5zdXAnKTtcbnZhciBwYXRoID0gcmVxdWlyZSgnLi4vLi4vaW50ZXJuYWxzL3BhdGgnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBwYXRoLlN0cmluZztcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/es/string/index.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/a-function.js": +/*!******************************************************!*\ + !*** ./node_modules/core-js/internals/a-function.js ***! + \******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("module.exports = function (it) {\n if (typeof it != 'function') {\n throw TypeError(String(it) + ' is not a function');\n } return it;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvYS1mdW5jdGlvbi5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL2EtZnVuY3Rpb24uanM/MWMwYiJdLCJzb3VyY2VzQ29udGVudCI6WyJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICBpZiAodHlwZW9mIGl0ICE9ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBUeXBlRXJyb3IoU3RyaW5nKGl0KSArICcgaXMgbm90IGEgZnVuY3Rpb24nKTtcbiAgfSByZXR1cm4gaXQ7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/a-function.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/add-to-unscopables.js": +/*!**************************************************************!*\ + !*** ./node_modules/core-js/internals/add-to-unscopables.js ***! + \**************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ \"./node_modules/core-js/internals/well-known-symbol.js\");\nvar create = __webpack_require__(/*! ../internals/object-create */ \"./node_modules/core-js/internals/object-create.js\");\nvar hide = __webpack_require__(/*! ../internals/hide */ \"./node_modules/core-js/internals/hide.js\");\n\nvar UNSCOPABLES = wellKnownSymbol('unscopables');\nvar ArrayPrototype = Array.prototype;\n\n// Array.prototype[@@unscopables]\n// https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables\nif (ArrayPrototype[UNSCOPABLES] == undefined) {\n hide(ArrayPrototype, UNSCOPABLES, create(null));\n}\n\n// add a key to Array.prototype[@@unscopables]\nmodule.exports = function (key) {\n ArrayPrototype[UNSCOPABLES][key] = true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvYWRkLXRvLXVuc2NvcGFibGVzLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvYWRkLXRvLXVuc2NvcGFibGVzLmpzPzQ0ZDIiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIHdlbGxLbm93blN5bWJvbCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy93ZWxsLWtub3duLXN5bWJvbCcpO1xudmFyIGNyZWF0ZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9vYmplY3QtY3JlYXRlJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9oaWRlJyk7XG5cbnZhciBVTlNDT1BBQkxFUyA9IHdlbGxLbm93blN5bWJvbCgndW5zY29wYWJsZXMnKTtcbnZhciBBcnJheVByb3RvdHlwZSA9IEFycmF5LnByb3RvdHlwZTtcblxuLy8gQXJyYXkucHJvdG90eXBlW0BAdW5zY29wYWJsZXNdXG4vLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1hcnJheS5wcm90b3R5cGUtQEB1bnNjb3BhYmxlc1xuaWYgKEFycmF5UHJvdG90eXBlW1VOU0NPUEFCTEVTXSA9PSB1bmRlZmluZWQpIHtcbiAgaGlkZShBcnJheVByb3RvdHlwZSwgVU5TQ09QQUJMRVMsIGNyZWF0ZShudWxsKSk7XG59XG5cbi8vIGFkZCBhIGtleSB0byBBcnJheS5wcm90b3R5cGVbQEB1bnNjb3BhYmxlc11cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGtleSkge1xuICBBcnJheVByb3RvdHlwZVtVTlNDT1BBQkxFU11ba2V5XSA9IHRydWU7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/add-to-unscopables.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/advance-string-index.js": +/*!****************************************************************!*\ + !*** ./node_modules/core-js/internals/advance-string-index.js ***! + \****************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar codePointAt = __webpack_require__(/*! ../internals/string-at */ \"./node_modules/core-js/internals/string-at.js\");\n\n// `AdvanceStringIndex` abstract operation\n// https://tc39.github.io/ecma262/#sec-advancestringindex\nmodule.exports = function (S, index, unicode) {\n return index + (unicode ? codePointAt(S, index, true).length : 1);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvYWR2YW5jZS1zdHJpbmctaW5kZXguanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9hZHZhbmNlLXN0cmluZy1pbmRleC5qcz84YWE1Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcbnZhciBjb2RlUG9pbnRBdCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9zdHJpbmctYXQnKTtcblxuLy8gYEFkdmFuY2VTdHJpbmdJbmRleGAgYWJzdHJhY3Qgb3BlcmF0aW9uXG4vLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1hZHZhbmNlc3RyaW5naW5kZXhcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKFMsIGluZGV4LCB1bmljb2RlKSB7XG4gIHJldHVybiBpbmRleCArICh1bmljb2RlID8gY29kZVBvaW50QXQoUywgaW5kZXgsIHRydWUpLmxlbmd0aCA6IDEpO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/advance-string-index.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/an-instance.js": +/*!*******************************************************!*\ + !*** ./node_modules/core-js/internals/an-instance.js ***! + \*******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("module.exports = function (it, Constructor, name) {\n if (!(it instanceof Constructor)) {\n throw TypeError('Incorrect ' + (name ? name + ' ' : '') + 'invocation');\n } return it;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvYW4taW5zdGFuY2UuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9hbi1pbnN0YW5jZS5qcz8xOWFhIl0sInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0LCBDb25zdHJ1Y3RvciwgbmFtZSkge1xuICBpZiAoIShpdCBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkge1xuICAgIHRocm93IFR5cGVFcnJvcignSW5jb3JyZWN0ICcgKyAobmFtZSA/IG5hbWUgKyAnICcgOiAnJykgKyAnaW52b2NhdGlvbicpO1xuICB9IHJldHVybiBpdDtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/an-instance.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/an-object.js": +/*!*****************************************************!*\ + !*** ./node_modules/core-js/internals/an-object.js ***! + \*****************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var isObject = __webpack_require__(/*! ../internals/is-object */ \"./node_modules/core-js/internals/is-object.js\");\n\nmodule.exports = function (it) {\n if (!isObject(it)) {\n throw TypeError(String(it) + ' is not an object');\n } return it;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvYW4tb2JqZWN0LmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvYW4tb2JqZWN0LmpzPzgyNWEiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2lzLW9iamVjdCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICBpZiAoIWlzT2JqZWN0KGl0KSkge1xuICAgIHRocm93IFR5cGVFcnJvcihTdHJpbmcoaXQpICsgJyBpcyBub3QgYW4gb2JqZWN0Jyk7XG4gIH0gcmV0dXJuIGl0O1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/an-object.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/array-includes.js": +/*!**********************************************************!*\ + !*** ./node_modules/core-js/internals/array-includes.js ***! + \**********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var toIndexedObject = __webpack_require__(/*! ../internals/to-indexed-object */ \"./node_modules/core-js/internals/to-indexed-object.js\");\nvar toLength = __webpack_require__(/*! ../internals/to-length */ \"./node_modules/core-js/internals/to-length.js\");\nvar toAbsoluteIndex = __webpack_require__(/*! ../internals/to-absolute-index */ \"./node_modules/core-js/internals/to-absolute-index.js\");\n\n// `Array.prototype.{ indexOf, includes }` methods implementation\n// false -> Array#indexOf\n// https://tc39.github.io/ecma262/#sec-array.prototype.indexof\n// true -> Array#includes\n// https://tc39.github.io/ecma262/#sec-array.prototype.includes\nmodule.exports = function (IS_INCLUDES) {\n return function ($this, el, fromIndex) {\n var O = toIndexedObject($this);\n var length = toLength(O.length);\n var index = toAbsoluteIndex(fromIndex, length);\n var value;\n // Array#includes uses SameValueZero equality algorithm\n // eslint-disable-next-line no-self-compare\n if (IS_INCLUDES && el != el) while (length > index) {\n value = O[index++];\n // eslint-disable-next-line no-self-compare\n if (value != value) return true;\n // Array#indexOf ignores holes, Array#includes - not\n } else for (;length > index; index++) if (IS_INCLUDES || index in O) {\n if (O[index] === el) return IS_INCLUDES || index || 0;\n } return !IS_INCLUDES && -1;\n };\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvYXJyYXktaW5jbHVkZXMuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9hcnJheS1pbmNsdWRlcy5qcz80ZDY0Il0sInNvdXJjZXNDb250ZW50IjpbInZhciB0b0luZGV4ZWRPYmplY3QgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvdG8taW5kZXhlZC1vYmplY3QnKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy90by1sZW5ndGgnKTtcbnZhciB0b0Fic29sdXRlSW5kZXggPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvdG8tYWJzb2x1dGUtaW5kZXgnKTtcblxuLy8gYEFycmF5LnByb3RvdHlwZS57IGluZGV4T2YsIGluY2x1ZGVzIH1gIG1ldGhvZHMgaW1wbGVtZW50YXRpb25cbi8vIGZhbHNlIC0+IEFycmF5I2luZGV4T2Zcbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLWFycmF5LnByb3RvdHlwZS5pbmRleG9mXG4vLyB0cnVlICAtPiBBcnJheSNpbmNsdWRlc1xuLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtYXJyYXkucHJvdG90eXBlLmluY2x1ZGVzXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChJU19JTkNMVURFUykge1xuICByZXR1cm4gZnVuY3Rpb24gKCR0aGlzLCBlbCwgZnJvbUluZGV4KSB7XG4gICAgdmFyIE8gPSB0b0luZGV4ZWRPYmplY3QoJHRoaXMpO1xuICAgIHZhciBsZW5ndGggPSB0b0xlbmd0aChPLmxlbmd0aCk7XG4gICAgdmFyIGluZGV4ID0gdG9BYnNvbHV0ZUluZGV4KGZyb21JbmRleCwgbGVuZ3RoKTtcbiAgICB2YXIgdmFsdWU7XG4gICAgLy8gQXJyYXkjaW5jbHVkZXMgdXNlcyBTYW1lVmFsdWVaZXJvIGVxdWFsaXR5IGFsZ29yaXRobVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgICBpZiAoSVNfSU5DTFVERVMgJiYgZWwgIT0gZWwpIHdoaWxlIChsZW5ndGggPiBpbmRleCkge1xuICAgICAgdmFsdWUgPSBPW2luZGV4KytdO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNlbGYtY29tcGFyZVxuICAgICAgaWYgKHZhbHVlICE9IHZhbHVlKSByZXR1cm4gdHJ1ZTtcbiAgICAvLyBBcnJheSNpbmRleE9mIGlnbm9yZXMgaG9sZXMsIEFycmF5I2luY2x1ZGVzIC0gbm90XG4gICAgfSBlbHNlIGZvciAoO2xlbmd0aCA+IGluZGV4OyBpbmRleCsrKSBpZiAoSVNfSU5DTFVERVMgfHwgaW5kZXggaW4gTykge1xuICAgICAgaWYgKE9baW5kZXhdID09PSBlbCkgcmV0dXJuIElTX0lOQ0xVREVTIHx8IGluZGV4IHx8IDA7XG4gICAgfSByZXR1cm4gIUlTX0lOQ0xVREVTICYmIC0xO1xuICB9O1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/array-includes.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/bind-context.js": +/*!********************************************************!*\ + !*** ./node_modules/core-js/internals/bind-context.js ***! + \********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var aFunction = __webpack_require__(/*! ../internals/a-function */ \"./node_modules/core-js/internals/a-function.js\");\n\n// optional / simple context binding\nmodule.exports = function (fn, that, length) {\n aFunction(fn);\n if (that === undefined) return fn;\n switch (length) {\n case 0: return function () {\n return fn.call(that);\n };\n case 1: return function (a) {\n return fn.call(that, a);\n };\n case 2: return function (a, b) {\n return fn.call(that, a, b);\n };\n case 3: return function (a, b, c) {\n return fn.call(that, a, b, c);\n };\n }\n return function (/* ...args */) {\n return fn.apply(that, arguments);\n };\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvYmluZC1jb250ZXh0LmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvYmluZC1jb250ZXh0LmpzP2Y4YzIiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9hLWZ1bmN0aW9uJyk7XG5cbi8vIG9wdGlvbmFsIC8gc2ltcGxlIGNvbnRleHQgYmluZGluZ1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZm4sIHRoYXQsIGxlbmd0aCkge1xuICBhRnVuY3Rpb24oZm4pO1xuICBpZiAodGhhdCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gZm47XG4gIHN3aXRjaCAobGVuZ3RoKSB7XG4gICAgY2FzZSAwOiByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCk7XG4gICAgfTtcbiAgICBjYXNlIDE6IHJldHVybiBmdW5jdGlvbiAoYSkge1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSk7XG4gICAgfTtcbiAgICBjYXNlIDI6IHJldHVybiBmdW5jdGlvbiAoYSwgYikge1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSwgYik7XG4gICAgfTtcbiAgICBjYXNlIDM6IHJldHVybiBmdW5jdGlvbiAoYSwgYiwgYykge1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSwgYiwgYyk7XG4gICAgfTtcbiAgfVxuICByZXR1cm4gZnVuY3Rpb24gKC8qIC4uLmFyZ3MgKi8pIHtcbiAgICByZXR1cm4gZm4uYXBwbHkodGhhdCwgYXJndW1lbnRzKTtcbiAgfTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/bind-context.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/call-with-safe-iteration-closing.js": +/*!****************************************************************************!*\ + !*** ./node_modules/core-js/internals/call-with-safe-iteration-closing.js ***! + \****************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var anObject = __webpack_require__(/*! ../internals/an-object */ \"./node_modules/core-js/internals/an-object.js\");\n\n// call something on iterator step with safe closing on error\nmodule.exports = function (iterator, fn, value, ENTRIES) {\n try {\n return ENTRIES ? fn(anObject(value)[0], value[1]) : fn(value);\n // 7.4.6 IteratorClose(iterator, completion)\n } catch (error) {\n var returnMethod = iterator['return'];\n if (returnMethod !== undefined) anObject(returnMethod.call(iterator));\n throw error;\n }\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvY2FsbC13aXRoLXNhZmUtaXRlcmF0aW9uLWNsb3NpbmcuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9jYWxsLXdpdGgtc2FmZS1pdGVyYXRpb24tY2xvc2luZy5qcz85YmRkIl0sInNvdXJjZXNDb250ZW50IjpbInZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9hbi1vYmplY3QnKTtcblxuLy8gY2FsbCBzb21ldGhpbmcgb24gaXRlcmF0b3Igc3RlcCB3aXRoIHNhZmUgY2xvc2luZyBvbiBlcnJvclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXRlcmF0b3IsIGZuLCB2YWx1ZSwgRU5UUklFUykge1xuICB0cnkge1xuICAgIHJldHVybiBFTlRSSUVTID8gZm4oYW5PYmplY3QodmFsdWUpWzBdLCB2YWx1ZVsxXSkgOiBmbih2YWx1ZSk7XG4gIC8vIDcuNC42IEl0ZXJhdG9yQ2xvc2UoaXRlcmF0b3IsIGNvbXBsZXRpb24pXG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgdmFyIHJldHVybk1ldGhvZCA9IGl0ZXJhdG9yWydyZXR1cm4nXTtcbiAgICBpZiAocmV0dXJuTWV0aG9kICE9PSB1bmRlZmluZWQpIGFuT2JqZWN0KHJldHVybk1ldGhvZC5jYWxsKGl0ZXJhdG9yKSk7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/call-with-safe-iteration-closing.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/check-correctness-of-iteration.js": +/*!**************************************************************************!*\ + !*** ./node_modules/core-js/internals/check-correctness-of-iteration.js ***! + \**************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ \"./node_modules/core-js/internals/well-known-symbol.js\");\n\nvar ITERATOR = wellKnownSymbol('iterator');\nvar SAFE_CLOSING = false;\n\ntry {\n var called = 0;\n var iteratorWithReturn = {\n next: function () {\n return { done: !!called++ };\n },\n 'return': function () {\n SAFE_CLOSING = true;\n }\n };\n iteratorWithReturn[ITERATOR] = function () {\n return this;\n };\n // eslint-disable-next-line no-throw-literal\n Array.from(iteratorWithReturn, function () { throw 2; });\n} catch (error) { /* empty */ }\n\nmodule.exports = function (exec, SKIP_CLOSING) {\n if (!SKIP_CLOSING && !SAFE_CLOSING) return false;\n var ITERATION_SUPPORT = false;\n try {\n var object = {};\n object[ITERATOR] = function () {\n return {\n next: function () {\n return { done: ITERATION_SUPPORT = true };\n }\n };\n };\n exec(object);\n } catch (error) { /* empty */ }\n return ITERATION_SUPPORT;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvY2hlY2stY29ycmVjdG5lc3Mtb2YtaXRlcmF0aW9uLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvY2hlY2stY29ycmVjdG5lc3Mtb2YtaXRlcmF0aW9uLmpzPzFjN2UiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIHdlbGxLbm93blN5bWJvbCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy93ZWxsLWtub3duLXN5bWJvbCcpO1xuXG52YXIgSVRFUkFUT1IgPSB3ZWxsS25vd25TeW1ib2woJ2l0ZXJhdG9yJyk7XG52YXIgU0FGRV9DTE9TSU5HID0gZmFsc2U7XG5cbnRyeSB7XG4gIHZhciBjYWxsZWQgPSAwO1xuICB2YXIgaXRlcmF0b3JXaXRoUmV0dXJuID0ge1xuICAgIG5leHQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiB7IGRvbmU6ICEhY2FsbGVkKysgfTtcbiAgICB9LFxuICAgICdyZXR1cm4nOiBmdW5jdGlvbiAoKSB7XG4gICAgICBTQUZFX0NMT1NJTkcgPSB0cnVlO1xuICAgIH1cbiAgfTtcbiAgaXRlcmF0b3JXaXRoUmV0dXJuW0lURVJBVE9SXSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXRocm93LWxpdGVyYWxcbiAgQXJyYXkuZnJvbShpdGVyYXRvcldpdGhSZXR1cm4sIGZ1bmN0aW9uICgpIHsgdGhyb3cgMjsgfSk7XG59IGNhdGNoIChlcnJvcikgeyAvKiBlbXB0eSAqLyB9XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGV4ZWMsIFNLSVBfQ0xPU0lORykge1xuICBpZiAoIVNLSVBfQ0xPU0lORyAmJiAhU0FGRV9DTE9TSU5HKSByZXR1cm4gZmFsc2U7XG4gIHZhciBJVEVSQVRJT05fU1VQUE9SVCA9IGZhbHNlO1xuICB0cnkge1xuICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICBvYmplY3RbSVRFUkFUT1JdID0gZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbmV4dDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHJldHVybiB7IGRvbmU6IElURVJBVElPTl9TVVBQT1JUID0gdHJ1ZSB9O1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH07XG4gICAgZXhlYyhvYmplY3QpO1xuICB9IGNhdGNoIChlcnJvcikgeyAvKiBlbXB0eSAqLyB9XG4gIHJldHVybiBJVEVSQVRJT05fU1VQUE9SVDtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/check-correctness-of-iteration.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/classof-raw.js": +/*!*******************************************************!*\ + !*** ./node_modules/core-js/internals/classof-raw.js ***! + \*******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("var toString = {}.toString;\n\nmodule.exports = function (it) {\n return toString.call(it).slice(8, -1);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvY2xhc3NvZi1yYXcuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9jbGFzc29mLXJhdy5qcz9jNmI2Il0sInNvdXJjZXNDb250ZW50IjpbInZhciB0b1N0cmluZyA9IHt9LnRvU3RyaW5nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbChpdCkuc2xpY2UoOCwgLTEpO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/classof-raw.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/classof.js": +/*!***************************************************!*\ + !*** ./node_modules/core-js/internals/classof.js ***! + \***************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var classofRaw = __webpack_require__(/*! ../internals/classof-raw */ \"./node_modules/core-js/internals/classof-raw.js\");\nvar wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ \"./node_modules/core-js/internals/well-known-symbol.js\");\n\nvar TO_STRING_TAG = wellKnownSymbol('toStringTag');\n// ES3 wrong here\nvar CORRECT_ARGUMENTS = classofRaw(function () { return arguments; }()) == 'Arguments';\n\n// fallback for IE11 Script Access Denied error\nvar tryGet = function (it, key) {\n try {\n return it[key];\n } catch (error) { /* empty */ }\n};\n\n// getting tag from ES6+ `Object.prototype.toString`\nmodule.exports = function (it) {\n var O, tag, result;\n return it === undefined ? 'Undefined' : it === null ? 'Null'\n // @@toStringTag case\n : typeof (tag = tryGet(O = Object(it), TO_STRING_TAG)) == 'string' ? tag\n // builtinTag case\n : CORRECT_ARGUMENTS ? classofRaw(O)\n // ES3 arguments fallback\n : (result = classofRaw(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : result;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvY2xhc3NvZi5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL2NsYXNzb2YuanM/ZjVkZiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgY2xhc3NvZlJhdyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9jbGFzc29mLXJhdycpO1xudmFyIHdlbGxLbm93blN5bWJvbCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy93ZWxsLWtub3duLXN5bWJvbCcpO1xuXG52YXIgVE9fU1RSSU5HX1RBRyA9IHdlbGxLbm93blN5bWJvbCgndG9TdHJpbmdUYWcnKTtcbi8vIEVTMyB3cm9uZyBoZXJlXG52YXIgQ09SUkVDVF9BUkdVTUVOVFMgPSBjbGFzc29mUmF3KGZ1bmN0aW9uICgpIHsgcmV0dXJuIGFyZ3VtZW50czsgfSgpKSA9PSAnQXJndW1lbnRzJztcblxuLy8gZmFsbGJhY2sgZm9yIElFMTEgU2NyaXB0IEFjY2VzcyBEZW5pZWQgZXJyb3JcbnZhciB0cnlHZXQgPSBmdW5jdGlvbiAoaXQsIGtleSkge1xuICB0cnkge1xuICAgIHJldHVybiBpdFtrZXldO1xuICB9IGNhdGNoIChlcnJvcikgeyAvKiBlbXB0eSAqLyB9XG59O1xuXG4vLyBnZXR0aW5nIHRhZyBmcm9tIEVTNisgYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmdgXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICB2YXIgTywgdGFnLCByZXN1bHQ7XG4gIHJldHVybiBpdCA9PT0gdW5kZWZpbmVkID8gJ1VuZGVmaW5lZCcgOiBpdCA9PT0gbnVsbCA/ICdOdWxsJ1xuICAgIC8vIEBAdG9TdHJpbmdUYWcgY2FzZVxuICAgIDogdHlwZW9mICh0YWcgPSB0cnlHZXQoTyA9IE9iamVjdChpdCksIFRPX1NUUklOR19UQUcpKSA9PSAnc3RyaW5nJyA/IHRhZ1xuICAgIC8vIGJ1aWx0aW5UYWcgY2FzZVxuICAgIDogQ09SUkVDVF9BUkdVTUVOVFMgPyBjbGFzc29mUmF3KE8pXG4gICAgLy8gRVMzIGFyZ3VtZW50cyBmYWxsYmFja1xuICAgIDogKHJlc3VsdCA9IGNsYXNzb2ZSYXcoTykpID09ICdPYmplY3QnICYmIHR5cGVvZiBPLmNhbGxlZSA9PSAnZnVuY3Rpb24nID8gJ0FyZ3VtZW50cycgOiByZXN1bHQ7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/classof.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/copy-constructor-properties.js": +/*!***********************************************************************!*\ + !*** ./node_modules/core-js/internals/copy-constructor-properties.js ***! + \***********************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var has = __webpack_require__(/*! ../internals/has */ \"./node_modules/core-js/internals/has.js\");\nvar ownKeys = __webpack_require__(/*! ../internals/own-keys */ \"./node_modules/core-js/internals/own-keys.js\");\nvar getOwnPropertyDescriptorModule = __webpack_require__(/*! ../internals/object-get-own-property-descriptor */ \"./node_modules/core-js/internals/object-get-own-property-descriptor.js\");\nvar definePropertyModule = __webpack_require__(/*! ../internals/object-define-property */ \"./node_modules/core-js/internals/object-define-property.js\");\n\nmodule.exports = function (target, source) {\n var keys = ownKeys(source);\n var defineProperty = definePropertyModule.f;\n var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f;\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n if (!has(target, key)) defineProperty(target, key, getOwnPropertyDescriptor(source, key));\n }\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvY29weS1jb25zdHJ1Y3Rvci1wcm9wZXJ0aWVzLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvY29weS1jb25zdHJ1Y3Rvci1wcm9wZXJ0aWVzLmpzP2U4OTMiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIGhhcyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9oYXMnKTtcbnZhciBvd25LZXlzID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL293bi1rZXlzJyk7XG52YXIgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yTW9kdWxlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL29iamVjdC1nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3InKTtcbnZhciBkZWZpbmVQcm9wZXJ0eU1vZHVsZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9vYmplY3QtZGVmaW5lLXByb3BlcnR5Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHRhcmdldCwgc291cmNlKSB7XG4gIHZhciBrZXlzID0gb3duS2V5cyhzb3VyY2UpO1xuICB2YXIgZGVmaW5lUHJvcGVydHkgPSBkZWZpbmVQcm9wZXJ0eU1vZHVsZS5mO1xuICB2YXIgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID0gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yTW9kdWxlLmY7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBrZXkgPSBrZXlzW2ldO1xuICAgIGlmICghaGFzKHRhcmdldCwga2V5KSkgZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIGdldE93blByb3BlcnR5RGVzY3JpcHRvcihzb3VyY2UsIGtleSkpO1xuICB9XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/copy-constructor-properties.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/correct-is-regexp-logic.js": +/*!*******************************************************************!*\ + !*** ./node_modules/core-js/internals/correct-is-regexp-logic.js ***! + \*******************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ \"./node_modules/core-js/internals/well-known-symbol.js\");\n\nvar MATCH = wellKnownSymbol('match');\n\nmodule.exports = function (METHOD_NAME) {\n var regexp = /./;\n try {\n '/./'[METHOD_NAME](regexp);\n } catch (e) {\n try {\n regexp[MATCH] = false;\n return '/./'[METHOD_NAME](regexp);\n } catch (f) { /* empty */ }\n } return false;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvY29ycmVjdC1pcy1yZWdleHAtbG9naWMuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9jb3JyZWN0LWlzLXJlZ2V4cC1sb2dpYy5qcz9hYjEzIl0sInNvdXJjZXNDb250ZW50IjpbInZhciB3ZWxsS25vd25TeW1ib2wgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvd2VsbC1rbm93bi1zeW1ib2wnKTtcblxudmFyIE1BVENIID0gd2VsbEtub3duU3ltYm9sKCdtYXRjaCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChNRVRIT0RfTkFNRSkge1xuICB2YXIgcmVnZXhwID0gLy4vO1xuICB0cnkge1xuICAgICcvLi8nW01FVEhPRF9OQU1FXShyZWdleHApO1xuICB9IGNhdGNoIChlKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJlZ2V4cFtNQVRDSF0gPSBmYWxzZTtcbiAgICAgIHJldHVybiAnLy4vJ1tNRVRIT0RfTkFNRV0ocmVnZXhwKTtcbiAgICB9IGNhdGNoIChmKSB7IC8qIGVtcHR5ICovIH1cbiAgfSByZXR1cm4gZmFsc2U7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/correct-is-regexp-logic.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/correct-prototype-getter.js": +/*!********************************************************************!*\ + !*** ./node_modules/core-js/internals/correct-prototype-getter.js ***! + \********************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var fails = __webpack_require__(/*! ../internals/fails */ \"./node_modules/core-js/internals/fails.js\");\n\nmodule.exports = !fails(function () {\n function F() { /* empty */ }\n F.prototype.constructor = null;\n return Object.getPrototypeOf(new F()) !== F.prototype;\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvY29ycmVjdC1wcm90b3R5cGUtZ2V0dGVyLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvY29ycmVjdC1wcm90b3R5cGUtZ2V0dGVyLmpzP2UxNzciXSwic291cmNlc0NvbnRlbnQiOlsidmFyIGZhaWxzID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2ZhaWxzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gRigpIHsgLyogZW1wdHkgKi8gfVxuICBGLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IG51bGw7XG4gIHJldHVybiBPYmplY3QuZ2V0UHJvdG90eXBlT2YobmV3IEYoKSkgIT09IEYucHJvdG90eXBlO1xufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/correct-prototype-getter.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/create-html.js": +/*!*******************************************************!*\ + !*** ./node_modules/core-js/internals/create-html.js ***! + \*******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var requireObjectCoercible = __webpack_require__(/*! ../internals/require-object-coercible */ \"./node_modules/core-js/internals/require-object-coercible.js\");\n\nvar quot = /\"/g;\n\n// B.2.3.2.1 CreateHTML(string, tag, attribute, value)\n// https://tc39.github.io/ecma262/#sec-createhtml\nmodule.exports = function (string, tag, attribute, value) {\n var S = String(requireObjectCoercible(string));\n var p1 = '<' + tag;\n if (attribute !== '') p1 += ' ' + attribute + '=\"' + String(value).replace(quot, '"') + '\"';\n return p1 + '>' + S + '';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvY3JlYXRlLWh0bWwuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9jcmVhdGUtaHRtbC5qcz84NTdhIl0sInNvdXJjZXNDb250ZW50IjpbInZhciByZXF1aXJlT2JqZWN0Q29lcmNpYmxlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3JlcXVpcmUtb2JqZWN0LWNvZXJjaWJsZScpO1xuXG52YXIgcXVvdCA9IC9cIi9nO1xuXG4vLyBCLjIuMy4yLjEgQ3JlYXRlSFRNTChzdHJpbmcsIHRhZywgYXR0cmlidXRlLCB2YWx1ZSlcbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLWNyZWF0ZWh0bWxcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHN0cmluZywgdGFnLCBhdHRyaWJ1dGUsIHZhbHVlKSB7XG4gIHZhciBTID0gU3RyaW5nKHJlcXVpcmVPYmplY3RDb2VyY2libGUoc3RyaW5nKSk7XG4gIHZhciBwMSA9ICc8JyArIHRhZztcbiAgaWYgKGF0dHJpYnV0ZSAhPT0gJycpIHAxICs9ICcgJyArIGF0dHJpYnV0ZSArICc9XCInICsgU3RyaW5nKHZhbHVlKS5yZXBsYWNlKHF1b3QsICcmcXVvdDsnKSArICdcIic7XG4gIHJldHVybiBwMSArICc+JyArIFMgKyAnPC8nICsgdGFnICsgJz4nO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/create-html.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/create-iterator-constructor.js": +/*!***********************************************************************!*\ + !*** ./node_modules/core-js/internals/create-iterator-constructor.js ***! + \***********************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar IteratorPrototype = __webpack_require__(/*! ../internals/iterators-core */ \"./node_modules/core-js/internals/iterators-core.js\").IteratorPrototype;\nvar create = __webpack_require__(/*! ../internals/object-create */ \"./node_modules/core-js/internals/object-create.js\");\nvar createPropertyDescriptor = __webpack_require__(/*! ../internals/create-property-descriptor */ \"./node_modules/core-js/internals/create-property-descriptor.js\");\nvar setToStringTag = __webpack_require__(/*! ../internals/set-to-string-tag */ \"./node_modules/core-js/internals/set-to-string-tag.js\");\nvar Iterators = __webpack_require__(/*! ../internals/iterators */ \"./node_modules/core-js/internals/iterators.js\");\n\nvar returnThis = function () { return this; };\n\nmodule.exports = function (IteratorConstructor, NAME, next) {\n var TO_STRING_TAG = NAME + ' Iterator';\n IteratorConstructor.prototype = create(IteratorPrototype, { next: createPropertyDescriptor(1, next) });\n setToStringTag(IteratorConstructor, TO_STRING_TAG, false, true);\n Iterators[TO_STRING_TAG] = returnThis;\n return IteratorConstructor;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvY3JlYXRlLWl0ZXJhdG9yLWNvbnN0cnVjdG9yLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvY3JlYXRlLWl0ZXJhdG9yLWNvbnN0cnVjdG9yLmpzPzllZDMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xudmFyIEl0ZXJhdG9yUHJvdG90eXBlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2l0ZXJhdG9ycy1jb3JlJykuSXRlcmF0b3JQcm90b3R5cGU7XG52YXIgY3JlYXRlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL29iamVjdC1jcmVhdGUnKTtcbnZhciBjcmVhdGVQcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvY3JlYXRlLXByb3BlcnR5LWRlc2NyaXB0b3InKTtcbnZhciBzZXRUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9zZXQtdG8tc3RyaW5nLXRhZycpO1xudmFyIEl0ZXJhdG9ycyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9pdGVyYXRvcnMnKTtcblxudmFyIHJldHVyblRoaXMgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChJdGVyYXRvckNvbnN0cnVjdG9yLCBOQU1FLCBuZXh0KSB7XG4gIHZhciBUT19TVFJJTkdfVEFHID0gTkFNRSArICcgSXRlcmF0b3InO1xuICBJdGVyYXRvckNvbnN0cnVjdG9yLnByb3RvdHlwZSA9IGNyZWF0ZShJdGVyYXRvclByb3RvdHlwZSwgeyBuZXh0OiBjcmVhdGVQcm9wZXJ0eURlc2NyaXB0b3IoMSwgbmV4dCkgfSk7XG4gIHNldFRvU3RyaW5nVGFnKEl0ZXJhdG9yQ29uc3RydWN0b3IsIFRPX1NUUklOR19UQUcsIGZhbHNlLCB0cnVlKTtcbiAgSXRlcmF0b3JzW1RPX1NUUklOR19UQUddID0gcmV0dXJuVGhpcztcbiAgcmV0dXJuIEl0ZXJhdG9yQ29uc3RydWN0b3I7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/create-iterator-constructor.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/create-property-descriptor.js": +/*!**********************************************************************!*\ + !*** ./node_modules/core-js/internals/create-property-descriptor.js ***! + \**********************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("module.exports = function (bitmap, value) {\n return {\n enumerable: !(bitmap & 1),\n configurable: !(bitmap & 2),\n writable: !(bitmap & 4),\n value: value\n };\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvY3JlYXRlLXByb3BlcnR5LWRlc2NyaXB0b3IuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9jcmVhdGUtcHJvcGVydHktZGVzY3JpcHRvci5qcz81YzZjIl0sInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGJpdG1hcCwgdmFsdWUpIHtcbiAgcmV0dXJuIHtcbiAgICBlbnVtZXJhYmxlOiAhKGJpdG1hcCAmIDEpLFxuICAgIGNvbmZpZ3VyYWJsZTogIShiaXRtYXAgJiAyKSxcbiAgICB3cml0YWJsZTogIShiaXRtYXAgJiA0KSxcbiAgICB2YWx1ZTogdmFsdWVcbiAgfTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/create-property-descriptor.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/define-iterator.js": +/*!***********************************************************!*\ + !*** ./node_modules/core-js/internals/define-iterator.js ***! + \***********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar createIteratorConstructor = __webpack_require__(/*! ../internals/create-iterator-constructor */ \"./node_modules/core-js/internals/create-iterator-constructor.js\");\nvar getPrototypeOf = __webpack_require__(/*! ../internals/object-get-prototype-of */ \"./node_modules/core-js/internals/object-get-prototype-of.js\");\nvar setPrototypeOf = __webpack_require__(/*! ../internals/object-set-prototype-of */ \"./node_modules/core-js/internals/object-set-prototype-of.js\");\nvar setToStringTag = __webpack_require__(/*! ../internals/set-to-string-tag */ \"./node_modules/core-js/internals/set-to-string-tag.js\");\nvar hide = __webpack_require__(/*! ../internals/hide */ \"./node_modules/core-js/internals/hide.js\");\nvar redefine = __webpack_require__(/*! ../internals/redefine */ \"./node_modules/core-js/internals/redefine.js\");\nvar wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ \"./node_modules/core-js/internals/well-known-symbol.js\");\nvar IS_PURE = __webpack_require__(/*! ../internals/is-pure */ \"./node_modules/core-js/internals/is-pure.js\");\nvar Iterators = __webpack_require__(/*! ../internals/iterators */ \"./node_modules/core-js/internals/iterators.js\");\nvar IteratorsCore = __webpack_require__(/*! ../internals/iterators-core */ \"./node_modules/core-js/internals/iterators-core.js\");\n\nvar IteratorPrototype = IteratorsCore.IteratorPrototype;\nvar BUGGY_SAFARI_ITERATORS = IteratorsCore.BUGGY_SAFARI_ITERATORS;\nvar ITERATOR = wellKnownSymbol('iterator');\nvar KEYS = 'keys';\nvar VALUES = 'values';\nvar ENTRIES = 'entries';\n\nvar returnThis = function () { return this; };\n\nmodule.exports = function (Iterable, NAME, IteratorConstructor, next, DEFAULT, IS_SET, FORCED) {\n createIteratorConstructor(IteratorConstructor, NAME, next);\n\n var getIterationMethod = function (KIND) {\n if (KIND === DEFAULT && defaultIterator) return defaultIterator;\n if (!BUGGY_SAFARI_ITERATORS && KIND in IterablePrototype) return IterablePrototype[KIND];\n switch (KIND) {\n case KEYS: return function keys() { return new IteratorConstructor(this, KIND); };\n case VALUES: return function values() { return new IteratorConstructor(this, KIND); };\n case ENTRIES: return function entries() { return new IteratorConstructor(this, KIND); };\n } return function () { return new IteratorConstructor(this); };\n };\n\n var TO_STRING_TAG = NAME + ' Iterator';\n var INCORRECT_VALUES_NAME = false;\n var IterablePrototype = Iterable.prototype;\n var nativeIterator = IterablePrototype[ITERATOR]\n || IterablePrototype['@@iterator']\n || DEFAULT && IterablePrototype[DEFAULT];\n var defaultIterator = !BUGGY_SAFARI_ITERATORS && nativeIterator || getIterationMethod(DEFAULT);\n var anyNativeIterator = NAME == 'Array' ? IterablePrototype.entries || nativeIterator : nativeIterator;\n var CurrentIteratorPrototype, methods, KEY;\n\n // fix native\n if (anyNativeIterator) {\n CurrentIteratorPrototype = getPrototypeOf(anyNativeIterator.call(new Iterable()));\n if (IteratorPrototype !== Object.prototype && CurrentIteratorPrototype.next) {\n if (!IS_PURE && getPrototypeOf(CurrentIteratorPrototype) !== IteratorPrototype) {\n if (setPrototypeOf) {\n setPrototypeOf(CurrentIteratorPrototype, IteratorPrototype);\n } else if (typeof CurrentIteratorPrototype[ITERATOR] != 'function') {\n hide(CurrentIteratorPrototype, ITERATOR, returnThis);\n }\n }\n // Set @@toStringTag to native iterators\n setToStringTag(CurrentIteratorPrototype, TO_STRING_TAG, true, true);\n if (IS_PURE) Iterators[TO_STRING_TAG] = returnThis;\n }\n }\n\n // fix Array#{values, @@iterator}.name in V8 / FF\n if (DEFAULT == VALUES && nativeIterator && nativeIterator.name !== VALUES) {\n INCORRECT_VALUES_NAME = true;\n defaultIterator = function values() { return nativeIterator.call(this); };\n }\n\n // define iterator\n if ((!IS_PURE || FORCED) && IterablePrototype[ITERATOR] !== defaultIterator) {\n hide(IterablePrototype, ITERATOR, defaultIterator);\n }\n Iterators[NAME] = defaultIterator;\n\n // export additional methods\n if (DEFAULT) {\n methods = {\n values: getIterationMethod(VALUES),\n keys: IS_SET ? defaultIterator : getIterationMethod(KEYS),\n entries: getIterationMethod(ENTRIES)\n };\n if (FORCED) for (KEY in methods) {\n if (BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME || !(KEY in IterablePrototype)) {\n redefine(IterablePrototype, KEY, methods[KEY]);\n }\n } else $({ target: NAME, proto: true, forced: BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME }, methods);\n }\n\n return methods;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvZGVmaW5lLWl0ZXJhdG9yLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvZGVmaW5lLWl0ZXJhdG9yLmpzPzdkZDAiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xudmFyICQgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZXhwb3J0Jyk7XG52YXIgY3JlYXRlSXRlcmF0b3JDb25zdHJ1Y3RvciA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9jcmVhdGUtaXRlcmF0b3ItY29uc3RydWN0b3InKTtcbnZhciBnZXRQcm90b3R5cGVPZiA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9vYmplY3QtZ2V0LXByb3RvdHlwZS1vZicpO1xudmFyIHNldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL29iamVjdC1zZXQtcHJvdG90eXBlLW9mJyk7XG52YXIgc2V0VG9TdHJpbmdUYWcgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvc2V0LXRvLXN0cmluZy10YWcnKTtcbnZhciBoaWRlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2hpZGUnKTtcbnZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9yZWRlZmluZScpO1xudmFyIHdlbGxLbm93blN5bWJvbCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy93ZWxsLWtub3duLXN5bWJvbCcpO1xudmFyIElTX1BVUkUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaXMtcHVyZScpO1xudmFyIEl0ZXJhdG9ycyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9pdGVyYXRvcnMnKTtcbnZhciBJdGVyYXRvcnNDb3JlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2l0ZXJhdG9ycy1jb3JlJyk7XG5cbnZhciBJdGVyYXRvclByb3RvdHlwZSA9IEl0ZXJhdG9yc0NvcmUuSXRlcmF0b3JQcm90b3R5cGU7XG52YXIgQlVHR1lfU0FGQVJJX0lURVJBVE9SUyA9IEl0ZXJhdG9yc0NvcmUuQlVHR1lfU0FGQVJJX0lURVJBVE9SUztcbnZhciBJVEVSQVRPUiA9IHdlbGxLbm93blN5bWJvbCgnaXRlcmF0b3InKTtcbnZhciBLRVlTID0gJ2tleXMnO1xudmFyIFZBTFVFUyA9ICd2YWx1ZXMnO1xudmFyIEVOVFJJRVMgPSAnZW50cmllcyc7XG5cbnZhciByZXR1cm5UaGlzID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoSXRlcmFibGUsIE5BTUUsIEl0ZXJhdG9yQ29uc3RydWN0b3IsIG5leHQsIERFRkFVTFQsIElTX1NFVCwgRk9SQ0VEKSB7XG4gIGNyZWF0ZUl0ZXJhdG9yQ29uc3RydWN0b3IoSXRlcmF0b3JDb25zdHJ1Y3RvciwgTkFNRSwgbmV4dCk7XG5cbiAgdmFyIGdldEl0ZXJhdGlvbk1ldGhvZCA9IGZ1bmN0aW9uIChLSU5EKSB7XG4gICAgaWYgKEtJTkQgPT09IERFRkFVTFQgJiYgZGVmYXVsdEl0ZXJhdG9yKSByZXR1cm4gZGVmYXVsdEl0ZXJhdG9yO1xuICAgIGlmICghQlVHR1lfU0FGQVJJX0lURVJBVE9SUyAmJiBLSU5EIGluIEl0ZXJhYmxlUHJvdG90eXBlKSByZXR1cm4gSXRlcmFibGVQcm90b3R5cGVbS0lORF07XG4gICAgc3dpdGNoIChLSU5EKSB7XG4gICAgICBjYXNlIEtFWVM6IHJldHVybiBmdW5jdGlvbiBrZXlzKCkgeyByZXR1cm4gbmV3IEl0ZXJhdG9yQ29uc3RydWN0b3IodGhpcywgS0lORCk7IH07XG4gICAgICBjYXNlIFZBTFVFUzogcmV0dXJuIGZ1bmN0aW9uIHZhbHVlcygpIHsgcmV0dXJuIG5ldyBJdGVyYXRvckNvbnN0cnVjdG9yKHRoaXMsIEtJTkQpOyB9O1xuICAgICAgY2FzZSBFTlRSSUVTOiByZXR1cm4gZnVuY3Rpb24gZW50cmllcygpIHsgcmV0dXJuIG5ldyBJdGVyYXRvckNvbnN0cnVjdG9yKHRoaXMsIEtJTkQpOyB9O1xuICAgIH0gcmV0dXJuIGZ1bmN0aW9uICgpIHsgcmV0dXJuIG5ldyBJdGVyYXRvckNvbnN0cnVjdG9yKHRoaXMpOyB9O1xuICB9O1xuXG4gIHZhciBUT19TVFJJTkdfVEFHID0gTkFNRSArICcgSXRlcmF0b3InO1xuICB2YXIgSU5DT1JSRUNUX1ZBTFVFU19OQU1FID0gZmFsc2U7XG4gIHZhciBJdGVyYWJsZVByb3RvdHlwZSA9IEl0ZXJhYmxlLnByb3RvdHlwZTtcbiAgdmFyIG5hdGl2ZUl0ZXJhdG9yID0gSXRlcmFibGVQcm90b3R5cGVbSVRFUkFUT1JdXG4gICAgfHwgSXRlcmFibGVQcm90b3R5cGVbJ0BAaXRlcmF0b3InXVxuICAgIHx8IERFRkFVTFQgJiYgSXRlcmFibGVQcm90b3R5cGVbREVGQVVMVF07XG4gIHZhciBkZWZhdWx0SXRlcmF0b3IgPSAhQlVHR1lfU0FGQVJJX0lURVJBVE9SUyAmJiBuYXRpdmVJdGVyYXRvciB8fCBnZXRJdGVyYXRpb25NZXRob2QoREVGQVVMVCk7XG4gIHZhciBhbnlOYXRpdmVJdGVyYXRvciA9IE5BTUUgPT0gJ0FycmF5JyA/IEl0ZXJhYmxlUHJvdG90eXBlLmVudHJpZXMgfHwgbmF0aXZlSXRlcmF0b3IgOiBuYXRpdmVJdGVyYXRvcjtcbiAgdmFyIEN1cnJlbnRJdGVyYXRvclByb3RvdHlwZSwgbWV0aG9kcywgS0VZO1xuXG4gIC8vIGZpeCBuYXRpdmVcbiAgaWYgKGFueU5hdGl2ZUl0ZXJhdG9yKSB7XG4gICAgQ3VycmVudEl0ZXJhdG9yUHJvdG90eXBlID0gZ2V0UHJvdG90eXBlT2YoYW55TmF0aXZlSXRlcmF0b3IuY2FsbChuZXcgSXRlcmFibGUoKSkpO1xuICAgIGlmIChJdGVyYXRvclByb3RvdHlwZSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBDdXJyZW50SXRlcmF0b3JQcm90b3R5cGUubmV4dCkge1xuICAgICAgaWYgKCFJU19QVVJFICYmIGdldFByb3RvdHlwZU9mKEN1cnJlbnRJdGVyYXRvclByb3RvdHlwZSkgIT09IEl0ZXJhdG9yUHJvdG90eXBlKSB7XG4gICAgICAgIGlmIChzZXRQcm90b3R5cGVPZikge1xuICAgICAgICAgIHNldFByb3RvdHlwZU9mKEN1cnJlbnRJdGVyYXRvclByb3RvdHlwZSwgSXRlcmF0b3JQcm90b3R5cGUpO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBDdXJyZW50SXRlcmF0b3JQcm90b3R5cGVbSVRFUkFUT1JdICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICBoaWRlKEN1cnJlbnRJdGVyYXRvclByb3RvdHlwZSwgSVRFUkFUT1IsIHJldHVyblRoaXMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBTZXQgQEB0b1N0cmluZ1RhZyB0byBuYXRpdmUgaXRlcmF0b3JzXG4gICAgICBzZXRUb1N0cmluZ1RhZyhDdXJyZW50SXRlcmF0b3JQcm90b3R5cGUsIFRPX1NUUklOR19UQUcsIHRydWUsIHRydWUpO1xuICAgICAgaWYgKElTX1BVUkUpIEl0ZXJhdG9yc1tUT19TVFJJTkdfVEFHXSA9IHJldHVyblRoaXM7XG4gICAgfVxuICB9XG5cbiAgLy8gZml4IEFycmF5I3t2YWx1ZXMsIEBAaXRlcmF0b3J9Lm5hbWUgaW4gVjggLyBGRlxuICBpZiAoREVGQVVMVCA9PSBWQUxVRVMgJiYgbmF0aXZlSXRlcmF0b3IgJiYgbmF0aXZlSXRlcmF0b3IubmFtZSAhPT0gVkFMVUVTKSB7XG4gICAgSU5DT1JSRUNUX1ZBTFVFU19OQU1FID0gdHJ1ZTtcbiAgICBkZWZhdWx0SXRlcmF0b3IgPSBmdW5jdGlvbiB2YWx1ZXMoKSB7IHJldHVybiBuYXRpdmVJdGVyYXRvci5jYWxsKHRoaXMpOyB9O1xuICB9XG5cbiAgLy8gZGVmaW5lIGl0ZXJhdG9yXG4gIGlmICgoIUlTX1BVUkUgfHwgRk9SQ0VEKSAmJiBJdGVyYWJsZVByb3RvdHlwZVtJVEVSQVRPUl0gIT09IGRlZmF1bHRJdGVyYXRvcikge1xuICAgIGhpZGUoSXRlcmFibGVQcm90b3R5cGUsIElURVJBVE9SLCBkZWZhdWx0SXRlcmF0b3IpO1xuICB9XG4gIEl0ZXJhdG9yc1tOQU1FXSA9IGRlZmF1bHRJdGVyYXRvcjtcblxuICAvLyBleHBvcnQgYWRkaXRpb25hbCBtZXRob2RzXG4gIGlmIChERUZBVUxUKSB7XG4gICAgbWV0aG9kcyA9IHtcbiAgICAgIHZhbHVlczogZ2V0SXRlcmF0aW9uTWV0aG9kKFZBTFVFUyksXG4gICAgICBrZXlzOiBJU19TRVQgPyBkZWZhdWx0SXRlcmF0b3IgOiBnZXRJdGVyYXRpb25NZXRob2QoS0VZUyksXG4gICAgICBlbnRyaWVzOiBnZXRJdGVyYXRpb25NZXRob2QoRU5UUklFUylcbiAgICB9O1xuICAgIGlmIChGT1JDRUQpIGZvciAoS0VZIGluIG1ldGhvZHMpIHtcbiAgICAgIGlmIChCVUdHWV9TQUZBUklfSVRFUkFUT1JTIHx8IElOQ09SUkVDVF9WQUxVRVNfTkFNRSB8fCAhKEtFWSBpbiBJdGVyYWJsZVByb3RvdHlwZSkpIHtcbiAgICAgICAgcmVkZWZpbmUoSXRlcmFibGVQcm90b3R5cGUsIEtFWSwgbWV0aG9kc1tLRVldKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgJCh7IHRhcmdldDogTkFNRSwgcHJvdG86IHRydWUsIGZvcmNlZDogQlVHR1lfU0FGQVJJX0lURVJBVE9SUyB8fCBJTkNPUlJFQ1RfVkFMVUVTX05BTUUgfSwgbWV0aG9kcyk7XG4gIH1cblxuICByZXR1cm4gbWV0aG9kcztcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/define-iterator.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/descriptors.js": +/*!*******************************************************!*\ + !*** ./node_modules/core-js/internals/descriptors.js ***! + \*******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var fails = __webpack_require__(/*! ../internals/fails */ \"./node_modules/core-js/internals/fails.js\");\n\n// Thank's IE8 for his funny defineProperty\nmodule.exports = !fails(function () {\n return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvZGVzY3JpcHRvcnMuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9kZXNjcmlwdG9ycy5qcz84M2FiIl0sInNvdXJjZXNDb250ZW50IjpbInZhciBmYWlscyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9mYWlscycpO1xuXG4vLyBUaGFuaydzIElFOCBmb3IgaGlzIGZ1bm55IGRlZmluZVByb3BlcnR5XG5tb2R1bGUuZXhwb3J0cyA9ICFmYWlscyhmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdhJywgeyBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDc7IH0gfSkuYSAhPSA3O1xufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/descriptors.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/document-create-element.js": +/*!*******************************************************************!*\ + !*** ./node_modules/core-js/internals/document-create-element.js ***! + \*******************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var global = __webpack_require__(/*! ../internals/global */ \"./node_modules/core-js/internals/global.js\");\nvar isObject = __webpack_require__(/*! ../internals/is-object */ \"./node_modules/core-js/internals/is-object.js\");\n\nvar document = global.document;\n// typeof document.createElement is 'object' in old IE\nvar exist = isObject(document) && isObject(document.createElement);\n\nmodule.exports = function (it) {\n return exist ? document.createElement(it) : {};\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvZG9jdW1lbnQtY3JlYXRlLWVsZW1lbnQuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9kb2N1bWVudC1jcmVhdGUtZWxlbWVudC5qcz9jYzEyIl0sInNvdXJjZXNDb250ZW50IjpbInZhciBnbG9iYWwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZ2xvYmFsJyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaXMtb2JqZWN0Jyk7XG5cbnZhciBkb2N1bWVudCA9IGdsb2JhbC5kb2N1bWVudDtcbi8vIHR5cGVvZiBkb2N1bWVudC5jcmVhdGVFbGVtZW50IGlzICdvYmplY3QnIGluIG9sZCBJRVxudmFyIGV4aXN0ID0gaXNPYmplY3QoZG9jdW1lbnQpICYmIGlzT2JqZWN0KGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gZXhpc3QgPyBkb2N1bWVudC5jcmVhdGVFbGVtZW50KGl0KSA6IHt9O1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/document-create-element.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/dom-iterables.js": +/*!*********************************************************!*\ + !*** ./node_modules/core-js/internals/dom-iterables.js ***! + \*********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("// iterable DOM collections\n// flag - `iterable` interface - 'entries', 'keys', 'values', 'forEach' methods\nmodule.exports = {\n CSSRuleList: 0,\n CSSStyleDeclaration: 0,\n CSSValueList: 0,\n ClientRectList: 0,\n DOMRectList: 0,\n DOMStringList: 0,\n DOMTokenList: 1,\n DataTransferItemList: 0,\n FileList: 0,\n HTMLAllCollection: 0,\n HTMLCollection: 0,\n HTMLFormElement: 0,\n HTMLSelectElement: 0,\n MediaList: 0,\n MimeTypeArray: 0,\n NamedNodeMap: 0,\n NodeList: 1,\n PaintRequestList: 0,\n Plugin: 0,\n PluginArray: 0,\n SVGLengthList: 0,\n SVGNumberList: 0,\n SVGPathSegList: 0,\n SVGPointList: 0,\n SVGStringList: 0,\n SVGTransformList: 0,\n SourceBufferList: 0,\n StyleSheetList: 0,\n TextTrackCueList: 0,\n TextTrackList: 0,\n TouchList: 0\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvZG9tLWl0ZXJhYmxlcy5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL2RvbS1pdGVyYWJsZXMuanM/ZmRiYyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBpdGVyYWJsZSBET00gY29sbGVjdGlvbnNcbi8vIGZsYWcgLSBgaXRlcmFibGVgIGludGVyZmFjZSAtICdlbnRyaWVzJywgJ2tleXMnLCAndmFsdWVzJywgJ2ZvckVhY2gnIG1ldGhvZHNcbm1vZHVsZS5leHBvcnRzID0ge1xuICBDU1NSdWxlTGlzdDogMCxcbiAgQ1NTU3R5bGVEZWNsYXJhdGlvbjogMCxcbiAgQ1NTVmFsdWVMaXN0OiAwLFxuICBDbGllbnRSZWN0TGlzdDogMCxcbiAgRE9NUmVjdExpc3Q6IDAsXG4gIERPTVN0cmluZ0xpc3Q6IDAsXG4gIERPTVRva2VuTGlzdDogMSxcbiAgRGF0YVRyYW5zZmVySXRlbUxpc3Q6IDAsXG4gIEZpbGVMaXN0OiAwLFxuICBIVE1MQWxsQ29sbGVjdGlvbjogMCxcbiAgSFRNTENvbGxlY3Rpb246IDAsXG4gIEhUTUxGb3JtRWxlbWVudDogMCxcbiAgSFRNTFNlbGVjdEVsZW1lbnQ6IDAsXG4gIE1lZGlhTGlzdDogMCxcbiAgTWltZVR5cGVBcnJheTogMCxcbiAgTmFtZWROb2RlTWFwOiAwLFxuICBOb2RlTGlzdDogMSxcbiAgUGFpbnRSZXF1ZXN0TGlzdDogMCxcbiAgUGx1Z2luOiAwLFxuICBQbHVnaW5BcnJheTogMCxcbiAgU1ZHTGVuZ3RoTGlzdDogMCxcbiAgU1ZHTnVtYmVyTGlzdDogMCxcbiAgU1ZHUGF0aFNlZ0xpc3Q6IDAsXG4gIFNWR1BvaW50TGlzdDogMCxcbiAgU1ZHU3RyaW5nTGlzdDogMCxcbiAgU1ZHVHJhbnNmb3JtTGlzdDogMCxcbiAgU291cmNlQnVmZmVyTGlzdDogMCxcbiAgU3R5bGVTaGVldExpc3Q6IDAsXG4gIFRleHRUcmFja0N1ZUxpc3Q6IDAsXG4gIFRleHRUcmFja0xpc3Q6IDAsXG4gIFRvdWNoTGlzdDogMFxufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/dom-iterables.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/enum-bug-keys.js": +/*!*********************************************************!*\ + !*** ./node_modules/core-js/internals/enum-bug-keys.js ***! + \*********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("// IE8- don't enum bug keys\nmodule.exports = [\n 'constructor',\n 'hasOwnProperty',\n 'isPrototypeOf',\n 'propertyIsEnumerable',\n 'toLocaleString',\n 'toString',\n 'valueOf'\n];\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvZW51bS1idWcta2V5cy5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL2VudW0tYnVnLWtleXMuanM/NzgzOSJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBJRTgtIGRvbid0IGVudW0gYnVnIGtleXNcbm1vZHVsZS5leHBvcnRzID0gW1xuICAnY29uc3RydWN0b3InLFxuICAnaGFzT3duUHJvcGVydHknLFxuICAnaXNQcm90b3R5cGVPZicsXG4gICdwcm9wZXJ0eUlzRW51bWVyYWJsZScsXG4gICd0b0xvY2FsZVN0cmluZycsXG4gICd0b1N0cmluZycsXG4gICd2YWx1ZU9mJ1xuXTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/enum-bug-keys.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/export.js": +/*!**************************************************!*\ + !*** ./node_modules/core-js/internals/export.js ***! + \**************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var global = __webpack_require__(/*! ../internals/global */ \"./node_modules/core-js/internals/global.js\");\nvar getOwnPropertyDescriptor = __webpack_require__(/*! ../internals/object-get-own-property-descriptor */ \"./node_modules/core-js/internals/object-get-own-property-descriptor.js\").f;\nvar hide = __webpack_require__(/*! ../internals/hide */ \"./node_modules/core-js/internals/hide.js\");\nvar redefine = __webpack_require__(/*! ../internals/redefine */ \"./node_modules/core-js/internals/redefine.js\");\nvar setGlobal = __webpack_require__(/*! ../internals/set-global */ \"./node_modules/core-js/internals/set-global.js\");\nvar copyConstructorProperties = __webpack_require__(/*! ../internals/copy-constructor-properties */ \"./node_modules/core-js/internals/copy-constructor-properties.js\");\nvar isForced = __webpack_require__(/*! ../internals/is-forced */ \"./node_modules/core-js/internals/is-forced.js\");\n\n/*\n options.target - name of the target object\n options.global - target is the global object\n options.stat - export as static methods of target\n options.proto - export as prototype methods of target\n options.real - real prototype method for the `pure` version\n options.forced - export even if the native feature is available\n options.bind - bind methods to the target, required for the `pure` version\n options.wrap - wrap constructors to preventing global pollution, required for the `pure` version\n options.unsafe - use the simple assignment of property instead of delete + defineProperty\n options.sham - add a flag to not completely full polyfills\n options.enumerable - export as enumerable property\n options.noTargetGet - prevent calling a getter on target\n*/\nmodule.exports = function (options, source) {\n var TARGET = options.target;\n var GLOBAL = options.global;\n var STATIC = options.stat;\n var FORCED, target, key, targetProperty, sourceProperty, descriptor;\n if (GLOBAL) {\n target = global;\n } else if (STATIC) {\n target = global[TARGET] || setGlobal(TARGET, {});\n } else {\n target = (global[TARGET] || {}).prototype;\n }\n if (target) for (key in source) {\n sourceProperty = source[key];\n if (options.noTargetGet) {\n descriptor = getOwnPropertyDescriptor(target, key);\n targetProperty = descriptor && descriptor.value;\n } else targetProperty = target[key];\n FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);\n // contained in target\n if (!FORCED && targetProperty !== undefined) {\n if (typeof sourceProperty === typeof targetProperty) continue;\n copyConstructorProperties(sourceProperty, targetProperty);\n }\n // add a flag to not completely full polyfills\n if (options.sham || (targetProperty && targetProperty.sham)) {\n hide(sourceProperty, 'sham', true);\n }\n // extend global\n redefine(target, key, sourceProperty, options);\n }\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvZXhwb3J0LmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvZXhwb3J0LmpzPzIzZTciXSwic291cmNlc0NvbnRlbnQiOlsidmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9nbG9iYWwnKTtcbnZhciBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvb2JqZWN0LWdldC1vd24tcHJvcGVydHktZGVzY3JpcHRvcicpLmY7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9oaWRlJyk7XG52YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvcmVkZWZpbmUnKTtcbnZhciBzZXRHbG9iYWwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvc2V0LWdsb2JhbCcpO1xudmFyIGNvcHlDb25zdHJ1Y3RvclByb3BlcnRpZXMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvY29weS1jb25zdHJ1Y3Rvci1wcm9wZXJ0aWVzJyk7XG52YXIgaXNGb3JjZWQgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaXMtZm9yY2VkJyk7XG5cbi8qXG4gIG9wdGlvbnMudGFyZ2V0ICAgICAgLSBuYW1lIG9mIHRoZSB0YXJnZXQgb2JqZWN0XG4gIG9wdGlvbnMuZ2xvYmFsICAgICAgLSB0YXJnZXQgaXMgdGhlIGdsb2JhbCBvYmplY3RcbiAgb3B0aW9ucy5zdGF0ICAgICAgICAtIGV4cG9ydCBhcyBzdGF0aWMgbWV0aG9kcyBvZiB0YXJnZXRcbiAgb3B0aW9ucy5wcm90byAgICAgICAtIGV4cG9ydCBhcyBwcm90b3R5cGUgbWV0aG9kcyBvZiB0YXJnZXRcbiAgb3B0aW9ucy5yZWFsICAgICAgICAtIHJlYWwgcHJvdG90eXBlIG1ldGhvZCBmb3IgdGhlIGBwdXJlYCB2ZXJzaW9uXG4gIG9wdGlvbnMuZm9yY2VkICAgICAgLSBleHBvcnQgZXZlbiBpZiB0aGUgbmF0aXZlIGZlYXR1cmUgaXMgYXZhaWxhYmxlXG4gIG9wdGlvbnMuYmluZCAgICAgICAgLSBiaW5kIG1ldGhvZHMgdG8gdGhlIHRhcmdldCwgcmVxdWlyZWQgZm9yIHRoZSBgcHVyZWAgdmVyc2lvblxuICBvcHRpb25zLndyYXAgICAgICAgIC0gd3JhcCBjb25zdHJ1Y3RvcnMgdG8gcHJldmVudGluZyBnbG9iYWwgcG9sbHV0aW9uLCByZXF1aXJlZCBmb3IgdGhlIGBwdXJlYCB2ZXJzaW9uXG4gIG9wdGlvbnMudW5zYWZlICAgICAgLSB1c2UgdGhlIHNpbXBsZSBhc3NpZ25tZW50IG9mIHByb3BlcnR5IGluc3RlYWQgb2YgZGVsZXRlICsgZGVmaW5lUHJvcGVydHlcbiAgb3B0aW9ucy5zaGFtICAgICAgICAtIGFkZCBhIGZsYWcgdG8gbm90IGNvbXBsZXRlbHkgZnVsbCBwb2x5ZmlsbHNcbiAgb3B0aW9ucy5lbnVtZXJhYmxlICAtIGV4cG9ydCBhcyBlbnVtZXJhYmxlIHByb3BlcnR5XG4gIG9wdGlvbnMubm9UYXJnZXRHZXQgLSBwcmV2ZW50IGNhbGxpbmcgYSBnZXR0ZXIgb24gdGFyZ2V0XG4qL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob3B0aW9ucywgc291cmNlKSB7XG4gIHZhciBUQVJHRVQgPSBvcHRpb25zLnRhcmdldDtcbiAgdmFyIEdMT0JBTCA9IG9wdGlvbnMuZ2xvYmFsO1xuICB2YXIgU1RBVElDID0gb3B0aW9ucy5zdGF0O1xuICB2YXIgRk9SQ0VELCB0YXJnZXQsIGtleSwgdGFyZ2V0UHJvcGVydHksIHNvdXJjZVByb3BlcnR5LCBkZXNjcmlwdG9yO1xuICBpZiAoR0xPQkFMKSB7XG4gICAgdGFyZ2V0ID0gZ2xvYmFsO1xuICB9IGVsc2UgaWYgKFNUQVRJQykge1xuICAgIHRhcmdldCA9IGdsb2JhbFtUQVJHRVRdIHx8IHNldEdsb2JhbChUQVJHRVQsIHt9KTtcbiAgfSBlbHNlIHtcbiAgICB0YXJnZXQgPSAoZ2xvYmFsW1RBUkdFVF0gfHwge30pLnByb3RvdHlwZTtcbiAgfVxuICBpZiAodGFyZ2V0KSBmb3IgKGtleSBpbiBzb3VyY2UpIHtcbiAgICBzb3VyY2VQcm9wZXJ0eSA9IHNvdXJjZVtrZXldO1xuICAgIGlmIChvcHRpb25zLm5vVGFyZ2V0R2V0KSB7XG4gICAgICBkZXNjcmlwdG9yID0gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KTtcbiAgICAgIHRhcmdldFByb3BlcnR5ID0gZGVzY3JpcHRvciAmJiBkZXNjcmlwdG9yLnZhbHVlO1xuICAgIH0gZWxzZSB0YXJnZXRQcm9wZXJ0eSA9IHRhcmdldFtrZXldO1xuICAgIEZPUkNFRCA9IGlzRm9yY2VkKEdMT0JBTCA/IGtleSA6IFRBUkdFVCArIChTVEFUSUMgPyAnLicgOiAnIycpICsga2V5LCBvcHRpb25zLmZvcmNlZCk7XG4gICAgLy8gY29udGFpbmVkIGluIHRhcmdldFxuICAgIGlmICghRk9SQ0VEICYmIHRhcmdldFByb3BlcnR5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmICh0eXBlb2Ygc291cmNlUHJvcGVydHkgPT09IHR5cGVvZiB0YXJnZXRQcm9wZXJ0eSkgY29udGludWU7XG4gICAgICBjb3B5Q29uc3RydWN0b3JQcm9wZXJ0aWVzKHNvdXJjZVByb3BlcnR5LCB0YXJnZXRQcm9wZXJ0eSk7XG4gICAgfVxuICAgIC8vIGFkZCBhIGZsYWcgdG8gbm90IGNvbXBsZXRlbHkgZnVsbCBwb2x5ZmlsbHNcbiAgICBpZiAob3B0aW9ucy5zaGFtIHx8ICh0YXJnZXRQcm9wZXJ0eSAmJiB0YXJnZXRQcm9wZXJ0eS5zaGFtKSkge1xuICAgICAgaGlkZShzb3VyY2VQcm9wZXJ0eSwgJ3NoYW0nLCB0cnVlKTtcbiAgICB9XG4gICAgLy8gZXh0ZW5kIGdsb2JhbFxuICAgIHJlZGVmaW5lKHRhcmdldCwga2V5LCBzb3VyY2VQcm9wZXJ0eSwgb3B0aW9ucyk7XG4gIH1cbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/export.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/fails.js": +/*!*************************************************!*\ + !*** ./node_modules/core-js/internals/fails.js ***! + \*************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("module.exports = function (exec) {\n try {\n return !!exec();\n } catch (error) {\n return true;\n }\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvZmFpbHMuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9mYWlscy5qcz9kMDM5Il0sInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGV4ZWMpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gISFleGVjKCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/fails.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/fix-regexp-well-known-symbol-logic.js": +/*!******************************************************************************!*\ + !*** ./node_modules/core-js/internals/fix-regexp-well-known-symbol-logic.js ***! + \******************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar hide = __webpack_require__(/*! ../internals/hide */ \"./node_modules/core-js/internals/hide.js\");\nvar redefine = __webpack_require__(/*! ../internals/redefine */ \"./node_modules/core-js/internals/redefine.js\");\nvar fails = __webpack_require__(/*! ../internals/fails */ \"./node_modules/core-js/internals/fails.js\");\nvar wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ \"./node_modules/core-js/internals/well-known-symbol.js\");\nvar regexpExec = __webpack_require__(/*! ../internals/regexp-exec */ \"./node_modules/core-js/internals/regexp-exec.js\");\n\nvar SPECIES = wellKnownSymbol('species');\n\nvar REPLACE_SUPPORTS_NAMED_GROUPS = !fails(function () {\n // #replace needs built-in support for named groups.\n // #match works fine because it just return the exec results, even if it has\n // a \"grops\" property.\n var re = /./;\n re.exec = function () {\n var result = [];\n result.groups = { a: '7' };\n return result;\n };\n return ''.replace(re, '$') !== '7';\n});\n\n// Chrome 51 has a buggy \"split\" implementation when RegExp#exec !== nativeExec\n// Weex JS has frozen built-in prototypes, so use try / catch wrapper\nvar SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = !fails(function () {\n var re = /(?:)/;\n var originalExec = re.exec;\n re.exec = function () { return originalExec.apply(this, arguments); };\n var result = 'ab'.split(re);\n return result.length !== 2 || result[0] !== 'a' || result[1] !== 'b';\n});\n\nmodule.exports = function (KEY, length, exec, sham) {\n var SYMBOL = wellKnownSymbol(KEY);\n\n var DELEGATES_TO_SYMBOL = !fails(function () {\n // String methods call symbol-named RegEp methods\n var O = {};\n O[SYMBOL] = function () { return 7; };\n return ''[KEY](O) != 7;\n });\n\n var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL && !fails(function () {\n // Symbol-named RegExp methods call .exec\n var execCalled = false;\n var re = /a/;\n re.exec = function () { execCalled = true; return null; };\n\n if (KEY === 'split') {\n // RegExp[@@split] doesn't call the regex's exec method, but first creates\n // a new one. We need to return the patched regex when creating the new one.\n re.constructor = {};\n re.constructor[SPECIES] = function () { return re; };\n }\n\n re[SYMBOL]('');\n return !execCalled;\n });\n\n if (\n !DELEGATES_TO_SYMBOL ||\n !DELEGATES_TO_EXEC ||\n (KEY === 'replace' && !REPLACE_SUPPORTS_NAMED_GROUPS) ||\n (KEY === 'split' && !SPLIT_WORKS_WITH_OVERWRITTEN_EXEC)\n ) {\n var nativeRegExpMethod = /./[SYMBOL];\n var methods = exec(SYMBOL, ''[KEY], function (nativeMethod, regexp, str, arg2, forceStringMethod) {\n if (regexp.exec === regexpExec) {\n if (DELEGATES_TO_SYMBOL && !forceStringMethod) {\n // The native String method already delegates to @@method (this\n // polyfilled function), leasing to infinite recursion.\n // We avoid it by directly calling the native @@method method.\n return { done: true, value: nativeRegExpMethod.call(regexp, str, arg2) };\n }\n return { done: true, value: nativeMethod.call(str, regexp, arg2) };\n }\n return { done: false };\n });\n var stringMethod = methods[0];\n var regexMethod = methods[1];\n\n redefine(String.prototype, KEY, stringMethod);\n redefine(RegExp.prototype, SYMBOL, length == 2\n // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)\n // 21.2.5.11 RegExp.prototype[@@split](string, limit)\n ? function (string, arg) { return regexMethod.call(string, this, arg); }\n // 21.2.5.6 RegExp.prototype[@@match](string)\n // 21.2.5.9 RegExp.prototype[@@search](string)\n : function (string) { return regexMethod.call(string, this); }\n );\n if (sham) hide(RegExp.prototype[SYMBOL], 'sham', true);\n }\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvZml4LXJlZ2V4cC13ZWxsLWtub3duLXN5bWJvbC1sb2dpYy5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL2ZpeC1yZWdleHAtd2VsbC1rbm93bi1zeW1ib2wtbG9naWMuanM/ZDc4NCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9oaWRlJyk7XG52YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvcmVkZWZpbmUnKTtcbnZhciBmYWlscyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9mYWlscycpO1xudmFyIHdlbGxLbm93blN5bWJvbCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy93ZWxsLWtub3duLXN5bWJvbCcpO1xudmFyIHJlZ2V4cEV4ZWMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvcmVnZXhwLWV4ZWMnKTtcblxudmFyIFNQRUNJRVMgPSB3ZWxsS25vd25TeW1ib2woJ3NwZWNpZXMnKTtcblxudmFyIFJFUExBQ0VfU1VQUE9SVFNfTkFNRURfR1JPVVBTID0gIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgLy8gI3JlcGxhY2UgbmVlZHMgYnVpbHQtaW4gc3VwcG9ydCBmb3IgbmFtZWQgZ3JvdXBzLlxuICAvLyAjbWF0Y2ggd29ya3MgZmluZSBiZWNhdXNlIGl0IGp1c3QgcmV0dXJuIHRoZSBleGVjIHJlc3VsdHMsIGV2ZW4gaWYgaXQgaGFzXG4gIC8vIGEgXCJncm9wc1wiIHByb3BlcnR5LlxuICB2YXIgcmUgPSAvLi87XG4gIHJlLmV4ZWMgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgIHJlc3VsdC5ncm91cHMgPSB7IGE6ICc3JyB9O1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG4gIHJldHVybiAnJy5yZXBsYWNlKHJlLCAnJDxhPicpICE9PSAnNyc7XG59KTtcblxuLy8gQ2hyb21lIDUxIGhhcyBhIGJ1Z2d5IFwic3BsaXRcIiBpbXBsZW1lbnRhdGlvbiB3aGVuIFJlZ0V4cCNleGVjICE9PSBuYXRpdmVFeGVjXG4vLyBXZWV4IEpTIGhhcyBmcm96ZW4gYnVpbHQtaW4gcHJvdG90eXBlcywgc28gdXNlIHRyeSAvIGNhdGNoIHdyYXBwZXJcbnZhciBTUExJVF9XT1JLU19XSVRIX09WRVJXUklUVEVOX0VYRUMgPSAhZmFpbHMoZnVuY3Rpb24gKCkge1xuICB2YXIgcmUgPSAvKD86KS87XG4gIHZhciBvcmlnaW5hbEV4ZWMgPSByZS5leGVjO1xuICByZS5leGVjID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gb3JpZ2luYWxFeGVjLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH07XG4gIHZhciByZXN1bHQgPSAnYWInLnNwbGl0KHJlKTtcbiAgcmV0dXJuIHJlc3VsdC5sZW5ndGggIT09IDIgfHwgcmVzdWx0WzBdICE9PSAnYScgfHwgcmVzdWx0WzFdICE9PSAnYic7XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoS0VZLCBsZW5ndGgsIGV4ZWMsIHNoYW0pIHtcbiAgdmFyIFNZTUJPTCA9IHdlbGxLbm93blN5bWJvbChLRVkpO1xuXG4gIHZhciBERUxFR0FURVNfVE9fU1lNQk9MID0gIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgICAvLyBTdHJpbmcgbWV0aG9kcyBjYWxsIHN5bWJvbC1uYW1lZCBSZWdFcCBtZXRob2RzXG4gICAgdmFyIE8gPSB7fTtcbiAgICBPW1NZTUJPTF0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiA3OyB9O1xuICAgIHJldHVybiAnJ1tLRVldKE8pICE9IDc7XG4gIH0pO1xuXG4gIHZhciBERUxFR0FURVNfVE9fRVhFQyA9IERFTEVHQVRFU19UT19TWU1CT0wgJiYgIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgICAvLyBTeW1ib2wtbmFtZWQgUmVnRXhwIG1ldGhvZHMgY2FsbCAuZXhlY1xuICAgIHZhciBleGVjQ2FsbGVkID0gZmFsc2U7XG4gICAgdmFyIHJlID0gL2EvO1xuICAgIHJlLmV4ZWMgPSBmdW5jdGlvbiAoKSB7IGV4ZWNDYWxsZWQgPSB0cnVlOyByZXR1cm4gbnVsbDsgfTtcblxuICAgIGlmIChLRVkgPT09ICdzcGxpdCcpIHtcbiAgICAgIC8vIFJlZ0V4cFtAQHNwbGl0XSBkb2Vzbid0IGNhbGwgdGhlIHJlZ2V4J3MgZXhlYyBtZXRob2QsIGJ1dCBmaXJzdCBjcmVhdGVzXG4gICAgICAvLyBhIG5ldyBvbmUuIFdlIG5lZWQgdG8gcmV0dXJuIHRoZSBwYXRjaGVkIHJlZ2V4IHdoZW4gY3JlYXRpbmcgdGhlIG5ldyBvbmUuXG4gICAgICByZS5jb25zdHJ1Y3RvciA9IHt9O1xuICAgICAgcmUuY29uc3RydWN0b3JbU1BFQ0lFU10gPSBmdW5jdGlvbiAoKSB7IHJldHVybiByZTsgfTtcbiAgICB9XG5cbiAgICByZVtTWU1CT0xdKCcnKTtcbiAgICByZXR1cm4gIWV4ZWNDYWxsZWQ7XG4gIH0pO1xuXG4gIGlmIChcbiAgICAhREVMRUdBVEVTX1RPX1NZTUJPTCB8fFxuICAgICFERUxFR0FURVNfVE9fRVhFQyB8fFxuICAgIChLRVkgPT09ICdyZXBsYWNlJyAmJiAhUkVQTEFDRV9TVVBQT1JUU19OQU1FRF9HUk9VUFMpIHx8XG4gICAgKEtFWSA9PT0gJ3NwbGl0JyAmJiAhU1BMSVRfV09SS1NfV0lUSF9PVkVSV1JJVFRFTl9FWEVDKVxuICApIHtcbiAgICB2YXIgbmF0aXZlUmVnRXhwTWV0aG9kID0gLy4vW1NZTUJPTF07XG4gICAgdmFyIG1ldGhvZHMgPSBleGVjKFNZTUJPTCwgJydbS0VZXSwgZnVuY3Rpb24gKG5hdGl2ZU1ldGhvZCwgcmVnZXhwLCBzdHIsIGFyZzIsIGZvcmNlU3RyaW5nTWV0aG9kKSB7XG4gICAgICBpZiAocmVnZXhwLmV4ZWMgPT09IHJlZ2V4cEV4ZWMpIHtcbiAgICAgICAgaWYgKERFTEVHQVRFU19UT19TWU1CT0wgJiYgIWZvcmNlU3RyaW5nTWV0aG9kKSB7XG4gICAgICAgICAgLy8gVGhlIG5hdGl2ZSBTdHJpbmcgbWV0aG9kIGFscmVhZHkgZGVsZWdhdGVzIHRvIEBAbWV0aG9kICh0aGlzXG4gICAgICAgICAgLy8gcG9seWZpbGxlZCBmdW5jdGlvbiksIGxlYXNpbmcgdG8gaW5maW5pdGUgcmVjdXJzaW9uLlxuICAgICAgICAgIC8vIFdlIGF2b2lkIGl0IGJ5IGRpcmVjdGx5IGNhbGxpbmcgdGhlIG5hdGl2ZSBAQG1ldGhvZCBtZXRob2QuXG4gICAgICAgICAgcmV0dXJuIHsgZG9uZTogdHJ1ZSwgdmFsdWU6IG5hdGl2ZVJlZ0V4cE1ldGhvZC5jYWxsKHJlZ2V4cCwgc3RyLCBhcmcyKSB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IGRvbmU6IHRydWUsIHZhbHVlOiBuYXRpdmVNZXRob2QuY2FsbChzdHIsIHJlZ2V4cCwgYXJnMikgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7IGRvbmU6IGZhbHNlIH07XG4gICAgfSk7XG4gICAgdmFyIHN0cmluZ01ldGhvZCA9IG1ldGhvZHNbMF07XG4gICAgdmFyIHJlZ2V4TWV0aG9kID0gbWV0aG9kc1sxXTtcblxuICAgIHJlZGVmaW5lKFN0cmluZy5wcm90b3R5cGUsIEtFWSwgc3RyaW5nTWV0aG9kKTtcbiAgICByZWRlZmluZShSZWdFeHAucHJvdG90eXBlLCBTWU1CT0wsIGxlbmd0aCA9PSAyXG4gICAgICAvLyAyMS4yLjUuOCBSZWdFeHAucHJvdG90eXBlW0BAcmVwbGFjZV0oc3RyaW5nLCByZXBsYWNlVmFsdWUpXG4gICAgICAvLyAyMS4yLjUuMTEgUmVnRXhwLnByb3RvdHlwZVtAQHNwbGl0XShzdHJpbmcsIGxpbWl0KVxuICAgICAgPyBmdW5jdGlvbiAoc3RyaW5nLCBhcmcpIHsgcmV0dXJuIHJlZ2V4TWV0aG9kLmNhbGwoc3RyaW5nLCB0aGlzLCBhcmcpOyB9XG4gICAgICAvLyAyMS4yLjUuNiBSZWdFeHAucHJvdG90eXBlW0BAbWF0Y2hdKHN0cmluZylcbiAgICAgIC8vIDIxLjIuNS45IFJlZ0V4cC5wcm90b3R5cGVbQEBzZWFyY2hdKHN0cmluZylcbiAgICAgIDogZnVuY3Rpb24gKHN0cmluZykgeyByZXR1cm4gcmVnZXhNZXRob2QuY2FsbChzdHJpbmcsIHRoaXMpOyB9XG4gICAgKTtcbiAgICBpZiAoc2hhbSkgaGlkZShSZWdFeHAucHJvdG90eXBlW1NZTUJPTF0sICdzaGFtJywgdHJ1ZSk7XG4gIH1cbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/fix-regexp-well-known-symbol-logic.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/forced-string-html-method.js": +/*!*********************************************************************!*\ + !*** ./node_modules/core-js/internals/forced-string-html-method.js ***! + \*********************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var fails = __webpack_require__(/*! ../internals/fails */ \"./node_modules/core-js/internals/fails.js\");\n\n// check the existence of a method, lowercase\n// of a tag and escaping quotes in arguments\nmodule.exports = function (METHOD_NAME) {\n return fails(function () {\n var test = ''[METHOD_NAME]('\"');\n return test !== test.toLowerCase() || test.split('\"').length > 3;\n });\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvZm9yY2VkLXN0cmluZy1odG1sLW1ldGhvZC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL2ZvcmNlZC1zdHJpbmctaHRtbC1tZXRob2QuanM/ZWFlOSJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgZmFpbHMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZmFpbHMnKTtcblxuLy8gY2hlY2sgdGhlIGV4aXN0ZW5jZSBvZiBhIG1ldGhvZCwgbG93ZXJjYXNlXG4vLyBvZiBhIHRhZyBhbmQgZXNjYXBpbmcgcXVvdGVzIGluIGFyZ3VtZW50c1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoTUVUSE9EX05BTUUpIHtcbiAgcmV0dXJuIGZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdGVzdCA9ICcnW01FVEhPRF9OQU1FXSgnXCInKTtcbiAgICByZXR1cm4gdGVzdCAhPT0gdGVzdC50b0xvd2VyQ2FzZSgpIHx8IHRlc3Quc3BsaXQoJ1wiJykubGVuZ3RoID4gMztcbiAgfSk7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/forced-string-html-method.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/forced-string-trim-method.js": +/*!*********************************************************************!*\ + !*** ./node_modules/core-js/internals/forced-string-trim-method.js ***! + \*********************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var fails = __webpack_require__(/*! ../internals/fails */ \"./node_modules/core-js/internals/fails.js\");\nvar whitespaces = __webpack_require__(/*! ../internals/whitespaces */ \"./node_modules/core-js/internals/whitespaces.js\");\n\nvar non = '\\u200B\\u0085\\u180E';\n\n// check that a method works with the correct list\n// of whitespaces and has a correct name\nmodule.exports = function (METHOD_NAME) {\n return fails(function () {\n return !!whitespaces[METHOD_NAME]() || non[METHOD_NAME]() != non || whitespaces[METHOD_NAME].name !== METHOD_NAME;\n });\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvZm9yY2VkLXN0cmluZy10cmltLW1ldGhvZC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL2ZvcmNlZC1zdHJpbmctdHJpbS1tZXRob2QuanM/ZTA3MCJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgZmFpbHMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZmFpbHMnKTtcbnZhciB3aGl0ZXNwYWNlcyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy93aGl0ZXNwYWNlcycpO1xuXG52YXIgbm9uID0gJ1xcdTIwMEJcXHUwMDg1XFx1MTgwRSc7XG5cbi8vIGNoZWNrIHRoYXQgYSBtZXRob2Qgd29ya3Mgd2l0aCB0aGUgY29ycmVjdCBsaXN0XG4vLyBvZiB3aGl0ZXNwYWNlcyBhbmQgaGFzIGEgY29ycmVjdCBuYW1lXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChNRVRIT0RfTkFNRSkge1xuICByZXR1cm4gZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAhIXdoaXRlc3BhY2VzW01FVEhPRF9OQU1FXSgpIHx8IG5vbltNRVRIT0RfTkFNRV0oKSAhPSBub24gfHwgd2hpdGVzcGFjZXNbTUVUSE9EX05BTUVdLm5hbWUgIT09IE1FVEhPRF9OQU1FO1xuICB9KTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/forced-string-trim-method.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/function-to-string.js": +/*!**************************************************************!*\ + !*** ./node_modules/core-js/internals/function-to-string.js ***! + \**************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var shared = __webpack_require__(/*! ../internals/shared */ \"./node_modules/core-js/internals/shared.js\");\n\nmodule.exports = shared('native-function-to-string', Function.toString);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvZnVuY3Rpb24tdG8tc3RyaW5nLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvZnVuY3Rpb24tdG8tc3RyaW5nLmpzPzllODEiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIHNoYXJlZCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9zaGFyZWQnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBzaGFyZWQoJ25hdGl2ZS1mdW5jdGlvbi10by1zdHJpbmcnLCBGdW5jdGlvbi50b1N0cmluZyk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/function-to-string.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/get-built-in.js": +/*!********************************************************!*\ + !*** ./node_modules/core-js/internals/get-built-in.js ***! + \********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var path = __webpack_require__(/*! ../internals/path */ \"./node_modules/core-js/internals/path.js\");\nvar global = __webpack_require__(/*! ../internals/global */ \"./node_modules/core-js/internals/global.js\");\n\nvar aFunction = function (variable) {\n return typeof variable == 'function' ? variable : undefined;\n};\n\nmodule.exports = function (namespace, method) {\n return arguments.length < 2 ? aFunction(path[namespace]) || aFunction(global[namespace])\n : path[namespace] && path[namespace][method] || global[namespace] && global[namespace][method];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvZ2V0LWJ1aWx0LWluLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvZ2V0LWJ1aWx0LWluLmpzP2QwNjYiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIHBhdGggPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvcGF0aCcpO1xudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9nbG9iYWwnKTtcblxudmFyIGFGdW5jdGlvbiA9IGZ1bmN0aW9uICh2YXJpYWJsZSkge1xuICByZXR1cm4gdHlwZW9mIHZhcmlhYmxlID09ICdmdW5jdGlvbicgPyB2YXJpYWJsZSA6IHVuZGVmaW5lZDtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG5hbWVzcGFjZSwgbWV0aG9kKSB7XG4gIHJldHVybiBhcmd1bWVudHMubGVuZ3RoIDwgMiA/IGFGdW5jdGlvbihwYXRoW25hbWVzcGFjZV0pIHx8IGFGdW5jdGlvbihnbG9iYWxbbmFtZXNwYWNlXSlcbiAgICA6IHBhdGhbbmFtZXNwYWNlXSAmJiBwYXRoW25hbWVzcGFjZV1bbWV0aG9kXSB8fCBnbG9iYWxbbmFtZXNwYWNlXSAmJiBnbG9iYWxbbmFtZXNwYWNlXVttZXRob2RdO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/get-built-in.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/get-iterator-method.js": +/*!***************************************************************!*\ + !*** ./node_modules/core-js/internals/get-iterator-method.js ***! + \***************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var classof = __webpack_require__(/*! ../internals/classof */ \"./node_modules/core-js/internals/classof.js\");\nvar Iterators = __webpack_require__(/*! ../internals/iterators */ \"./node_modules/core-js/internals/iterators.js\");\nvar wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ \"./node_modules/core-js/internals/well-known-symbol.js\");\n\nvar ITERATOR = wellKnownSymbol('iterator');\n\nmodule.exports = function (it) {\n if (it != undefined) return it[ITERATOR]\n || it['@@iterator']\n || Iterators[classof(it)];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvZ2V0LWl0ZXJhdG9yLW1ldGhvZC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL2dldC1pdGVyYXRvci1tZXRob2QuanM/MzVhMSJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgY2xhc3NvZiA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9jbGFzc29mJyk7XG52YXIgSXRlcmF0b3JzID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2l0ZXJhdG9ycycpO1xudmFyIHdlbGxLbm93blN5bWJvbCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy93ZWxsLWtub3duLXN5bWJvbCcpO1xuXG52YXIgSVRFUkFUT1IgPSB3ZWxsS25vd25TeW1ib2woJ2l0ZXJhdG9yJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIGlmIChpdCAhPSB1bmRlZmluZWQpIHJldHVybiBpdFtJVEVSQVRPUl1cbiAgICB8fCBpdFsnQEBpdGVyYXRvciddXG4gICAgfHwgSXRlcmF0b3JzW2NsYXNzb2YoaXQpXTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/get-iterator-method.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/global.js": +/*!**************************************************!*\ + !*** ./node_modules/core-js/internals/global.js ***! + \**************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("/* WEBPACK VAR INJECTION */(function(global) {var O = 'object';\nvar check = function (it) {\n return it && it.Math == Math && it;\n};\n\n// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nmodule.exports =\n // eslint-disable-next-line no-undef\n check(typeof globalThis == O && globalThis) ||\n check(typeof window == O && window) ||\n check(typeof self == O && self) ||\n check(typeof global == O && global) ||\n // eslint-disable-next-line no-new-func\n Function('return this')();\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvZ2xvYmFsLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvZ2xvYmFsLmpzP2RhODQiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIE8gPSAnb2JqZWN0JztcbnZhciBjaGVjayA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gaXQgJiYgaXQuTWF0aCA9PSBNYXRoICYmIGl0O1xufTtcblxuLy8gaHR0cHM6Ly9naXRodWIuY29tL3psb2lyb2NrL2NvcmUtanMvaXNzdWVzLzg2I2lzc3VlY29tbWVudC0xMTU3NTkwMjhcbm1vZHVsZS5leHBvcnRzID1cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG4gIGNoZWNrKHR5cGVvZiBnbG9iYWxUaGlzID09IE8gJiYgZ2xvYmFsVGhpcykgfHxcbiAgY2hlY2sodHlwZW9mIHdpbmRvdyA9PSBPICYmIHdpbmRvdykgfHxcbiAgY2hlY2sodHlwZW9mIHNlbGYgPT0gTyAmJiBzZWxmKSB8fFxuICBjaGVjayh0eXBlb2YgZ2xvYmFsID09IE8gJiYgZ2xvYmFsKSB8fFxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbmV3LWZ1bmNcbiAgRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/global.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/has.js": +/*!***********************************************!*\ + !*** ./node_modules/core-js/internals/has.js ***! + \***********************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("var hasOwnProperty = {}.hasOwnProperty;\n\nmodule.exports = function (it, key) {\n return hasOwnProperty.call(it, key);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvaGFzLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvaGFzLmpzPzUxMzUiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIGhhc093blByb3BlcnR5ID0ge30uaGFzT3duUHJvcGVydHk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0LCBrZXkpIHtcbiAgcmV0dXJuIGhhc093blByb3BlcnR5LmNhbGwoaXQsIGtleSk7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/has.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/hidden-keys.js": +/*!*******************************************************!*\ + !*** ./node_modules/core-js/internals/hidden-keys.js ***! + \*******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("module.exports = {};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvaGlkZGVuLWtleXMuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9oaWRkZW4ta2V5cy5qcz9kMDEyIl0sInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0ge307XG4iXSwibWFwcGluZ3MiOiJBQUFBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/hidden-keys.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/hide.js": +/*!************************************************!*\ + !*** ./node_modules/core-js/internals/hide.js ***! + \************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ \"./node_modules/core-js/internals/descriptors.js\");\nvar definePropertyModule = __webpack_require__(/*! ../internals/object-define-property */ \"./node_modules/core-js/internals/object-define-property.js\");\nvar createPropertyDescriptor = __webpack_require__(/*! ../internals/create-property-descriptor */ \"./node_modules/core-js/internals/create-property-descriptor.js\");\n\nmodule.exports = DESCRIPTORS ? function (object, key, value) {\n return definePropertyModule.f(object, key, createPropertyDescriptor(1, value));\n} : function (object, key, value) {\n object[key] = value;\n return object;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvaGlkZS5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL2hpZGUuanM/NWY2NSJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgREVTQ1JJUFRPUlMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZGVzY3JpcHRvcnMnKTtcbnZhciBkZWZpbmVQcm9wZXJ0eU1vZHVsZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9vYmplY3QtZGVmaW5lLXByb3BlcnR5Jyk7XG52YXIgY3JlYXRlUHJvcGVydHlEZXNjcmlwdG9yID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2NyZWF0ZS1wcm9wZXJ0eS1kZXNjcmlwdG9yJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gREVTQ1JJUFRPUlMgPyBmdW5jdGlvbiAob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gIHJldHVybiBkZWZpbmVQcm9wZXJ0eU1vZHVsZS5mKG9iamVjdCwga2V5LCBjcmVhdGVQcm9wZXJ0eURlc2NyaXB0b3IoMSwgdmFsdWUpKTtcbn0gOiBmdW5jdGlvbiAob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gIG9iamVjdFtrZXldID0gdmFsdWU7XG4gIHJldHVybiBvYmplY3Q7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/hide.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/host-report-errors.js": +/*!**************************************************************!*\ + !*** ./node_modules/core-js/internals/host-report-errors.js ***! + \**************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var global = __webpack_require__(/*! ../internals/global */ \"./node_modules/core-js/internals/global.js\");\n\nmodule.exports = function (a, b) {\n var console = global.console;\n if (console && console.error) {\n arguments.length === 1 ? console.error(a) : console.error(a, b);\n }\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvaG9zdC1yZXBvcnQtZXJyb3JzLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvaG9zdC1yZXBvcnQtZXJyb3JzLmpzPzQ0ZGUiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9nbG9iYWwnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoYSwgYikge1xuICB2YXIgY29uc29sZSA9IGdsb2JhbC5jb25zb2xlO1xuICBpZiAoY29uc29sZSAmJiBjb25zb2xlLmVycm9yKSB7XG4gICAgYXJndW1lbnRzLmxlbmd0aCA9PT0gMSA/IGNvbnNvbGUuZXJyb3IoYSkgOiBjb25zb2xlLmVycm9yKGEsIGIpO1xuICB9XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/host-report-errors.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/html.js": +/*!************************************************!*\ + !*** ./node_modules/core-js/internals/html.js ***! + \************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var global = __webpack_require__(/*! ../internals/global */ \"./node_modules/core-js/internals/global.js\");\n\nvar document = global.document;\n\nmodule.exports = document && document.documentElement;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvaHRtbC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL2h0bWwuanM/MWJlNCJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2dsb2JhbCcpO1xuXG52YXIgZG9jdW1lbnQgPSBnbG9iYWwuZG9jdW1lbnQ7XG5cbm1vZHVsZS5leHBvcnRzID0gZG9jdW1lbnQgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/html.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/ie8-dom-define.js": +/*!**********************************************************!*\ + !*** ./node_modules/core-js/internals/ie8-dom-define.js ***! + \**********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ \"./node_modules/core-js/internals/descriptors.js\");\nvar fails = __webpack_require__(/*! ../internals/fails */ \"./node_modules/core-js/internals/fails.js\");\nvar createElement = __webpack_require__(/*! ../internals/document-create-element */ \"./node_modules/core-js/internals/document-create-element.js\");\n\n// Thank's IE8 for his funny defineProperty\nmodule.exports = !DESCRIPTORS && !fails(function () {\n return Object.defineProperty(createElement('div'), 'a', {\n get: function () { return 7; }\n }).a != 7;\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvaWU4LWRvbS1kZWZpbmUuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9pZTgtZG9tLWRlZmluZS5qcz8wY2ZiIl0sInNvdXJjZXNDb250ZW50IjpbInZhciBERVNDUklQVE9SUyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9kZXNjcmlwdG9ycycpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2ZhaWxzJyk7XG52YXIgY3JlYXRlRWxlbWVudCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9kb2N1bWVudC1jcmVhdGUtZWxlbWVudCcpO1xuXG4vLyBUaGFuaydzIElFOCBmb3IgaGlzIGZ1bm55IGRlZmluZVByb3BlcnR5XG5tb2R1bGUuZXhwb3J0cyA9ICFERVNDUklQVE9SUyAmJiAhZmFpbHMoZnVuY3Rpb24gKCkge1xuICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KGNyZWF0ZUVsZW1lbnQoJ2RpdicpLCAnYScsIHtcbiAgICBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDc7IH1cbiAgfSkuYSAhPSA3O1xufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/ie8-dom-define.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/indexed-object.js": +/*!**********************************************************!*\ + !*** ./node_modules/core-js/internals/indexed-object.js ***! + \**********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("// fallback for non-array-like ES3 and non-enumerable old V8 strings\nvar fails = __webpack_require__(/*! ../internals/fails */ \"./node_modules/core-js/internals/fails.js\");\nvar classof = __webpack_require__(/*! ../internals/classof-raw */ \"./node_modules/core-js/internals/classof-raw.js\");\n\nvar split = ''.split;\n\nmodule.exports = fails(function () {\n // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346\n // eslint-disable-next-line no-prototype-builtins\n return !Object('z').propertyIsEnumerable(0);\n}) ? function (it) {\n return classof(it) == 'String' ? split.call(it, '') : Object(it);\n} : Object;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvaW5kZXhlZC1vYmplY3QuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9pbmRleGVkLW9iamVjdC5qcz80NGFkIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIGZhbGxiYWNrIGZvciBub24tYXJyYXktbGlrZSBFUzMgYW5kIG5vbi1lbnVtZXJhYmxlIG9sZCBWOCBzdHJpbmdzXG52YXIgZmFpbHMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZmFpbHMnKTtcbnZhciBjbGFzc29mID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2NsYXNzb2YtcmF3Jyk7XG5cbnZhciBzcGxpdCA9ICcnLnNwbGl0O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgLy8gdGhyb3dzIGFuIGVycm9yIGluIHJoaW5vLCBzZWUgaHR0cHM6Ly9naXRodWIuY29tL21vemlsbGEvcmhpbm8vaXNzdWVzLzM0NlxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcHJvdG90eXBlLWJ1aWx0aW5zXG4gIHJldHVybiAhT2JqZWN0KCd6JykucHJvcGVydHlJc0VudW1lcmFibGUoMCk7XG59KSA/IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gY2xhc3NvZihpdCkgPT0gJ1N0cmluZycgPyBzcGxpdC5jYWxsKGl0LCAnJykgOiBPYmplY3QoaXQpO1xufSA6IE9iamVjdDtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/indexed-object.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/internal-state.js": +/*!**********************************************************!*\ + !*** ./node_modules/core-js/internals/internal-state.js ***! + \**********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var NATIVE_WEAK_MAP = __webpack_require__(/*! ../internals/native-weak-map */ \"./node_modules/core-js/internals/native-weak-map.js\");\nvar global = __webpack_require__(/*! ../internals/global */ \"./node_modules/core-js/internals/global.js\");\nvar isObject = __webpack_require__(/*! ../internals/is-object */ \"./node_modules/core-js/internals/is-object.js\");\nvar hide = __webpack_require__(/*! ../internals/hide */ \"./node_modules/core-js/internals/hide.js\");\nvar objectHas = __webpack_require__(/*! ../internals/has */ \"./node_modules/core-js/internals/has.js\");\nvar sharedKey = __webpack_require__(/*! ../internals/shared-key */ \"./node_modules/core-js/internals/shared-key.js\");\nvar hiddenKeys = __webpack_require__(/*! ../internals/hidden-keys */ \"./node_modules/core-js/internals/hidden-keys.js\");\n\nvar WeakMap = global.WeakMap;\nvar set, get, has;\n\nvar enforce = function (it) {\n return has(it) ? get(it) : set(it, {});\n};\n\nvar getterFor = function (TYPE) {\n return function (it) {\n var state;\n if (!isObject(it) || (state = get(it)).type !== TYPE) {\n throw TypeError('Incompatible receiver, ' + TYPE + ' required');\n } return state;\n };\n};\n\nif (NATIVE_WEAK_MAP) {\n var store = new WeakMap();\n var wmget = store.get;\n var wmhas = store.has;\n var wmset = store.set;\n set = function (it, metadata) {\n wmset.call(store, it, metadata);\n return metadata;\n };\n get = function (it) {\n return wmget.call(store, it) || {};\n };\n has = function (it) {\n return wmhas.call(store, it);\n };\n} else {\n var STATE = sharedKey('state');\n hiddenKeys[STATE] = true;\n set = function (it, metadata) {\n hide(it, STATE, metadata);\n return metadata;\n };\n get = function (it) {\n return objectHas(it, STATE) ? it[STATE] : {};\n };\n has = function (it) {\n return objectHas(it, STATE);\n };\n}\n\nmodule.exports = {\n set: set,\n get: get,\n has: has,\n enforce: enforce,\n getterFor: getterFor\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvaW50ZXJuYWwtc3RhdGUuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9pbnRlcm5hbC1zdGF0ZS5qcz82OWYzIl0sInNvdXJjZXNDb250ZW50IjpbInZhciBOQVRJVkVfV0VBS19NQVAgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvbmF0aXZlLXdlYWstbWFwJyk7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2dsb2JhbCcpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2lzLW9iamVjdCcpO1xudmFyIGhpZGUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaGlkZScpO1xudmFyIG9iamVjdEhhcyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9oYXMnKTtcbnZhciBzaGFyZWRLZXkgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvc2hhcmVkLWtleScpO1xudmFyIGhpZGRlbktleXMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaGlkZGVuLWtleXMnKTtcblxudmFyIFdlYWtNYXAgPSBnbG9iYWwuV2Vha01hcDtcbnZhciBzZXQsIGdldCwgaGFzO1xuXG52YXIgZW5mb3JjZSA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gaGFzKGl0KSA/IGdldChpdCkgOiBzZXQoaXQsIHt9KTtcbn07XG5cbnZhciBnZXR0ZXJGb3IgPSBmdW5jdGlvbiAoVFlQRSkge1xuICByZXR1cm4gZnVuY3Rpb24gKGl0KSB7XG4gICAgdmFyIHN0YXRlO1xuICAgIGlmICghaXNPYmplY3QoaXQpIHx8IChzdGF0ZSA9IGdldChpdCkpLnR5cGUgIT09IFRZUEUpIHtcbiAgICAgIHRocm93IFR5cGVFcnJvcignSW5jb21wYXRpYmxlIHJlY2VpdmVyLCAnICsgVFlQRSArICcgcmVxdWlyZWQnKTtcbiAgICB9IHJldHVybiBzdGF0ZTtcbiAgfTtcbn07XG5cbmlmIChOQVRJVkVfV0VBS19NQVApIHtcbiAgdmFyIHN0b3JlID0gbmV3IFdlYWtNYXAoKTtcbiAgdmFyIHdtZ2V0ID0gc3RvcmUuZ2V0O1xuICB2YXIgd21oYXMgPSBzdG9yZS5oYXM7XG4gIHZhciB3bXNldCA9IHN0b3JlLnNldDtcbiAgc2V0ID0gZnVuY3Rpb24gKGl0LCBtZXRhZGF0YSkge1xuICAgIHdtc2V0LmNhbGwoc3RvcmUsIGl0LCBtZXRhZGF0YSk7XG4gICAgcmV0dXJuIG1ldGFkYXRhO1xuICB9O1xuICBnZXQgPSBmdW5jdGlvbiAoaXQpIHtcbiAgICByZXR1cm4gd21nZXQuY2FsbChzdG9yZSwgaXQpIHx8IHt9O1xuICB9O1xuICBoYXMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgICByZXR1cm4gd21oYXMuY2FsbChzdG9yZSwgaXQpO1xuICB9O1xufSBlbHNlIHtcbiAgdmFyIFNUQVRFID0gc2hhcmVkS2V5KCdzdGF0ZScpO1xuICBoaWRkZW5LZXlzW1NUQVRFXSA9IHRydWU7XG4gIHNldCA9IGZ1bmN0aW9uIChpdCwgbWV0YWRhdGEpIHtcbiAgICBoaWRlKGl0LCBTVEFURSwgbWV0YWRhdGEpO1xuICAgIHJldHVybiBtZXRhZGF0YTtcbiAgfTtcbiAgZ2V0ID0gZnVuY3Rpb24gKGl0KSB7XG4gICAgcmV0dXJuIG9iamVjdEhhcyhpdCwgU1RBVEUpID8gaXRbU1RBVEVdIDoge307XG4gIH07XG4gIGhhcyA9IGZ1bmN0aW9uIChpdCkge1xuICAgIHJldHVybiBvYmplY3RIYXMoaXQsIFNUQVRFKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHNldDogc2V0LFxuICBnZXQ6IGdldCxcbiAgaGFzOiBoYXMsXG4gIGVuZm9yY2U6IGVuZm9yY2UsXG4gIGdldHRlckZvcjogZ2V0dGVyRm9yXG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/internal-state.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/is-array-iterator-method.js": +/*!********************************************************************!*\ + !*** ./node_modules/core-js/internals/is-array-iterator-method.js ***! + \********************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ \"./node_modules/core-js/internals/well-known-symbol.js\");\nvar Iterators = __webpack_require__(/*! ../internals/iterators */ \"./node_modules/core-js/internals/iterators.js\");\n\nvar ITERATOR = wellKnownSymbol('iterator');\nvar ArrayPrototype = Array.prototype;\n\n// check on default Array iterator\nmodule.exports = function (it) {\n return it !== undefined && (Iterators.Array === it || ArrayPrototype[ITERATOR] === it);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvaXMtYXJyYXktaXRlcmF0b3ItbWV0aG9kLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvaXMtYXJyYXktaXRlcmF0b3ItbWV0aG9kLmpzP2U5NWEiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIHdlbGxLbm93blN5bWJvbCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy93ZWxsLWtub3duLXN5bWJvbCcpO1xudmFyIEl0ZXJhdG9ycyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9pdGVyYXRvcnMnKTtcblxudmFyIElURVJBVE9SID0gd2VsbEtub3duU3ltYm9sKCdpdGVyYXRvcicpO1xudmFyIEFycmF5UHJvdG90eXBlID0gQXJyYXkucHJvdG90eXBlO1xuXG4vLyBjaGVjayBvbiBkZWZhdWx0IEFycmF5IGl0ZXJhdG9yXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gaXQgIT09IHVuZGVmaW5lZCAmJiAoSXRlcmF0b3JzLkFycmF5ID09PSBpdCB8fCBBcnJheVByb3RvdHlwZVtJVEVSQVRPUl0gPT09IGl0KTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/is-array-iterator-method.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/is-forced.js": +/*!*****************************************************!*\ + !*** ./node_modules/core-js/internals/is-forced.js ***! + \*****************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var fails = __webpack_require__(/*! ../internals/fails */ \"./node_modules/core-js/internals/fails.js\");\n\nvar replacement = /#|\\.prototype\\./;\n\nvar isForced = function (feature, detection) {\n var value = data[normalize(feature)];\n return value == POLYFILL ? true\n : value == NATIVE ? false\n : typeof detection == 'function' ? fails(detection)\n : !!detection;\n};\n\nvar normalize = isForced.normalize = function (string) {\n return String(string).replace(replacement, '.').toLowerCase();\n};\n\nvar data = isForced.data = {};\nvar NATIVE = isForced.NATIVE = 'N';\nvar POLYFILL = isForced.POLYFILL = 'P';\n\nmodule.exports = isForced;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvaXMtZm9yY2VkLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvaXMtZm9yY2VkLmpzPzk0Y2EiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIGZhaWxzID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2ZhaWxzJyk7XG5cbnZhciByZXBsYWNlbWVudCA9IC8jfFxcLnByb3RvdHlwZVxcLi87XG5cbnZhciBpc0ZvcmNlZCA9IGZ1bmN0aW9uIChmZWF0dXJlLCBkZXRlY3Rpb24pIHtcbiAgdmFyIHZhbHVlID0gZGF0YVtub3JtYWxpemUoZmVhdHVyZSldO1xuICByZXR1cm4gdmFsdWUgPT0gUE9MWUZJTEwgPyB0cnVlXG4gICAgOiB2YWx1ZSA9PSBOQVRJVkUgPyBmYWxzZVxuICAgIDogdHlwZW9mIGRldGVjdGlvbiA9PSAnZnVuY3Rpb24nID8gZmFpbHMoZGV0ZWN0aW9uKVxuICAgIDogISFkZXRlY3Rpb247XG59O1xuXG52YXIgbm9ybWFsaXplID0gaXNGb3JjZWQubm9ybWFsaXplID0gZnVuY3Rpb24gKHN0cmluZykge1xuICByZXR1cm4gU3RyaW5nKHN0cmluZykucmVwbGFjZShyZXBsYWNlbWVudCwgJy4nKS50b0xvd2VyQ2FzZSgpO1xufTtcblxudmFyIGRhdGEgPSBpc0ZvcmNlZC5kYXRhID0ge307XG52YXIgTkFUSVZFID0gaXNGb3JjZWQuTkFUSVZFID0gJ04nO1xudmFyIFBPTFlGSUxMID0gaXNGb3JjZWQuUE9MWUZJTEwgPSAnUCc7XG5cbm1vZHVsZS5leHBvcnRzID0gaXNGb3JjZWQ7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/is-forced.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/is-object.js": +/*!*****************************************************!*\ + !*** ./node_modules/core-js/internals/is-object.js ***! + \*****************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("module.exports = function (it) {\n return typeof it === 'object' ? it !== null : typeof it === 'function';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvaXMtb2JqZWN0LmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvaXMtb2JqZWN0LmpzPzg2MWQiXSwic291cmNlc0NvbnRlbnQiOlsibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIHR5cGVvZiBpdCA9PT0gJ29iamVjdCcgPyBpdCAhPT0gbnVsbCA6IHR5cGVvZiBpdCA9PT0gJ2Z1bmN0aW9uJztcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/is-object.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/is-pure.js": +/*!***************************************************!*\ + !*** ./node_modules/core-js/internals/is-pure.js ***! + \***************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("module.exports = false;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvaXMtcHVyZS5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL2lzLXB1cmUuanM/YzQzMCJdLCJzb3VyY2VzQ29udGVudCI6WyJtb2R1bGUuZXhwb3J0cyA9IGZhbHNlO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/is-pure.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/is-regexp.js": +/*!*****************************************************!*\ + !*** ./node_modules/core-js/internals/is-regexp.js ***! + \*****************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var isObject = __webpack_require__(/*! ../internals/is-object */ \"./node_modules/core-js/internals/is-object.js\");\nvar classof = __webpack_require__(/*! ../internals/classof-raw */ \"./node_modules/core-js/internals/classof-raw.js\");\nvar wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ \"./node_modules/core-js/internals/well-known-symbol.js\");\n\nvar MATCH = wellKnownSymbol('match');\n\n// `IsRegExp` abstract operation\n// https://tc39.github.io/ecma262/#sec-isregexp\nmodule.exports = function (it) {\n var isRegExp;\n return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : classof(it) == 'RegExp');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvaXMtcmVnZXhwLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvaXMtcmVnZXhwLmpzPzQ0ZTciXSwic291cmNlc0NvbnRlbnQiOlsidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2lzLW9iamVjdCcpO1xudmFyIGNsYXNzb2YgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvY2xhc3NvZi1yYXcnKTtcbnZhciB3ZWxsS25vd25TeW1ib2wgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvd2VsbC1rbm93bi1zeW1ib2wnKTtcblxudmFyIE1BVENIID0gd2VsbEtub3duU3ltYm9sKCdtYXRjaCcpO1xuXG4vLyBgSXNSZWdFeHBgIGFic3RyYWN0IG9wZXJhdGlvblxuLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtaXNyZWdleHBcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIHZhciBpc1JlZ0V4cDtcbiAgcmV0dXJuIGlzT2JqZWN0KGl0KSAmJiAoKGlzUmVnRXhwID0gaXRbTUFUQ0hdKSAhPT0gdW5kZWZpbmVkID8gISFpc1JlZ0V4cCA6IGNsYXNzb2YoaXQpID09ICdSZWdFeHAnKTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/is-regexp.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/iterate.js": +/*!***************************************************!*\ + !*** ./node_modules/core-js/internals/iterate.js ***! + \***************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var anObject = __webpack_require__(/*! ../internals/an-object */ \"./node_modules/core-js/internals/an-object.js\");\nvar isArrayIteratorMethod = __webpack_require__(/*! ../internals/is-array-iterator-method */ \"./node_modules/core-js/internals/is-array-iterator-method.js\");\nvar toLength = __webpack_require__(/*! ../internals/to-length */ \"./node_modules/core-js/internals/to-length.js\");\nvar bind = __webpack_require__(/*! ../internals/bind-context */ \"./node_modules/core-js/internals/bind-context.js\");\nvar getIteratorMethod = __webpack_require__(/*! ../internals/get-iterator-method */ \"./node_modules/core-js/internals/get-iterator-method.js\");\nvar callWithSafeIterationClosing = __webpack_require__(/*! ../internals/call-with-safe-iteration-closing */ \"./node_modules/core-js/internals/call-with-safe-iteration-closing.js\");\n\nvar BREAK = {};\n\nvar exports = module.exports = function (iterable, fn, that, ENTRIES, ITERATOR) {\n var boundFunction = bind(fn, that, ENTRIES ? 2 : 1);\n var iterator, iterFn, index, length, result, step;\n\n if (ITERATOR) {\n iterator = iterable;\n } else {\n iterFn = getIteratorMethod(iterable);\n if (typeof iterFn != 'function') throw TypeError('Target is not iterable');\n // optimisation for array iterators\n if (isArrayIteratorMethod(iterFn)) {\n for (index = 0, length = toLength(iterable.length); length > index; index++) {\n result = ENTRIES ? boundFunction(anObject(step = iterable[index])[0], step[1]) : boundFunction(iterable[index]);\n if (result === BREAK) return BREAK;\n } return;\n }\n iterator = iterFn.call(iterable);\n }\n\n while (!(step = iterator.next()).done) {\n if (callWithSafeIterationClosing(iterator, boundFunction, step.value, ENTRIES) === BREAK) return BREAK;\n }\n};\n\nexports.BREAK = BREAK;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvaXRlcmF0ZS5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL2l0ZXJhdGUuanM/MjI2NiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvYW4tb2JqZWN0Jyk7XG52YXIgaXNBcnJheUl0ZXJhdG9yTWV0aG9kID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2lzLWFycmF5LWl0ZXJhdG9yLW1ldGhvZCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3RvLWxlbmd0aCcpO1xudmFyIGJpbmQgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvYmluZC1jb250ZXh0Jyk7XG52YXIgZ2V0SXRlcmF0b3JNZXRob2QgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZ2V0LWl0ZXJhdG9yLW1ldGhvZCcpO1xudmFyIGNhbGxXaXRoU2FmZUl0ZXJhdGlvbkNsb3NpbmcgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvY2FsbC13aXRoLXNhZmUtaXRlcmF0aW9uLWNsb3NpbmcnKTtcblxudmFyIEJSRUFLID0ge307XG5cbnZhciBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXRlcmFibGUsIGZuLCB0aGF0LCBFTlRSSUVTLCBJVEVSQVRPUikge1xuICB2YXIgYm91bmRGdW5jdGlvbiA9IGJpbmQoZm4sIHRoYXQsIEVOVFJJRVMgPyAyIDogMSk7XG4gIHZhciBpdGVyYXRvciwgaXRlckZuLCBpbmRleCwgbGVuZ3RoLCByZXN1bHQsIHN0ZXA7XG5cbiAgaWYgKElURVJBVE9SKSB7XG4gICAgaXRlcmF0b3IgPSBpdGVyYWJsZTtcbiAgfSBlbHNlIHtcbiAgICBpdGVyRm4gPSBnZXRJdGVyYXRvck1ldGhvZChpdGVyYWJsZSk7XG4gICAgaWYgKHR5cGVvZiBpdGVyRm4gIT0gJ2Z1bmN0aW9uJykgdGhyb3cgVHlwZUVycm9yKCdUYXJnZXQgaXMgbm90IGl0ZXJhYmxlJyk7XG4gICAgLy8gb3B0aW1pc2F0aW9uIGZvciBhcnJheSBpdGVyYXRvcnNcbiAgICBpZiAoaXNBcnJheUl0ZXJhdG9yTWV0aG9kKGl0ZXJGbikpIHtcbiAgICAgIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSB0b0xlbmd0aChpdGVyYWJsZS5sZW5ndGgpOyBsZW5ndGggPiBpbmRleDsgaW5kZXgrKykge1xuICAgICAgICByZXN1bHQgPSBFTlRSSUVTID8gYm91bmRGdW5jdGlvbihhbk9iamVjdChzdGVwID0gaXRlcmFibGVbaW5kZXhdKVswXSwgc3RlcFsxXSkgOiBib3VuZEZ1bmN0aW9uKGl0ZXJhYmxlW2luZGV4XSk7XG4gICAgICAgIGlmIChyZXN1bHQgPT09IEJSRUFLKSByZXR1cm4gQlJFQUs7XG4gICAgICB9IHJldHVybjtcbiAgICB9XG4gICAgaXRlcmF0b3IgPSBpdGVyRm4uY2FsbChpdGVyYWJsZSk7XG4gIH1cblxuICB3aGlsZSAoIShzdGVwID0gaXRlcmF0b3IubmV4dCgpKS5kb25lKSB7XG4gICAgaWYgKGNhbGxXaXRoU2FmZUl0ZXJhdGlvbkNsb3NpbmcoaXRlcmF0b3IsIGJvdW5kRnVuY3Rpb24sIHN0ZXAudmFsdWUsIEVOVFJJRVMpID09PSBCUkVBSykgcmV0dXJuIEJSRUFLO1xuICB9XG59O1xuXG5leHBvcnRzLkJSRUFLID0gQlJFQUs7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/iterate.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/iterators-core.js": +/*!**********************************************************!*\ + !*** ./node_modules/core-js/internals/iterators-core.js ***! + \**********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar getPrototypeOf = __webpack_require__(/*! ../internals/object-get-prototype-of */ \"./node_modules/core-js/internals/object-get-prototype-of.js\");\nvar hide = __webpack_require__(/*! ../internals/hide */ \"./node_modules/core-js/internals/hide.js\");\nvar has = __webpack_require__(/*! ../internals/has */ \"./node_modules/core-js/internals/has.js\");\nvar wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ \"./node_modules/core-js/internals/well-known-symbol.js\");\nvar IS_PURE = __webpack_require__(/*! ../internals/is-pure */ \"./node_modules/core-js/internals/is-pure.js\");\n\nvar ITERATOR = wellKnownSymbol('iterator');\nvar BUGGY_SAFARI_ITERATORS = false;\n\nvar returnThis = function () { return this; };\n\n// `%IteratorPrototype%` object\n// https://tc39.github.io/ecma262/#sec-%iteratorprototype%-object\nvar IteratorPrototype, PrototypeOfArrayIteratorPrototype, arrayIterator;\n\nif ([].keys) {\n arrayIterator = [].keys();\n // Safari 8 has buggy iterators w/o `next`\n if (!('next' in arrayIterator)) BUGGY_SAFARI_ITERATORS = true;\n else {\n PrototypeOfArrayIteratorPrototype = getPrototypeOf(getPrototypeOf(arrayIterator));\n if (PrototypeOfArrayIteratorPrototype !== Object.prototype) IteratorPrototype = PrototypeOfArrayIteratorPrototype;\n }\n}\n\nif (IteratorPrototype == undefined) IteratorPrototype = {};\n\n// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()\nif (!IS_PURE && !has(IteratorPrototype, ITERATOR)) hide(IteratorPrototype, ITERATOR, returnThis);\n\nmodule.exports = {\n IteratorPrototype: IteratorPrototype,\n BUGGY_SAFARI_ITERATORS: BUGGY_SAFARI_ITERATORS\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvaXRlcmF0b3JzLWNvcmUuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9pdGVyYXRvcnMtY29yZS5qcz9hZTkzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcbnZhciBnZXRQcm90b3R5cGVPZiA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9vYmplY3QtZ2V0LXByb3RvdHlwZS1vZicpO1xudmFyIGhpZGUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaGlkZScpO1xudmFyIGhhcyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9oYXMnKTtcbnZhciB3ZWxsS25vd25TeW1ib2wgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvd2VsbC1rbm93bi1zeW1ib2wnKTtcbnZhciBJU19QVVJFID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2lzLXB1cmUnKTtcblxudmFyIElURVJBVE9SID0gd2VsbEtub3duU3ltYm9sKCdpdGVyYXRvcicpO1xudmFyIEJVR0dZX1NBRkFSSV9JVEVSQVRPUlMgPSBmYWxzZTtcblxudmFyIHJldHVyblRoaXMgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9O1xuXG4vLyBgJUl0ZXJhdG9yUHJvdG90eXBlJWAgb2JqZWN0XG4vLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy0laXRlcmF0b3Jwcm90b3R5cGUlLW9iamVjdFxudmFyIEl0ZXJhdG9yUHJvdG90eXBlLCBQcm90b3R5cGVPZkFycmF5SXRlcmF0b3JQcm90b3R5cGUsIGFycmF5SXRlcmF0b3I7XG5cbmlmIChbXS5rZXlzKSB7XG4gIGFycmF5SXRlcmF0b3IgPSBbXS5rZXlzKCk7XG4gIC8vIFNhZmFyaSA4IGhhcyBidWdneSBpdGVyYXRvcnMgdy9vIGBuZXh0YFxuICBpZiAoISgnbmV4dCcgaW4gYXJyYXlJdGVyYXRvcikpIEJVR0dZX1NBRkFSSV9JVEVSQVRPUlMgPSB0cnVlO1xuICBlbHNlIHtcbiAgICBQcm90b3R5cGVPZkFycmF5SXRlcmF0b3JQcm90b3R5cGUgPSBnZXRQcm90b3R5cGVPZihnZXRQcm90b3R5cGVPZihhcnJheUl0ZXJhdG9yKSk7XG4gICAgaWYgKFByb3RvdHlwZU9mQXJyYXlJdGVyYXRvclByb3RvdHlwZSAhPT0gT2JqZWN0LnByb3RvdHlwZSkgSXRlcmF0b3JQcm90b3R5cGUgPSBQcm90b3R5cGVPZkFycmF5SXRlcmF0b3JQcm90b3R5cGU7XG4gIH1cbn1cblxuaWYgKEl0ZXJhdG9yUHJvdG90eXBlID09IHVuZGVmaW5lZCkgSXRlcmF0b3JQcm90b3R5cGUgPSB7fTtcblxuLy8gMjUuMS4yLjEuMSAlSXRlcmF0b3JQcm90b3R5cGUlW0BAaXRlcmF0b3JdKClcbmlmICghSVNfUFVSRSAmJiAhaGFzKEl0ZXJhdG9yUHJvdG90eXBlLCBJVEVSQVRPUikpIGhpZGUoSXRlcmF0b3JQcm90b3R5cGUsIElURVJBVE9SLCByZXR1cm5UaGlzKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIEl0ZXJhdG9yUHJvdG90eXBlOiBJdGVyYXRvclByb3RvdHlwZSxcbiAgQlVHR1lfU0FGQVJJX0lURVJBVE9SUzogQlVHR1lfU0FGQVJJX0lURVJBVE9SU1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/iterators-core.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/iterators.js": +/*!*****************************************************!*\ + !*** ./node_modules/core-js/internals/iterators.js ***! + \*****************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("module.exports = {};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvaXRlcmF0b3JzLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvaXRlcmF0b3JzLmpzPzNmOGMiXSwic291cmNlc0NvbnRlbnQiOlsibW9kdWxlLmV4cG9ydHMgPSB7fTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/iterators.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/microtask.js": +/*!*****************************************************!*\ + !*** ./node_modules/core-js/internals/microtask.js ***! + \*****************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var global = __webpack_require__(/*! ../internals/global */ \"./node_modules/core-js/internals/global.js\");\nvar getOwnPropertyDescriptor = __webpack_require__(/*! ../internals/object-get-own-property-descriptor */ \"./node_modules/core-js/internals/object-get-own-property-descriptor.js\").f;\nvar classof = __webpack_require__(/*! ../internals/classof-raw */ \"./node_modules/core-js/internals/classof-raw.js\");\nvar macrotask = __webpack_require__(/*! ../internals/task */ \"./node_modules/core-js/internals/task.js\").set;\nvar userAgent = __webpack_require__(/*! ../internals/user-agent */ \"./node_modules/core-js/internals/user-agent.js\");\n\nvar MutationObserver = global.MutationObserver || global.WebKitMutationObserver;\nvar process = global.process;\nvar Promise = global.Promise;\nvar IS_NODE = classof(process) == 'process';\n// Node.js 11 shows ExperimentalWarning on getting `queueMicrotask`\nvar queueMicrotaskDescriptor = getOwnPropertyDescriptor(global, 'queueMicrotask');\nvar queueMicrotask = queueMicrotaskDescriptor && queueMicrotaskDescriptor.value;\n\nvar flush, head, last, notify, toggle, node, promise;\n\n// modern engines have queueMicrotask method\nif (!queueMicrotask) {\n flush = function () {\n var parent, fn;\n if (IS_NODE && (parent = process.domain)) parent.exit();\n while (head) {\n fn = head.fn;\n head = head.next;\n try {\n fn();\n } catch (error) {\n if (head) notify();\n else last = undefined;\n throw error;\n }\n } last = undefined;\n if (parent) parent.enter();\n };\n\n // Node.js\n if (IS_NODE) {\n notify = function () {\n process.nextTick(flush);\n };\n // browsers with MutationObserver, except iOS - https://github.com/zloirock/core-js/issues/339\n } else if (MutationObserver && !/(iphone|ipod|ipad).*applewebkit/i.test(userAgent)) {\n toggle = true;\n node = document.createTextNode('');\n new MutationObserver(flush).observe(node, { characterData: true }); // eslint-disable-line no-new\n notify = function () {\n node.data = toggle = !toggle;\n };\n // environments with maybe non-completely correct, but existent Promise\n } else if (Promise && Promise.resolve) {\n // Promise.resolve without an argument throws an error in LG WebOS 2\n promise = Promise.resolve(undefined);\n notify = function () {\n promise.then(flush);\n };\n // for other environments - macrotask based on:\n // - setImmediate\n // - MessageChannel\n // - window.postMessag\n // - onreadystatechange\n // - setTimeout\n } else {\n notify = function () {\n // strange IE + webpack dev server bug - use .call(global)\n macrotask.call(global, flush);\n };\n }\n}\n\nmodule.exports = queueMicrotask || function (fn) {\n var task = { fn: fn, next: undefined };\n if (last) last.next = task;\n if (!head) {\n head = task;\n notify();\n } last = task;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvbWljcm90YXNrLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvbWljcm90YXNrLmpzP2I1NzUiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9nbG9iYWwnKTtcbnZhciBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvb2JqZWN0LWdldC1vd24tcHJvcGVydHktZGVzY3JpcHRvcicpLmY7XG52YXIgY2xhc3NvZiA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9jbGFzc29mLXJhdycpO1xudmFyIG1hY3JvdGFzayA9IHJlcXVpcmUoJy4uL2ludGVybmFscy90YXNrJykuc2V0O1xudmFyIHVzZXJBZ2VudCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy91c2VyLWFnZW50Jyk7XG5cbnZhciBNdXRhdGlvbk9ic2VydmVyID0gZ2xvYmFsLk11dGF0aW9uT2JzZXJ2ZXIgfHwgZ2xvYmFsLldlYktpdE11dGF0aW9uT2JzZXJ2ZXI7XG52YXIgcHJvY2VzcyA9IGdsb2JhbC5wcm9jZXNzO1xudmFyIFByb21pc2UgPSBnbG9iYWwuUHJvbWlzZTtcbnZhciBJU19OT0RFID0gY2xhc3NvZihwcm9jZXNzKSA9PSAncHJvY2Vzcyc7XG4vLyBOb2RlLmpzIDExIHNob3dzIEV4cGVyaW1lbnRhbFdhcm5pbmcgb24gZ2V0dGluZyBgcXVldWVNaWNyb3Rhc2tgXG52YXIgcXVldWVNaWNyb3Rhc2tEZXNjcmlwdG9yID0gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGdsb2JhbCwgJ3F1ZXVlTWljcm90YXNrJyk7XG52YXIgcXVldWVNaWNyb3Rhc2sgPSBxdWV1ZU1pY3JvdGFza0Rlc2NyaXB0b3IgJiYgcXVldWVNaWNyb3Rhc2tEZXNjcmlwdG9yLnZhbHVlO1xuXG52YXIgZmx1c2gsIGhlYWQsIGxhc3QsIG5vdGlmeSwgdG9nZ2xlLCBub2RlLCBwcm9taXNlO1xuXG4vLyBtb2Rlcm4gZW5naW5lcyBoYXZlIHF1ZXVlTWljcm90YXNrIG1ldGhvZFxuaWYgKCFxdWV1ZU1pY3JvdGFzaykge1xuICBmbHVzaCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcGFyZW50LCBmbjtcbiAgICBpZiAoSVNfTk9ERSAmJiAocGFyZW50ID0gcHJvY2Vzcy5kb21haW4pKSBwYXJlbnQuZXhpdCgpO1xuICAgIHdoaWxlIChoZWFkKSB7XG4gICAgICBmbiA9IGhlYWQuZm47XG4gICAgICBoZWFkID0gaGVhZC5uZXh0O1xuICAgICAgdHJ5IHtcbiAgICAgICAgZm4oKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGlmIChoZWFkKSBub3RpZnkoKTtcbiAgICAgICAgZWxzZSBsYXN0ID0gdW5kZWZpbmVkO1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICB9IGxhc3QgPSB1bmRlZmluZWQ7XG4gICAgaWYgKHBhcmVudCkgcGFyZW50LmVudGVyKCk7XG4gIH07XG5cbiAgLy8gTm9kZS5qc1xuICBpZiAoSVNfTk9ERSkge1xuICAgIG5vdGlmeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHByb2Nlc3MubmV4dFRpY2soZmx1c2gpO1xuICAgIH07XG4gIC8vIGJyb3dzZXJzIHdpdGggTXV0YXRpb25PYnNlcnZlciwgZXhjZXB0IGlPUyAtIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2lzc3Vlcy8zMzlcbiAgfSBlbHNlIGlmIChNdXRhdGlvbk9ic2VydmVyICYmICEvKGlwaG9uZXxpcG9kfGlwYWQpLiphcHBsZXdlYmtpdC9pLnRlc3QodXNlckFnZW50KSkge1xuICAgIHRvZ2dsZSA9IHRydWU7XG4gICAgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCcnKTtcbiAgICBuZXcgTXV0YXRpb25PYnNlcnZlcihmbHVzaCkub2JzZXJ2ZShub2RlLCB7IGNoYXJhY3RlckRhdGE6IHRydWUgfSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XG4gICAgbm90aWZ5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgbm9kZS5kYXRhID0gdG9nZ2xlID0gIXRvZ2dsZTtcbiAgICB9O1xuICAvLyBlbnZpcm9ubWVudHMgd2l0aCBtYXliZSBub24tY29tcGxldGVseSBjb3JyZWN0LCBidXQgZXhpc3RlbnQgUHJvbWlzZVxuICB9IGVsc2UgaWYgKFByb21pc2UgJiYgUHJvbWlzZS5yZXNvbHZlKSB7XG4gICAgLy8gUHJvbWlzZS5yZXNvbHZlIHdpdGhvdXQgYW4gYXJndW1lbnQgdGhyb3dzIGFuIGVycm9yIGluIExHIFdlYk9TIDJcbiAgICBwcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKHVuZGVmaW5lZCk7XG4gICAgbm90aWZ5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgcHJvbWlzZS50aGVuKGZsdXNoKTtcbiAgICB9O1xuICAvLyBmb3Igb3RoZXIgZW52aXJvbm1lbnRzIC0gbWFjcm90YXNrIGJhc2VkIG9uOlxuICAvLyAtIHNldEltbWVkaWF0ZVxuICAvLyAtIE1lc3NhZ2VDaGFubmVsXG4gIC8vIC0gd2luZG93LnBvc3RNZXNzYWdcbiAgLy8gLSBvbnJlYWR5c3RhdGVjaGFuZ2VcbiAgLy8gLSBzZXRUaW1lb3V0XG4gIH0gZWxzZSB7XG4gICAgbm90aWZ5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgLy8gc3RyYW5nZSBJRSArIHdlYnBhY2sgZGV2IHNlcnZlciBidWcgLSB1c2UgLmNhbGwoZ2xvYmFsKVxuICAgICAgbWFjcm90YXNrLmNhbGwoZ2xvYmFsLCBmbHVzaCk7XG4gICAgfTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHF1ZXVlTWljcm90YXNrIHx8IGZ1bmN0aW9uIChmbikge1xuICB2YXIgdGFzayA9IHsgZm46IGZuLCBuZXh0OiB1bmRlZmluZWQgfTtcbiAgaWYgKGxhc3QpIGxhc3QubmV4dCA9IHRhc2s7XG4gIGlmICghaGVhZCkge1xuICAgIGhlYWQgPSB0YXNrO1xuICAgIG5vdGlmeSgpO1xuICB9IGxhc3QgPSB0YXNrO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/microtask.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/native-symbol.js": +/*!*********************************************************!*\ + !*** ./node_modules/core-js/internals/native-symbol.js ***! + \*********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var fails = __webpack_require__(/*! ../internals/fails */ \"./node_modules/core-js/internals/fails.js\");\n\nmodule.exports = !!Object.getOwnPropertySymbols && !fails(function () {\n // Chrome 38 Symbol has incorrect toString conversion\n // eslint-disable-next-line no-undef\n return !String(Symbol());\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvbmF0aXZlLXN5bWJvbC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL25hdGl2ZS1zeW1ib2wuanM/NDkzMCJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgZmFpbHMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZmFpbHMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSAhIU9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgJiYgIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgLy8gQ2hyb21lIDM4IFN5bWJvbCBoYXMgaW5jb3JyZWN0IHRvU3RyaW5nIGNvbnZlcnNpb25cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG4gIHJldHVybiAhU3RyaW5nKFN5bWJvbCgpKTtcbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/native-symbol.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/native-weak-map.js": +/*!***********************************************************!*\ + !*** ./node_modules/core-js/internals/native-weak-map.js ***! + \***********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var global = __webpack_require__(/*! ../internals/global */ \"./node_modules/core-js/internals/global.js\");\nvar nativeFunctionToString = __webpack_require__(/*! ../internals/function-to-string */ \"./node_modules/core-js/internals/function-to-string.js\");\n\nvar WeakMap = global.WeakMap;\n\nmodule.exports = typeof WeakMap === 'function' && /native code/.test(nativeFunctionToString.call(WeakMap));\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvbmF0aXZlLXdlYWstbWFwLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvbmF0aXZlLXdlYWstbWFwLmpzPzdmOWEiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9nbG9iYWwnKTtcbnZhciBuYXRpdmVGdW5jdGlvblRvU3RyaW5nID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2Z1bmN0aW9uLXRvLXN0cmluZycpO1xuXG52YXIgV2Vha01hcCA9IGdsb2JhbC5XZWFrTWFwO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHR5cGVvZiBXZWFrTWFwID09PSAnZnVuY3Rpb24nICYmIC9uYXRpdmUgY29kZS8udGVzdChuYXRpdmVGdW5jdGlvblRvU3RyaW5nLmNhbGwoV2Vha01hcCkpO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/native-weak-map.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/new-promise-capability.js": +/*!******************************************************************!*\ + !*** ./node_modules/core-js/internals/new-promise-capability.js ***! + \******************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar aFunction = __webpack_require__(/*! ../internals/a-function */ \"./node_modules/core-js/internals/a-function.js\");\n\nvar PromiseCapability = function (C) {\n var resolve, reject;\n this.promise = new C(function ($$resolve, $$reject) {\n if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor');\n resolve = $$resolve;\n reject = $$reject;\n });\n this.resolve = aFunction(resolve);\n this.reject = aFunction(reject);\n};\n\n// 25.4.1.5 NewPromiseCapability(C)\nmodule.exports.f = function (C) {\n return new PromiseCapability(C);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvbmV3LXByb21pc2UtY2FwYWJpbGl0eS5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL25ldy1wcm9taXNlLWNhcGFiaWxpdHkuanM/ZjA2OSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG52YXIgYUZ1bmN0aW9uID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2EtZnVuY3Rpb24nKTtcblxudmFyIFByb21pc2VDYXBhYmlsaXR5ID0gZnVuY3Rpb24gKEMpIHtcbiAgdmFyIHJlc29sdmUsIHJlamVjdDtcbiAgdGhpcy5wcm9taXNlID0gbmV3IEMoZnVuY3Rpb24gKCQkcmVzb2x2ZSwgJCRyZWplY3QpIHtcbiAgICBpZiAocmVzb2x2ZSAhPT0gdW5kZWZpbmVkIHx8IHJlamVjdCAhPT0gdW5kZWZpbmVkKSB0aHJvdyBUeXBlRXJyb3IoJ0JhZCBQcm9taXNlIGNvbnN0cnVjdG9yJyk7XG4gICAgcmVzb2x2ZSA9ICQkcmVzb2x2ZTtcbiAgICByZWplY3QgPSAkJHJlamVjdDtcbiAgfSk7XG4gIHRoaXMucmVzb2x2ZSA9IGFGdW5jdGlvbihyZXNvbHZlKTtcbiAgdGhpcy5yZWplY3QgPSBhRnVuY3Rpb24ocmVqZWN0KTtcbn07XG5cbi8vIDI1LjQuMS41IE5ld1Byb21pc2VDYXBhYmlsaXR5KEMpXG5tb2R1bGUuZXhwb3J0cy5mID0gZnVuY3Rpb24gKEMpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlQ2FwYWJpbGl0eShDKTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/new-promise-capability.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/object-create.js": +/*!*********************************************************!*\ + !*** ./node_modules/core-js/internals/object-create.js ***! + \*********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var anObject = __webpack_require__(/*! ../internals/an-object */ \"./node_modules/core-js/internals/an-object.js\");\nvar defineProperties = __webpack_require__(/*! ../internals/object-define-properties */ \"./node_modules/core-js/internals/object-define-properties.js\");\nvar enumBugKeys = __webpack_require__(/*! ../internals/enum-bug-keys */ \"./node_modules/core-js/internals/enum-bug-keys.js\");\nvar hiddenKeys = __webpack_require__(/*! ../internals/hidden-keys */ \"./node_modules/core-js/internals/hidden-keys.js\");\nvar html = __webpack_require__(/*! ../internals/html */ \"./node_modules/core-js/internals/html.js\");\nvar documentCreateElement = __webpack_require__(/*! ../internals/document-create-element */ \"./node_modules/core-js/internals/document-create-element.js\");\nvar sharedKey = __webpack_require__(/*! ../internals/shared-key */ \"./node_modules/core-js/internals/shared-key.js\");\nvar IE_PROTO = sharedKey('IE_PROTO');\n\nvar PROTOTYPE = 'prototype';\nvar Empty = function () { /* empty */ };\n\n// Create object with fake `null` prototype: use iframe Object with cleared prototype\nvar createDict = function () {\n // Thrash, waste and sodomy: IE GC bug\n var iframe = documentCreateElement('iframe');\n var length = enumBugKeys.length;\n var lt = '<';\n var script = 'script';\n var gt = '>';\n var js = 'java' + script + ':';\n var iframeDocument;\n iframe.style.display = 'none';\n html.appendChild(iframe);\n iframe.src = String(js);\n iframeDocument = iframe.contentWindow.document;\n iframeDocument.open();\n iframeDocument.write(lt + script + gt + 'document.F=Object' + lt + '/' + script + gt);\n iframeDocument.close();\n createDict = iframeDocument.F;\n while (length--) delete createDict[PROTOTYPE][enumBugKeys[length]];\n return createDict();\n};\n\n// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])\nmodule.exports = Object.create || function create(O, Properties) {\n var result;\n if (O !== null) {\n Empty[PROTOTYPE] = anObject(O);\n result = new Empty();\n Empty[PROTOTYPE] = null;\n // add \"__proto__\" for Object.getPrototypeOf polyfill\n result[IE_PROTO] = O;\n } else result = createDict();\n return Properties === undefined ? result : defineProperties(result, Properties);\n};\n\nhiddenKeys[IE_PROTO] = true;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvb2JqZWN0LWNyZWF0ZS5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL29iamVjdC1jcmVhdGUuanM/N2M3MyJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvYW4tb2JqZWN0Jyk7XG52YXIgZGVmaW5lUHJvcGVydGllcyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9vYmplY3QtZGVmaW5lLXByb3BlcnRpZXMnKTtcbnZhciBlbnVtQnVnS2V5cyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9lbnVtLWJ1Zy1rZXlzJyk7XG52YXIgaGlkZGVuS2V5cyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9oaWRkZW4ta2V5cycpO1xudmFyIGh0bWwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaHRtbCcpO1xudmFyIGRvY3VtZW50Q3JlYXRlRWxlbWVudCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9kb2N1bWVudC1jcmVhdGUtZWxlbWVudCcpO1xudmFyIHNoYXJlZEtleSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9zaGFyZWQta2V5Jyk7XG52YXIgSUVfUFJPVE8gPSBzaGFyZWRLZXkoJ0lFX1BST1RPJyk7XG5cbnZhciBQUk9UT1RZUEUgPSAncHJvdG90eXBlJztcbnZhciBFbXB0eSA9IGZ1bmN0aW9uICgpIHsgLyogZW1wdHkgKi8gfTtcblxuLy8gQ3JlYXRlIG9iamVjdCB3aXRoIGZha2UgYG51bGxgIHByb3RvdHlwZTogdXNlIGlmcmFtZSBPYmplY3Qgd2l0aCBjbGVhcmVkIHByb3RvdHlwZVxudmFyIGNyZWF0ZURpY3QgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIFRocmFzaCwgd2FzdGUgYW5kIHNvZG9teTogSUUgR0MgYnVnXG4gIHZhciBpZnJhbWUgPSBkb2N1bWVudENyZWF0ZUVsZW1lbnQoJ2lmcmFtZScpO1xuICB2YXIgbGVuZ3RoID0gZW51bUJ1Z0tleXMubGVuZ3RoO1xuICB2YXIgbHQgPSAnPCc7XG4gIHZhciBzY3JpcHQgPSAnc2NyaXB0JztcbiAgdmFyIGd0ID0gJz4nO1xuICB2YXIganMgPSAnamF2YScgKyBzY3JpcHQgKyAnOic7XG4gIHZhciBpZnJhbWVEb2N1bWVudDtcbiAgaWZyYW1lLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gIGh0bWwuYXBwZW5kQ2hpbGQoaWZyYW1lKTtcbiAgaWZyYW1lLnNyYyA9IFN0cmluZyhqcyk7XG4gIGlmcmFtZURvY3VtZW50ID0gaWZyYW1lLmNvbnRlbnRXaW5kb3cuZG9jdW1lbnQ7XG4gIGlmcmFtZURvY3VtZW50Lm9wZW4oKTtcbiAgaWZyYW1lRG9jdW1lbnQud3JpdGUobHQgKyBzY3JpcHQgKyBndCArICdkb2N1bWVudC5GPU9iamVjdCcgKyBsdCArICcvJyArIHNjcmlwdCArIGd0KTtcbiAgaWZyYW1lRG9jdW1lbnQuY2xvc2UoKTtcbiAgY3JlYXRlRGljdCA9IGlmcmFtZURvY3VtZW50LkY7XG4gIHdoaWxlIChsZW5ndGgtLSkgZGVsZXRlIGNyZWF0ZURpY3RbUFJPVE9UWVBFXVtlbnVtQnVnS2V5c1tsZW5ndGhdXTtcbiAgcmV0dXJuIGNyZWF0ZURpY3QoKTtcbn07XG5cbi8vIDE5LjEuMi4yIC8gMTUuMi4zLjUgT2JqZWN0LmNyZWF0ZShPIFssIFByb3BlcnRpZXNdKVxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3QuY3JlYXRlIHx8IGZ1bmN0aW9uIGNyZWF0ZShPLCBQcm9wZXJ0aWVzKSB7XG4gIHZhciByZXN1bHQ7XG4gIGlmIChPICE9PSBudWxsKSB7XG4gICAgRW1wdHlbUFJPVE9UWVBFXSA9IGFuT2JqZWN0KE8pO1xuICAgIHJlc3VsdCA9IG5ldyBFbXB0eSgpO1xuICAgIEVtcHR5W1BST1RPVFlQRV0gPSBudWxsO1xuICAgIC8vIGFkZCBcIl9fcHJvdG9fX1wiIGZvciBPYmplY3QuZ2V0UHJvdG90eXBlT2YgcG9seWZpbGxcbiAgICByZXN1bHRbSUVfUFJPVE9dID0gTztcbiAgfSBlbHNlIHJlc3VsdCA9IGNyZWF0ZURpY3QoKTtcbiAgcmV0dXJuIFByb3BlcnRpZXMgPT09IHVuZGVmaW5lZCA/IHJlc3VsdCA6IGRlZmluZVByb3BlcnRpZXMocmVzdWx0LCBQcm9wZXJ0aWVzKTtcbn07XG5cbmhpZGRlbktleXNbSUVfUFJPVE9dID0gdHJ1ZTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/object-create.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/object-define-properties.js": +/*!********************************************************************!*\ + !*** ./node_modules/core-js/internals/object-define-properties.js ***! + \********************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ \"./node_modules/core-js/internals/descriptors.js\");\nvar definePropertyModule = __webpack_require__(/*! ../internals/object-define-property */ \"./node_modules/core-js/internals/object-define-property.js\");\nvar anObject = __webpack_require__(/*! ../internals/an-object */ \"./node_modules/core-js/internals/an-object.js\");\nvar objectKeys = __webpack_require__(/*! ../internals/object-keys */ \"./node_modules/core-js/internals/object-keys.js\");\n\nmodule.exports = DESCRIPTORS ? Object.defineProperties : function defineProperties(O, Properties) {\n anObject(O);\n var keys = objectKeys(Properties);\n var length = keys.length;\n var i = 0;\n var key;\n while (length > i) definePropertyModule.f(O, key = keys[i++], Properties[key]);\n return O;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvb2JqZWN0LWRlZmluZS1wcm9wZXJ0aWVzLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvb2JqZWN0LWRlZmluZS1wcm9wZXJ0aWVzLmpzPzM3ZTgiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIERFU0NSSVBUT1JTID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2Rlc2NyaXB0b3JzJyk7XG52YXIgZGVmaW5lUHJvcGVydHlNb2R1bGUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvb2JqZWN0LWRlZmluZS1wcm9wZXJ0eScpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2FuLW9iamVjdCcpO1xudmFyIG9iamVjdEtleXMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvb2JqZWN0LWtleXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBERVNDUklQVE9SUyA/IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzIDogZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyhPLCBQcm9wZXJ0aWVzKSB7XG4gIGFuT2JqZWN0KE8pO1xuICB2YXIga2V5cyA9IG9iamVjdEtleXMoUHJvcGVydGllcyk7XG4gIHZhciBsZW5ndGggPSBrZXlzLmxlbmd0aDtcbiAgdmFyIGkgPSAwO1xuICB2YXIga2V5O1xuICB3aGlsZSAobGVuZ3RoID4gaSkgZGVmaW5lUHJvcGVydHlNb2R1bGUuZihPLCBrZXkgPSBrZXlzW2krK10sIFByb3BlcnRpZXNba2V5XSk7XG4gIHJldHVybiBPO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/object-define-properties.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/object-define-property.js": +/*!******************************************************************!*\ + !*** ./node_modules/core-js/internals/object-define-property.js ***! + \******************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ \"./node_modules/core-js/internals/descriptors.js\");\nvar IE8_DOM_DEFINE = __webpack_require__(/*! ../internals/ie8-dom-define */ \"./node_modules/core-js/internals/ie8-dom-define.js\");\nvar anObject = __webpack_require__(/*! ../internals/an-object */ \"./node_modules/core-js/internals/an-object.js\");\nvar toPrimitive = __webpack_require__(/*! ../internals/to-primitive */ \"./node_modules/core-js/internals/to-primitive.js\");\n\nvar nativeDefineProperty = Object.defineProperty;\n\nexports.f = DESCRIPTORS ? nativeDefineProperty : function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPrimitive(P, true);\n anObject(Attributes);\n if (IE8_DOM_DEFINE) try {\n return nativeDefineProperty(O, P, Attributes);\n } catch (error) { /* empty */ }\n if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported');\n if ('value' in Attributes) O[P] = Attributes.value;\n return O;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvb2JqZWN0LWRlZmluZS1wcm9wZXJ0eS5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL29iamVjdC1kZWZpbmUtcHJvcGVydHkuanM/OWJmMiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgREVTQ1JJUFRPUlMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZGVzY3JpcHRvcnMnKTtcbnZhciBJRThfRE9NX0RFRklORSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9pZTgtZG9tLWRlZmluZScpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2FuLW9iamVjdCcpO1xudmFyIHRvUHJpbWl0aXZlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3RvLXByaW1pdGl2ZScpO1xuXG52YXIgbmF0aXZlRGVmaW5lUHJvcGVydHkgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG5cbmV4cG9ydHMuZiA9IERFU0NSSVBUT1JTID8gbmF0aXZlRGVmaW5lUHJvcGVydHkgOiBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0eShPLCBQLCBBdHRyaWJ1dGVzKSB7XG4gIGFuT2JqZWN0KE8pO1xuICBQID0gdG9QcmltaXRpdmUoUCwgdHJ1ZSk7XG4gIGFuT2JqZWN0KEF0dHJpYnV0ZXMpO1xuICBpZiAoSUU4X0RPTV9ERUZJTkUpIHRyeSB7XG4gICAgcmV0dXJuIG5hdGl2ZURlZmluZVByb3BlcnR5KE8sIFAsIEF0dHJpYnV0ZXMpO1xuICB9IGNhdGNoIChlcnJvcikgeyAvKiBlbXB0eSAqLyB9XG4gIGlmICgnZ2V0JyBpbiBBdHRyaWJ1dGVzIHx8ICdzZXQnIGluIEF0dHJpYnV0ZXMpIHRocm93IFR5cGVFcnJvcignQWNjZXNzb3JzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgaWYgKCd2YWx1ZScgaW4gQXR0cmlidXRlcykgT1tQXSA9IEF0dHJpYnV0ZXMudmFsdWU7XG4gIHJldHVybiBPO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/object-define-property.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/object-get-own-property-descriptor.js": +/*!******************************************************************************!*\ + !*** ./node_modules/core-js/internals/object-get-own-property-descriptor.js ***! + \******************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ \"./node_modules/core-js/internals/descriptors.js\");\nvar propertyIsEnumerableModule = __webpack_require__(/*! ../internals/object-property-is-enumerable */ \"./node_modules/core-js/internals/object-property-is-enumerable.js\");\nvar createPropertyDescriptor = __webpack_require__(/*! ../internals/create-property-descriptor */ \"./node_modules/core-js/internals/create-property-descriptor.js\");\nvar toIndexedObject = __webpack_require__(/*! ../internals/to-indexed-object */ \"./node_modules/core-js/internals/to-indexed-object.js\");\nvar toPrimitive = __webpack_require__(/*! ../internals/to-primitive */ \"./node_modules/core-js/internals/to-primitive.js\");\nvar has = __webpack_require__(/*! ../internals/has */ \"./node_modules/core-js/internals/has.js\");\nvar IE8_DOM_DEFINE = __webpack_require__(/*! ../internals/ie8-dom-define */ \"./node_modules/core-js/internals/ie8-dom-define.js\");\n\nvar nativeGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n\nexports.f = DESCRIPTORS ? nativeGetOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {\n O = toIndexedObject(O);\n P = toPrimitive(P, true);\n if (IE8_DOM_DEFINE) try {\n return nativeGetOwnPropertyDescriptor(O, P);\n } catch (error) { /* empty */ }\n if (has(O, P)) return createPropertyDescriptor(!propertyIsEnumerableModule.f.call(O, P), O[P]);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvb2JqZWN0LWdldC1vd24tcHJvcGVydHktZGVzY3JpcHRvci5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL29iamVjdC1nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3IuanM/MDZjZiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgREVTQ1JJUFRPUlMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZGVzY3JpcHRvcnMnKTtcbnZhciBwcm9wZXJ0eUlzRW51bWVyYWJsZU1vZHVsZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9vYmplY3QtcHJvcGVydHktaXMtZW51bWVyYWJsZScpO1xudmFyIGNyZWF0ZVByb3BlcnR5RGVzY3JpcHRvciA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9jcmVhdGUtcHJvcGVydHktZGVzY3JpcHRvcicpO1xudmFyIHRvSW5kZXhlZE9iamVjdCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy90by1pbmRleGVkLW9iamVjdCcpO1xudmFyIHRvUHJpbWl0aXZlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3RvLXByaW1pdGl2ZScpO1xudmFyIGhhcyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9oYXMnKTtcbnZhciBJRThfRE9NX0RFRklORSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9pZTgtZG9tLWRlZmluZScpO1xuXG52YXIgbmF0aXZlR2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcblxuZXhwb3J0cy5mID0gREVTQ1JJUFRPUlMgPyBuYXRpdmVHZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgOiBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoTywgUCkge1xuICBPID0gdG9JbmRleGVkT2JqZWN0KE8pO1xuICBQID0gdG9QcmltaXRpdmUoUCwgdHJ1ZSk7XG4gIGlmIChJRThfRE9NX0RFRklORSkgdHJ5IHtcbiAgICByZXR1cm4gbmF0aXZlR2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKE8sIFApO1xuICB9IGNhdGNoIChlcnJvcikgeyAvKiBlbXB0eSAqLyB9XG4gIGlmIChoYXMoTywgUCkpIHJldHVybiBjcmVhdGVQcm9wZXJ0eURlc2NyaXB0b3IoIXByb3BlcnR5SXNFbnVtZXJhYmxlTW9kdWxlLmYuY2FsbChPLCBQKSwgT1tQXSk7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/object-get-own-property-descriptor.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/object-get-own-property-names.js": +/*!*************************************************************************!*\ + !*** ./node_modules/core-js/internals/object-get-own-property-names.js ***! + \*************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O)\nvar internalObjectKeys = __webpack_require__(/*! ../internals/object-keys-internal */ \"./node_modules/core-js/internals/object-keys-internal.js\");\nvar enumBugKeys = __webpack_require__(/*! ../internals/enum-bug-keys */ \"./node_modules/core-js/internals/enum-bug-keys.js\");\n\nvar hiddenKeys = enumBugKeys.concat('length', 'prototype');\n\nexports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {\n return internalObjectKeys(O, hiddenKeys);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvb2JqZWN0LWdldC1vd24tcHJvcGVydHktbmFtZXMuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9vYmplY3QtZ2V0LW93bi1wcm9wZXJ0eS1uYW1lcy5qcz8yNDFjIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIDE5LjEuMi43IC8gMTUuMi4zLjQgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoTylcbnZhciBpbnRlcm5hbE9iamVjdEtleXMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvb2JqZWN0LWtleXMtaW50ZXJuYWwnKTtcbnZhciBlbnVtQnVnS2V5cyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9lbnVtLWJ1Zy1rZXlzJyk7XG5cbnZhciBoaWRkZW5LZXlzID0gZW51bUJ1Z0tleXMuY29uY2F0KCdsZW5ndGgnLCAncHJvdG90eXBlJyk7XG5cbmV4cG9ydHMuZiA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzIHx8IGZ1bmN0aW9uIGdldE93blByb3BlcnR5TmFtZXMoTykge1xuICByZXR1cm4gaW50ZXJuYWxPYmplY3RLZXlzKE8sIGhpZGRlbktleXMpO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/object-get-own-property-names.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/object-get-own-property-symbols.js": +/*!***************************************************************************!*\ + !*** ./node_modules/core-js/internals/object-get-own-property-symbols.js ***! + \***************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("exports.f = Object.getOwnPropertySymbols;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvb2JqZWN0LWdldC1vd24tcHJvcGVydHktc3ltYm9scy5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL29iamVjdC1nZXQtb3duLXByb3BlcnR5LXN5bWJvbHMuanM/NzQxOCJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnRzLmYgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/object-get-own-property-symbols.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/object-get-prototype-of.js": +/*!*******************************************************************!*\ + !*** ./node_modules/core-js/internals/object-get-prototype-of.js ***! + \*******************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var has = __webpack_require__(/*! ../internals/has */ \"./node_modules/core-js/internals/has.js\");\nvar toObject = __webpack_require__(/*! ../internals/to-object */ \"./node_modules/core-js/internals/to-object.js\");\nvar sharedKey = __webpack_require__(/*! ../internals/shared-key */ \"./node_modules/core-js/internals/shared-key.js\");\nvar CORRECT_PROTOTYPE_GETTER = __webpack_require__(/*! ../internals/correct-prototype-getter */ \"./node_modules/core-js/internals/correct-prototype-getter.js\");\n\nvar IE_PROTO = sharedKey('IE_PROTO');\nvar ObjectPrototype = Object.prototype;\n\n// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)\nmodule.exports = CORRECT_PROTOTYPE_GETTER ? Object.getPrototypeOf : function (O) {\n O = toObject(O);\n if (has(O, IE_PROTO)) return O[IE_PROTO];\n if (typeof O.constructor == 'function' && O instanceof O.constructor) {\n return O.constructor.prototype;\n } return O instanceof Object ? ObjectPrototype : null;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvb2JqZWN0LWdldC1wcm90b3R5cGUtb2YuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9vYmplY3QtZ2V0LXByb3RvdHlwZS1vZi5qcz9lMTYzIl0sInNvdXJjZXNDb250ZW50IjpbInZhciBoYXMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaGFzJyk7XG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvdG8tb2JqZWN0Jyk7XG52YXIgc2hhcmVkS2V5ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3NoYXJlZC1rZXknKTtcbnZhciBDT1JSRUNUX1BST1RPVFlQRV9HRVRURVIgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvY29ycmVjdC1wcm90b3R5cGUtZ2V0dGVyJyk7XG5cbnZhciBJRV9QUk9UTyA9IHNoYXJlZEtleSgnSUVfUFJPVE8nKTtcbnZhciBPYmplY3RQcm90b3R5cGUgPSBPYmplY3QucHJvdG90eXBlO1xuXG4vLyAxOS4xLjIuOSAvIDE1LjIuMy4yIE9iamVjdC5nZXRQcm90b3R5cGVPZihPKVxubW9kdWxlLmV4cG9ydHMgPSBDT1JSRUNUX1BST1RPVFlQRV9HRVRURVIgPyBPYmplY3QuZ2V0UHJvdG90eXBlT2YgOiBmdW5jdGlvbiAoTykge1xuICBPID0gdG9PYmplY3QoTyk7XG4gIGlmIChoYXMoTywgSUVfUFJPVE8pKSByZXR1cm4gT1tJRV9QUk9UT107XG4gIGlmICh0eXBlb2YgTy5jb25zdHJ1Y3RvciA9PSAnZnVuY3Rpb24nICYmIE8gaW5zdGFuY2VvZiBPLmNvbnN0cnVjdG9yKSB7XG4gICAgcmV0dXJuIE8uY29uc3RydWN0b3IucHJvdG90eXBlO1xuICB9IHJldHVybiBPIGluc3RhbmNlb2YgT2JqZWN0ID8gT2JqZWN0UHJvdG90eXBlIDogbnVsbDtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/object-get-prototype-of.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/object-keys-internal.js": +/*!****************************************************************!*\ + !*** ./node_modules/core-js/internals/object-keys-internal.js ***! + \****************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var has = __webpack_require__(/*! ../internals/has */ \"./node_modules/core-js/internals/has.js\");\nvar toIndexedObject = __webpack_require__(/*! ../internals/to-indexed-object */ \"./node_modules/core-js/internals/to-indexed-object.js\");\nvar arrayIncludes = __webpack_require__(/*! ../internals/array-includes */ \"./node_modules/core-js/internals/array-includes.js\");\nvar hiddenKeys = __webpack_require__(/*! ../internals/hidden-keys */ \"./node_modules/core-js/internals/hidden-keys.js\");\n\nvar arrayIndexOf = arrayIncludes(false);\n\nmodule.exports = function (object, names) {\n var O = toIndexedObject(object);\n var i = 0;\n var result = [];\n var key;\n for (key in O) !has(hiddenKeys, key) && has(O, key) && result.push(key);\n // Don't enum bug & hidden keys\n while (names.length > i) if (has(O, key = names[i++])) {\n ~arrayIndexOf(result, key) || result.push(key);\n }\n return result;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvb2JqZWN0LWtleXMtaW50ZXJuYWwuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9vYmplY3Qta2V5cy1pbnRlcm5hbC5qcz9jYTg0Il0sInNvdXJjZXNDb250ZW50IjpbInZhciBoYXMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaGFzJyk7XG52YXIgdG9JbmRleGVkT2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3RvLWluZGV4ZWQtb2JqZWN0Jyk7XG52YXIgYXJyYXlJbmNsdWRlcyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9hcnJheS1pbmNsdWRlcycpO1xudmFyIGhpZGRlbktleXMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaGlkZGVuLWtleXMnKTtcblxudmFyIGFycmF5SW5kZXhPZiA9IGFycmF5SW5jbHVkZXMoZmFsc2UpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWVzKSB7XG4gIHZhciBPID0gdG9JbmRleGVkT2JqZWN0KG9iamVjdCk7XG4gIHZhciBpID0gMDtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICB2YXIga2V5O1xuICBmb3IgKGtleSBpbiBPKSAhaGFzKGhpZGRlbktleXMsIGtleSkgJiYgaGFzKE8sIGtleSkgJiYgcmVzdWx0LnB1c2goa2V5KTtcbiAgLy8gRG9uJ3QgZW51bSBidWcgJiBoaWRkZW4ga2V5c1xuICB3aGlsZSAobmFtZXMubGVuZ3RoID4gaSkgaWYgKGhhcyhPLCBrZXkgPSBuYW1lc1tpKytdKSkge1xuICAgIH5hcnJheUluZGV4T2YocmVzdWx0LCBrZXkpIHx8IHJlc3VsdC5wdXNoKGtleSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/object-keys-internal.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/object-keys.js": +/*!*******************************************************!*\ + !*** ./node_modules/core-js/internals/object-keys.js ***! + \*******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var internalObjectKeys = __webpack_require__(/*! ../internals/object-keys-internal */ \"./node_modules/core-js/internals/object-keys-internal.js\");\nvar enumBugKeys = __webpack_require__(/*! ../internals/enum-bug-keys */ \"./node_modules/core-js/internals/enum-bug-keys.js\");\n\n// 19.1.2.14 / 15.2.3.14 Object.keys(O)\nmodule.exports = Object.keys || function keys(O) {\n return internalObjectKeys(O, enumBugKeys);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvb2JqZWN0LWtleXMuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9vYmplY3Qta2V5cy5qcz9kZjc1Il0sInNvdXJjZXNDb250ZW50IjpbInZhciBpbnRlcm5hbE9iamVjdEtleXMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvb2JqZWN0LWtleXMtaW50ZXJuYWwnKTtcbnZhciBlbnVtQnVnS2V5cyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9lbnVtLWJ1Zy1rZXlzJyk7XG5cbi8vIDE5LjEuMi4xNCAvIDE1LjIuMy4xNCBPYmplY3Qua2V5cyhPKVxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiBrZXlzKE8pIHtcbiAgcmV0dXJuIGludGVybmFsT2JqZWN0S2V5cyhPLCBlbnVtQnVnS2V5cyk7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/object-keys.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/object-property-is-enumerable.js": +/*!*************************************************************************!*\ + !*** ./node_modules/core-js/internals/object-property-is-enumerable.js ***! + \*************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar nativePropertyIsEnumerable = {}.propertyIsEnumerable;\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n\n// Nashorn ~ JDK8 bug\nvar NASHORN_BUG = getOwnPropertyDescriptor && !nativePropertyIsEnumerable.call({ 1: 2 }, 1);\n\nexports.f = NASHORN_BUG ? function propertyIsEnumerable(V) {\n var descriptor = getOwnPropertyDescriptor(this, V);\n return !!descriptor && descriptor.enumerable;\n} : nativePropertyIsEnumerable;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvb2JqZWN0LXByb3BlcnR5LWlzLWVudW1lcmFibGUuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9vYmplY3QtcHJvcGVydHktaXMtZW51bWVyYWJsZS5qcz9kMWU3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcbnZhciBuYXRpdmVQcm9wZXJ0eUlzRW51bWVyYWJsZSA9IHt9LnByb3BlcnR5SXNFbnVtZXJhYmxlO1xudmFyIGdldE93blByb3BlcnR5RGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG5cbi8vIE5hc2hvcm4gfiBKREs4IGJ1Z1xudmFyIE5BU0hPUk5fQlVHID0gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yICYmICFuYXRpdmVQcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHsgMTogMiB9LCAxKTtcblxuZXhwb3J0cy5mID0gTkFTSE9STl9CVUcgPyBmdW5jdGlvbiBwcm9wZXJ0eUlzRW51bWVyYWJsZShWKSB7XG4gIHZhciBkZXNjcmlwdG9yID0gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRoaXMsIFYpO1xuICByZXR1cm4gISFkZXNjcmlwdG9yICYmIGRlc2NyaXB0b3IuZW51bWVyYWJsZTtcbn0gOiBuYXRpdmVQcm9wZXJ0eUlzRW51bWVyYWJsZTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/object-property-is-enumerable.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/object-set-prototype-of.js": +/*!*******************************************************************!*\ + !*** ./node_modules/core-js/internals/object-set-prototype-of.js ***! + \*******************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var validateSetPrototypeOfArguments = __webpack_require__(/*! ../internals/validate-set-prototype-of-arguments */ \"./node_modules/core-js/internals/validate-set-prototype-of-arguments.js\");\n\n// Works with __proto__ only. Old v8 can't work with null proto objects.\n/* eslint-disable no-proto */\nmodule.exports = Object.setPrototypeOf || ('__proto__' in {} ? function () {\n var correctSetter = false;\n var test = {};\n var setter;\n try {\n setter = Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').set;\n setter.call(test, []);\n correctSetter = test instanceof Array;\n } catch (error) { /* empty */ }\n return function setPrototypeOf(O, proto) {\n validateSetPrototypeOfArguments(O, proto);\n if (correctSetter) setter.call(O, proto);\n else O.__proto__ = proto;\n return O;\n };\n}() : undefined);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvb2JqZWN0LXNldC1wcm90b3R5cGUtb2YuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9vYmplY3Qtc2V0LXByb3RvdHlwZS1vZi5qcz9kMmJiIl0sInNvdXJjZXNDb250ZW50IjpbInZhciB2YWxpZGF0ZVNldFByb3RvdHlwZU9mQXJndW1lbnRzID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3ZhbGlkYXRlLXNldC1wcm90b3R5cGUtb2YtYXJndW1lbnRzJyk7XG5cbi8vIFdvcmtzIHdpdGggX19wcm90b19fIG9ubHkuIE9sZCB2OCBjYW4ndCB3b3JrIHdpdGggbnVsbCBwcm90byBvYmplY3RzLlxuLyogZXNsaW50LWRpc2FibGUgbm8tcHJvdG8gKi9cbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8ICgnX19wcm90b19fJyBpbiB7fSA/IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGNvcnJlY3RTZXR0ZXIgPSBmYWxzZTtcbiAgdmFyIHRlc3QgPSB7fTtcbiAgdmFyIHNldHRlcjtcbiAgdHJ5IHtcbiAgICBzZXR0ZXIgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKE9iamVjdC5wcm90b3R5cGUsICdfX3Byb3RvX18nKS5zZXQ7XG4gICAgc2V0dGVyLmNhbGwodGVzdCwgW10pO1xuICAgIGNvcnJlY3RTZXR0ZXIgPSB0ZXN0IGluc3RhbmNlb2YgQXJyYXk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7IC8qIGVtcHR5ICovIH1cbiAgcmV0dXJuIGZ1bmN0aW9uIHNldFByb3RvdHlwZU9mKE8sIHByb3RvKSB7XG4gICAgdmFsaWRhdGVTZXRQcm90b3R5cGVPZkFyZ3VtZW50cyhPLCBwcm90byk7XG4gICAgaWYgKGNvcnJlY3RTZXR0ZXIpIHNldHRlci5jYWxsKE8sIHByb3RvKTtcbiAgICBlbHNlIE8uX19wcm90b19fID0gcHJvdG87XG4gICAgcmV0dXJuIE87XG4gIH07XG59KCkgOiB1bmRlZmluZWQpO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/object-set-prototype-of.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/object-to-string.js": +/*!************************************************************!*\ + !*** ./node_modules/core-js/internals/object-to-string.js ***! + \************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar classof = __webpack_require__(/*! ../internals/classof */ \"./node_modules/core-js/internals/classof.js\");\nvar wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ \"./node_modules/core-js/internals/well-known-symbol.js\");\n\nvar TO_STRING_TAG = wellKnownSymbol('toStringTag');\nvar test = {};\n\ntest[TO_STRING_TAG] = 'z';\n\n// `Object.prototype.toString` method implementation\n// https://tc39.github.io/ecma262/#sec-object.prototype.tostring\nmodule.exports = String(test) !== '[object z]' ? function toString() {\n return '[object ' + classof(this) + ']';\n} : test.toString;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvb2JqZWN0LXRvLXN0cmluZy5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL29iamVjdC10by1zdHJpbmcuanM/YjA0MSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG52YXIgY2xhc3NvZiA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9jbGFzc29mJyk7XG52YXIgd2VsbEtub3duU3ltYm9sID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3dlbGwta25vd24tc3ltYm9sJyk7XG5cbnZhciBUT19TVFJJTkdfVEFHID0gd2VsbEtub3duU3ltYm9sKCd0b1N0cmluZ1RhZycpO1xudmFyIHRlc3QgPSB7fTtcblxudGVzdFtUT19TVFJJTkdfVEFHXSA9ICd6JztcblxuLy8gYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmdgIG1ldGhvZCBpbXBsZW1lbnRhdGlvblxuLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZ1xubW9kdWxlLmV4cG9ydHMgPSBTdHJpbmcodGVzdCkgIT09ICdbb2JqZWN0IHpdJyA/IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICByZXR1cm4gJ1tvYmplY3QgJyArIGNsYXNzb2YodGhpcykgKyAnXSc7XG59IDogdGVzdC50b1N0cmluZztcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/object-to-string.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/own-keys.js": +/*!****************************************************!*\ + !*** ./node_modules/core-js/internals/own-keys.js ***! + \****************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var global = __webpack_require__(/*! ../internals/global */ \"./node_modules/core-js/internals/global.js\");\nvar getOwnPropertyNamesModule = __webpack_require__(/*! ../internals/object-get-own-property-names */ \"./node_modules/core-js/internals/object-get-own-property-names.js\");\nvar getOwnPropertySymbolsModule = __webpack_require__(/*! ../internals/object-get-own-property-symbols */ \"./node_modules/core-js/internals/object-get-own-property-symbols.js\");\nvar anObject = __webpack_require__(/*! ../internals/an-object */ \"./node_modules/core-js/internals/an-object.js\");\n\nvar Reflect = global.Reflect;\n\n// all object keys, includes non-enumerable and symbols\nmodule.exports = Reflect && Reflect.ownKeys || function ownKeys(it) {\n var keys = getOwnPropertyNamesModule.f(anObject(it));\n var getOwnPropertySymbols = getOwnPropertySymbolsModule.f;\n return getOwnPropertySymbols ? keys.concat(getOwnPropertySymbols(it)) : keys;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvb3duLWtleXMuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9vd24ta2V5cy5qcz81NmVmIl0sInNvdXJjZXNDb250ZW50IjpbInZhciBnbG9iYWwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZ2xvYmFsJyk7XG52YXIgZ2V0T3duUHJvcGVydHlOYW1lc01vZHVsZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9vYmplY3QtZ2V0LW93bi1wcm9wZXJ0eS1uYW1lcycpO1xudmFyIGdldE93blByb3BlcnR5U3ltYm9sc01vZHVsZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9vYmplY3QtZ2V0LW93bi1wcm9wZXJ0eS1zeW1ib2xzJyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvYW4tb2JqZWN0Jyk7XG5cbnZhciBSZWZsZWN0ID0gZ2xvYmFsLlJlZmxlY3Q7XG5cbi8vIGFsbCBvYmplY3Qga2V5cywgaW5jbHVkZXMgbm9uLWVudW1lcmFibGUgYW5kIHN5bWJvbHNcbm1vZHVsZS5leHBvcnRzID0gUmVmbGVjdCAmJiBSZWZsZWN0Lm93bktleXMgfHwgZnVuY3Rpb24gb3duS2V5cyhpdCkge1xuICB2YXIga2V5cyA9IGdldE93blByb3BlcnR5TmFtZXNNb2R1bGUuZihhbk9iamVjdChpdCkpO1xuICB2YXIgZ2V0T3duUHJvcGVydHlTeW1ib2xzID0gZ2V0T3duUHJvcGVydHlTeW1ib2xzTW9kdWxlLmY7XG4gIHJldHVybiBnZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPyBrZXlzLmNvbmNhdChnZXRPd25Qcm9wZXJ0eVN5bWJvbHMoaXQpKSA6IGtleXM7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/own-keys.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/path.js": +/*!************************************************!*\ + !*** ./node_modules/core-js/internals/path.js ***! + \************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("module.exports = __webpack_require__(/*! ../internals/global */ \"./node_modules/core-js/internals/global.js\");\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvcGF0aC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL3BhdGguanM/NDI4ZiJdLCJzb3VyY2VzQ29udGVudCI6WyJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9nbG9iYWwnKTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/path.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/perform.js": +/*!***************************************************!*\ + !*** ./node_modules/core-js/internals/perform.js ***! + \***************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("module.exports = function (exec) {\n try {\n return { error: false, value: exec() };\n } catch (error) {\n return { error: true, value: error };\n }\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvcGVyZm9ybS5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL3BlcmZvcm0uanM/ZTY2NyJdLCJzb3VyY2VzQ29udGVudCI6WyJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChleGVjKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHsgZXJyb3I6IGZhbHNlLCB2YWx1ZTogZXhlYygpIH07XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmV0dXJuIHsgZXJyb3I6IHRydWUsIHZhbHVlOiBlcnJvciB9O1xuICB9XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/perform.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/promise-resolve.js": +/*!***********************************************************!*\ + !*** ./node_modules/core-js/internals/promise-resolve.js ***! + \***********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var anObject = __webpack_require__(/*! ../internals/an-object */ \"./node_modules/core-js/internals/an-object.js\");\nvar isObject = __webpack_require__(/*! ../internals/is-object */ \"./node_modules/core-js/internals/is-object.js\");\nvar newPromiseCapability = __webpack_require__(/*! ../internals/new-promise-capability */ \"./node_modules/core-js/internals/new-promise-capability.js\");\n\nmodule.exports = function (C, x) {\n anObject(C);\n if (isObject(x) && x.constructor === C) return x;\n var promiseCapability = newPromiseCapability.f(C);\n var resolve = promiseCapability.resolve;\n resolve(x);\n return promiseCapability.promise;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvcHJvbWlzZS1yZXNvbHZlLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvcHJvbWlzZS1yZXNvbHZlLmpzP2NkZjkiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2FuLW9iamVjdCcpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2lzLW9iamVjdCcpO1xudmFyIG5ld1Byb21pc2VDYXBhYmlsaXR5ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL25ldy1wcm9taXNlLWNhcGFiaWxpdHknKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoQywgeCkge1xuICBhbk9iamVjdChDKTtcbiAgaWYgKGlzT2JqZWN0KHgpICYmIHguY29uc3RydWN0b3IgPT09IEMpIHJldHVybiB4O1xuICB2YXIgcHJvbWlzZUNhcGFiaWxpdHkgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eS5mKEMpO1xuICB2YXIgcmVzb2x2ZSA9IHByb21pc2VDYXBhYmlsaXR5LnJlc29sdmU7XG4gIHJlc29sdmUoeCk7XG4gIHJldHVybiBwcm9taXNlQ2FwYWJpbGl0eS5wcm9taXNlO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/promise-resolve.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/redefine-all.js": +/*!********************************************************!*\ + !*** ./node_modules/core-js/internals/redefine-all.js ***! + \********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var redefine = __webpack_require__(/*! ../internals/redefine */ \"./node_modules/core-js/internals/redefine.js\");\n\nmodule.exports = function (target, src, options) {\n for (var key in src) redefine(target, key, src[key], options);\n return target;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvcmVkZWZpbmUtYWxsLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvcmVkZWZpbmUtYWxsLmpzP2UyY2MiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIHJlZGVmaW5lID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3JlZGVmaW5lJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHRhcmdldCwgc3JjLCBvcHRpb25zKSB7XG4gIGZvciAodmFyIGtleSBpbiBzcmMpIHJlZGVmaW5lKHRhcmdldCwga2V5LCBzcmNba2V5XSwgb3B0aW9ucyk7XG4gIHJldHVybiB0YXJnZXQ7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/redefine-all.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/redefine.js": +/*!****************************************************!*\ + !*** ./node_modules/core-js/internals/redefine.js ***! + \****************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var global = __webpack_require__(/*! ../internals/global */ \"./node_modules/core-js/internals/global.js\");\nvar shared = __webpack_require__(/*! ../internals/shared */ \"./node_modules/core-js/internals/shared.js\");\nvar hide = __webpack_require__(/*! ../internals/hide */ \"./node_modules/core-js/internals/hide.js\");\nvar has = __webpack_require__(/*! ../internals/has */ \"./node_modules/core-js/internals/has.js\");\nvar setGlobal = __webpack_require__(/*! ../internals/set-global */ \"./node_modules/core-js/internals/set-global.js\");\nvar nativeFunctionToString = __webpack_require__(/*! ../internals/function-to-string */ \"./node_modules/core-js/internals/function-to-string.js\");\nvar InternalStateModule = __webpack_require__(/*! ../internals/internal-state */ \"./node_modules/core-js/internals/internal-state.js\");\n\nvar getInternalState = InternalStateModule.get;\nvar enforceInternalState = InternalStateModule.enforce;\nvar TEMPLATE = String(nativeFunctionToString).split('toString');\n\nshared('inspectSource', function (it) {\n return nativeFunctionToString.call(it);\n});\n\n(module.exports = function (O, key, value, options) {\n var unsafe = options ? !!options.unsafe : false;\n var simple = options ? !!options.enumerable : false;\n var noTargetGet = options ? !!options.noTargetGet : false;\n if (typeof value == 'function') {\n if (typeof key == 'string' && !has(value, 'name')) hide(value, 'name', key);\n enforceInternalState(value).source = TEMPLATE.join(typeof key == 'string' ? key : '');\n }\n if (O === global) {\n if (simple) O[key] = value;\n else setGlobal(key, value);\n return;\n } else if (!unsafe) {\n delete O[key];\n } else if (!noTargetGet && O[key]) {\n simple = true;\n }\n if (simple) O[key] = value;\n else hide(O, key, value);\n// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative\n})(Function.prototype, 'toString', function toString() {\n return typeof this == 'function' && getInternalState(this).source || nativeFunctionToString.call(this);\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvcmVkZWZpbmUuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9yZWRlZmluZS5qcz82ZWViIl0sInNvdXJjZXNDb250ZW50IjpbInZhciBnbG9iYWwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZ2xvYmFsJyk7XG52YXIgc2hhcmVkID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3NoYXJlZCcpO1xudmFyIGhpZGUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaGlkZScpO1xudmFyIGhhcyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9oYXMnKTtcbnZhciBzZXRHbG9iYWwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvc2V0LWdsb2JhbCcpO1xudmFyIG5hdGl2ZUZ1bmN0aW9uVG9TdHJpbmcgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZnVuY3Rpb24tdG8tc3RyaW5nJyk7XG52YXIgSW50ZXJuYWxTdGF0ZU1vZHVsZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9pbnRlcm5hbC1zdGF0ZScpO1xuXG52YXIgZ2V0SW50ZXJuYWxTdGF0ZSA9IEludGVybmFsU3RhdGVNb2R1bGUuZ2V0O1xudmFyIGVuZm9yY2VJbnRlcm5hbFN0YXRlID0gSW50ZXJuYWxTdGF0ZU1vZHVsZS5lbmZvcmNlO1xudmFyIFRFTVBMQVRFID0gU3RyaW5nKG5hdGl2ZUZ1bmN0aW9uVG9TdHJpbmcpLnNwbGl0KCd0b1N0cmluZycpO1xuXG5zaGFyZWQoJ2luc3BlY3RTb3VyY2UnLCBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIG5hdGl2ZUZ1bmN0aW9uVG9TdHJpbmcuY2FsbChpdCk7XG59KTtcblxuKG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKE8sIGtleSwgdmFsdWUsIG9wdGlvbnMpIHtcbiAgdmFyIHVuc2FmZSA9IG9wdGlvbnMgPyAhIW9wdGlvbnMudW5zYWZlIDogZmFsc2U7XG4gIHZhciBzaW1wbGUgPSBvcHRpb25zID8gISFvcHRpb25zLmVudW1lcmFibGUgOiBmYWxzZTtcbiAgdmFyIG5vVGFyZ2V0R2V0ID0gb3B0aW9ucyA/ICEhb3B0aW9ucy5ub1RhcmdldEdldCA6IGZhbHNlO1xuICBpZiAodHlwZW9mIHZhbHVlID09ICdmdW5jdGlvbicpIHtcbiAgICBpZiAodHlwZW9mIGtleSA9PSAnc3RyaW5nJyAmJiAhaGFzKHZhbHVlLCAnbmFtZScpKSBoaWRlKHZhbHVlLCAnbmFtZScsIGtleSk7XG4gICAgZW5mb3JjZUludGVybmFsU3RhdGUodmFsdWUpLnNvdXJjZSA9IFRFTVBMQVRFLmpvaW4odHlwZW9mIGtleSA9PSAnc3RyaW5nJyA/IGtleSA6ICcnKTtcbiAgfVxuICBpZiAoTyA9PT0gZ2xvYmFsKSB7XG4gICAgaWYgKHNpbXBsZSkgT1trZXldID0gdmFsdWU7XG4gICAgZWxzZSBzZXRHbG9iYWwoa2V5LCB2YWx1ZSk7XG4gICAgcmV0dXJuO1xuICB9IGVsc2UgaWYgKCF1bnNhZmUpIHtcbiAgICBkZWxldGUgT1trZXldO1xuICB9IGVsc2UgaWYgKCFub1RhcmdldEdldCAmJiBPW2tleV0pIHtcbiAgICBzaW1wbGUgPSB0cnVlO1xuICB9XG4gIGlmIChzaW1wbGUpIE9ba2V5XSA9IHZhbHVlO1xuICBlbHNlIGhpZGUoTywga2V5LCB2YWx1ZSk7XG4vLyBhZGQgZmFrZSBGdW5jdGlvbiN0b1N0cmluZyBmb3IgY29ycmVjdCB3b3JrIHdyYXBwZWQgbWV0aG9kcyAvIGNvbnN0cnVjdG9ycyB3aXRoIG1ldGhvZHMgbGlrZSBMb0Rhc2ggaXNOYXRpdmVcbn0pKEZ1bmN0aW9uLnByb3RvdHlwZSwgJ3RvU3RyaW5nJywgZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gIHJldHVybiB0eXBlb2YgdGhpcyA9PSAnZnVuY3Rpb24nICYmIGdldEludGVybmFsU3RhdGUodGhpcykuc291cmNlIHx8IG5hdGl2ZUZ1bmN0aW9uVG9TdHJpbmcuY2FsbCh0aGlzKTtcbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/redefine.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/regexp-exec-abstract.js": +/*!****************************************************************!*\ + !*** ./node_modules/core-js/internals/regexp-exec-abstract.js ***! + \****************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var classof = __webpack_require__(/*! ./classof-raw */ \"./node_modules/core-js/internals/classof-raw.js\");\nvar regexpExec = __webpack_require__(/*! ./regexp-exec */ \"./node_modules/core-js/internals/regexp-exec.js\");\n\n// `RegExpExec` abstract operation\n// https://tc39.github.io/ecma262/#sec-regexpexec\nmodule.exports = function (R, S) {\n var exec = R.exec;\n if (typeof exec === 'function') {\n var result = exec.call(R, S);\n if (typeof result !== 'object') {\n throw TypeError('RegExp exec method returned something other than an Object or null');\n }\n return result;\n }\n\n if (classof(R) !== 'RegExp') {\n throw TypeError('RegExp#exec called on incompatible receiver');\n }\n\n return regexpExec.call(R, S);\n};\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvcmVnZXhwLWV4ZWMtYWJzdHJhY3QuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9yZWdleHAtZXhlYy1hYnN0cmFjdC5qcz8xNGMzIl0sInNvdXJjZXNDb250ZW50IjpbInZhciBjbGFzc29mID0gcmVxdWlyZSgnLi9jbGFzc29mLXJhdycpO1xudmFyIHJlZ2V4cEV4ZWMgPSByZXF1aXJlKCcuL3JlZ2V4cC1leGVjJyk7XG5cbi8vIGBSZWdFeHBFeGVjYCBhYnN0cmFjdCBvcGVyYXRpb25cbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXJlZ2V4cGV4ZWNcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKFIsIFMpIHtcbiAgdmFyIGV4ZWMgPSBSLmV4ZWM7XG4gIGlmICh0eXBlb2YgZXhlYyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHZhciByZXN1bHQgPSBleGVjLmNhbGwoUiwgUyk7XG4gICAgaWYgKHR5cGVvZiByZXN1bHQgIT09ICdvYmplY3QnKSB7XG4gICAgICB0aHJvdyBUeXBlRXJyb3IoJ1JlZ0V4cCBleGVjIG1ldGhvZCByZXR1cm5lZCBzb21ldGhpbmcgb3RoZXIgdGhhbiBhbiBPYmplY3Qgb3IgbnVsbCcpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgaWYgKGNsYXNzb2YoUikgIT09ICdSZWdFeHAnKSB7XG4gICAgdGhyb3cgVHlwZUVycm9yKCdSZWdFeHAjZXhlYyBjYWxsZWQgb24gaW5jb21wYXRpYmxlIHJlY2VpdmVyJyk7XG4gIH1cblxuICByZXR1cm4gcmVnZXhwRXhlYy5jYWxsKFIsIFMpO1xufTtcblxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/regexp-exec-abstract.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/regexp-exec.js": +/*!*******************************************************!*\ + !*** ./node_modules/core-js/internals/regexp-exec.js ***! + \*******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar regexpFlags = __webpack_require__(/*! ./regexp-flags */ \"./node_modules/core-js/internals/regexp-flags.js\");\n\nvar nativeExec = RegExp.prototype.exec;\n// This always refers to the native implementation, because the\n// String#replace polyfill uses ./fix-regexp-well-known-symbol-logic.js,\n// which loads this file before patching the method.\nvar nativeReplace = String.prototype.replace;\n\nvar patchedExec = nativeExec;\n\nvar UPDATES_LAST_INDEX_WRONG = (function () {\n var re1 = /a/;\n var re2 = /b*/g;\n nativeExec.call(re1, 'a');\n nativeExec.call(re2, 'a');\n return re1.lastIndex !== 0 || re2.lastIndex !== 0;\n})();\n\n// nonparticipating capturing group, copied from es5-shim's String#split patch.\nvar NPCG_INCLUDED = /()??/.exec('')[1] !== undefined;\n\nvar PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED;\n\nif (PATCH) {\n patchedExec = function exec(str) {\n var re = this;\n var lastIndex, reCopy, match, i;\n\n if (NPCG_INCLUDED) {\n reCopy = new RegExp('^' + re.source + '$(?!\\\\s)', regexpFlags.call(re));\n }\n if (UPDATES_LAST_INDEX_WRONG) lastIndex = re.lastIndex;\n\n match = nativeExec.call(re, str);\n\n if (UPDATES_LAST_INDEX_WRONG && match) {\n re.lastIndex = re.global ? match.index + match[0].length : lastIndex;\n }\n if (NPCG_INCLUDED && match && match.length > 1) {\n // Fix browsers whose `exec` methods don't consistently return `undefined`\n // for NPCG, like IE8. NOTE: This doesn' work for /(.?)?/\n nativeReplace.call(match[0], reCopy, function () {\n for (i = 1; i < arguments.length - 2; i++) {\n if (arguments[i] === undefined) match[i] = undefined;\n }\n });\n }\n\n return match;\n };\n}\n\nmodule.exports = patchedExec;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvcmVnZXhwLWV4ZWMuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9yZWdleHAtZXhlYy5qcz85MjYzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcbnZhciByZWdleHBGbGFncyA9IHJlcXVpcmUoJy4vcmVnZXhwLWZsYWdzJyk7XG5cbnZhciBuYXRpdmVFeGVjID0gUmVnRXhwLnByb3RvdHlwZS5leGVjO1xuLy8gVGhpcyBhbHdheXMgcmVmZXJzIHRvIHRoZSBuYXRpdmUgaW1wbGVtZW50YXRpb24sIGJlY2F1c2UgdGhlXG4vLyBTdHJpbmcjcmVwbGFjZSBwb2x5ZmlsbCB1c2VzIC4vZml4LXJlZ2V4cC13ZWxsLWtub3duLXN5bWJvbC1sb2dpYy5qcyxcbi8vIHdoaWNoIGxvYWRzIHRoaXMgZmlsZSBiZWZvcmUgcGF0Y2hpbmcgdGhlIG1ldGhvZC5cbnZhciBuYXRpdmVSZXBsYWNlID0gU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlO1xuXG52YXIgcGF0Y2hlZEV4ZWMgPSBuYXRpdmVFeGVjO1xuXG52YXIgVVBEQVRFU19MQVNUX0lOREVYX1dST05HID0gKGZ1bmN0aW9uICgpIHtcbiAgdmFyIHJlMSA9IC9hLztcbiAgdmFyIHJlMiA9IC9iKi9nO1xuICBuYXRpdmVFeGVjLmNhbGwocmUxLCAnYScpO1xuICBuYXRpdmVFeGVjLmNhbGwocmUyLCAnYScpO1xuICByZXR1cm4gcmUxLmxhc3RJbmRleCAhPT0gMCB8fCByZTIubGFzdEluZGV4ICE9PSAwO1xufSkoKTtcblxuLy8gbm9ucGFydGljaXBhdGluZyBjYXB0dXJpbmcgZ3JvdXAsIGNvcGllZCBmcm9tIGVzNS1zaGltJ3MgU3RyaW5nI3NwbGl0IHBhdGNoLlxudmFyIE5QQ0dfSU5DTFVERUQgPSAvKCk/Py8uZXhlYygnJylbMV0gIT09IHVuZGVmaW5lZDtcblxudmFyIFBBVENIID0gVVBEQVRFU19MQVNUX0lOREVYX1dST05HIHx8IE5QQ0dfSU5DTFVERUQ7XG5cbmlmIChQQVRDSCkge1xuICBwYXRjaGVkRXhlYyA9IGZ1bmN0aW9uIGV4ZWMoc3RyKSB7XG4gICAgdmFyIHJlID0gdGhpcztcbiAgICB2YXIgbGFzdEluZGV4LCByZUNvcHksIG1hdGNoLCBpO1xuXG4gICAgaWYgKE5QQ0dfSU5DTFVERUQpIHtcbiAgICAgIHJlQ29weSA9IG5ldyBSZWdFeHAoJ14nICsgcmUuc291cmNlICsgJyQoPyFcXFxccyknLCByZWdleHBGbGFncy5jYWxsKHJlKSk7XG4gICAgfVxuICAgIGlmIChVUERBVEVTX0xBU1RfSU5ERVhfV1JPTkcpIGxhc3RJbmRleCA9IHJlLmxhc3RJbmRleDtcblxuICAgIG1hdGNoID0gbmF0aXZlRXhlYy5jYWxsKHJlLCBzdHIpO1xuXG4gICAgaWYgKFVQREFURVNfTEFTVF9JTkRFWF9XUk9ORyAmJiBtYXRjaCkge1xuICAgICAgcmUubGFzdEluZGV4ID0gcmUuZ2xvYmFsID8gbWF0Y2guaW5kZXggKyBtYXRjaFswXS5sZW5ndGggOiBsYXN0SW5kZXg7XG4gICAgfVxuICAgIGlmIChOUENHX0lOQ0xVREVEICYmIG1hdGNoICYmIG1hdGNoLmxlbmd0aCA+IDEpIHtcbiAgICAgIC8vIEZpeCBicm93c2VycyB3aG9zZSBgZXhlY2AgbWV0aG9kcyBkb24ndCBjb25zaXN0ZW50bHkgcmV0dXJuIGB1bmRlZmluZWRgXG4gICAgICAvLyBmb3IgTlBDRywgbGlrZSBJRTguIE5PVEU6IFRoaXMgZG9lc24nIHdvcmsgZm9yIC8oLj8pPy9cbiAgICAgIG5hdGl2ZVJlcGxhY2UuY2FsbChtYXRjaFswXSwgcmVDb3B5LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGZvciAoaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoIC0gMjsgaSsrKSB7XG4gICAgICAgICAgaWYgKGFyZ3VtZW50c1tpXSA9PT0gdW5kZWZpbmVkKSBtYXRjaFtpXSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1hdGNoO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHBhdGNoZWRFeGVjO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/regexp-exec.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/regexp-flags.js": +/*!********************************************************!*\ + !*** ./node_modules/core-js/internals/regexp-flags.js ***! + \********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar anObject = __webpack_require__(/*! ../internals/an-object */ \"./node_modules/core-js/internals/an-object.js\");\n\n// `RegExp.prototype.flags` getter implementation\n// https://tc39.github.io/ecma262/#sec-get-regexp.prototype.flags\nmodule.exports = function () {\n var that = anObject(this);\n var result = '';\n if (that.global) result += 'g';\n if (that.ignoreCase) result += 'i';\n if (that.multiline) result += 'm';\n if (that.unicode) result += 'u';\n if (that.sticky) result += 'y';\n return result;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvcmVnZXhwLWZsYWdzLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvcmVnZXhwLWZsYWdzLmpzP2FkNmQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2FuLW9iamVjdCcpO1xuXG4vLyBgUmVnRXhwLnByb3RvdHlwZS5mbGFnc2AgZ2V0dGVyIGltcGxlbWVudGF0aW9uXG4vLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1nZXQtcmVnZXhwLnByb3RvdHlwZS5mbGFnc1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciB0aGF0ID0gYW5PYmplY3QodGhpcyk7XG4gIHZhciByZXN1bHQgPSAnJztcbiAgaWYgKHRoYXQuZ2xvYmFsKSByZXN1bHQgKz0gJ2cnO1xuICBpZiAodGhhdC5pZ25vcmVDYXNlKSByZXN1bHQgKz0gJ2knO1xuICBpZiAodGhhdC5tdWx0aWxpbmUpIHJlc3VsdCArPSAnbSc7XG4gIGlmICh0aGF0LnVuaWNvZGUpIHJlc3VsdCArPSAndSc7XG4gIGlmICh0aGF0LnN0aWNreSkgcmVzdWx0ICs9ICd5JztcbiAgcmV0dXJuIHJlc3VsdDtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/regexp-flags.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/require-object-coercible.js": +/*!********************************************************************!*\ + !*** ./node_modules/core-js/internals/require-object-coercible.js ***! + \********************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("// `RequireObjectCoercible` abstract operation\n// https://tc39.github.io/ecma262/#sec-requireobjectcoercible\nmodule.exports = function (it) {\n if (it == undefined) throw TypeError(\"Can't call method on \" + it);\n return it;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvcmVxdWlyZS1vYmplY3QtY29lcmNpYmxlLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvcmVxdWlyZS1vYmplY3QtY29lcmNpYmxlLmpzPzFkODAiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gYFJlcXVpcmVPYmplY3RDb2VyY2libGVgIGFic3RyYWN0IG9wZXJhdGlvblxuLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtcmVxdWlyZW9iamVjdGNvZXJjaWJsZVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgaWYgKGl0ID09IHVuZGVmaW5lZCkgdGhyb3cgVHlwZUVycm9yKFwiQ2FuJ3QgY2FsbCBtZXRob2Qgb24gXCIgKyBpdCk7XG4gIHJldHVybiBpdDtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/require-object-coercible.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/same-value.js": +/*!******************************************************!*\ + !*** ./node_modules/core-js/internals/same-value.js ***! + \******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("// `SameValue` abstract operation\n// https://tc39.github.io/ecma262/#sec-samevalue\nmodule.exports = Object.is || function is(x, y) {\n // eslint-disable-next-line no-self-compare\n return x === y ? x !== 0 || 1 / x === 1 / y : x != x && y != y;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvc2FtZS12YWx1ZS5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL3NhbWUtdmFsdWUuanM/MTI5ZiJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBgU2FtZVZhbHVlYCBhYnN0cmFjdCBvcGVyYXRpb25cbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXNhbWV2YWx1ZVxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3QuaXMgfHwgZnVuY3Rpb24gaXMoeCwgeSkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gIHJldHVybiB4ID09PSB5ID8geCAhPT0gMCB8fCAxIC8geCA9PT0gMSAvIHkgOiB4ICE9IHggJiYgeSAhPSB5O1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/same-value.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/set-global.js": +/*!******************************************************!*\ + !*** ./node_modules/core-js/internals/set-global.js ***! + \******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var global = __webpack_require__(/*! ../internals/global */ \"./node_modules/core-js/internals/global.js\");\nvar hide = __webpack_require__(/*! ../internals/hide */ \"./node_modules/core-js/internals/hide.js\");\n\nmodule.exports = function (key, value) {\n try {\n hide(global, key, value);\n } catch (error) {\n global[key] = value;\n } return value;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvc2V0LWdsb2JhbC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL3NldC1nbG9iYWwuanM/Y2U0ZSJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2dsb2JhbCcpO1xudmFyIGhpZGUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaGlkZScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gIHRyeSB7XG4gICAgaGlkZShnbG9iYWwsIGtleSwgdmFsdWUpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGdsb2JhbFtrZXldID0gdmFsdWU7XG4gIH0gcmV0dXJuIHZhbHVlO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/set-global.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/set-species.js": +/*!*******************************************************!*\ + !*** ./node_modules/core-js/internals/set-species.js ***! + \*******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar getBuiltIn = __webpack_require__(/*! ../internals/get-built-in */ \"./node_modules/core-js/internals/get-built-in.js\");\nvar definePropertyModule = __webpack_require__(/*! ../internals/object-define-property */ \"./node_modules/core-js/internals/object-define-property.js\");\nvar wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ \"./node_modules/core-js/internals/well-known-symbol.js\");\nvar DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ \"./node_modules/core-js/internals/descriptors.js\");\n\nvar SPECIES = wellKnownSymbol('species');\n\nmodule.exports = function (CONSTRUCTOR_NAME) {\n var C = getBuiltIn(CONSTRUCTOR_NAME);\n var defineProperty = definePropertyModule.f;\n if (DESCRIPTORS && C && !C[SPECIES]) defineProperty(C, SPECIES, {\n configurable: true,\n get: function () { return this; }\n });\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvc2V0LXNwZWNpZXMuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9zZXQtc3BlY2llcy5qcz8yNjI2Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcbnZhciBnZXRCdWlsdEluID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2dldC1idWlsdC1pbicpO1xudmFyIGRlZmluZVByb3BlcnR5TW9kdWxlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL29iamVjdC1kZWZpbmUtcHJvcGVydHknKTtcbnZhciB3ZWxsS25vd25TeW1ib2wgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvd2VsbC1rbm93bi1zeW1ib2wnKTtcbnZhciBERVNDUklQVE9SUyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9kZXNjcmlwdG9ycycpO1xuXG52YXIgU1BFQ0lFUyA9IHdlbGxLbm93blN5bWJvbCgnc3BlY2llcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChDT05TVFJVQ1RPUl9OQU1FKSB7XG4gIHZhciBDID0gZ2V0QnVpbHRJbihDT05TVFJVQ1RPUl9OQU1FKTtcbiAgdmFyIGRlZmluZVByb3BlcnR5ID0gZGVmaW5lUHJvcGVydHlNb2R1bGUuZjtcbiAgaWYgKERFU0NSSVBUT1JTICYmIEMgJiYgIUNbU1BFQ0lFU10pIGRlZmluZVByb3BlcnR5KEMsIFNQRUNJRVMsIHtcbiAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9XG4gIH0pO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/set-species.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/set-to-string-tag.js": +/*!*************************************************************!*\ + !*** ./node_modules/core-js/internals/set-to-string-tag.js ***! + \*************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var defineProperty = __webpack_require__(/*! ../internals/object-define-property */ \"./node_modules/core-js/internals/object-define-property.js\").f;\nvar has = __webpack_require__(/*! ../internals/has */ \"./node_modules/core-js/internals/has.js\");\nvar wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ \"./node_modules/core-js/internals/well-known-symbol.js\");\n\nvar TO_STRING_TAG = wellKnownSymbol('toStringTag');\n\nmodule.exports = function (it, TAG, STATIC) {\n if (it && !has(it = STATIC ? it : it.prototype, TO_STRING_TAG)) {\n defineProperty(it, TO_STRING_TAG, { configurable: true, value: TAG });\n }\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvc2V0LXRvLXN0cmluZy10YWcuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9zZXQtdG8tc3RyaW5nLXRhZy5qcz9kNDRlIl0sInNvdXJjZXNDb250ZW50IjpbInZhciBkZWZpbmVQcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9vYmplY3QtZGVmaW5lLXByb3BlcnR5JykuZjtcbnZhciBoYXMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaGFzJyk7XG52YXIgd2VsbEtub3duU3ltYm9sID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3dlbGwta25vd24tc3ltYm9sJyk7XG5cbnZhciBUT19TVFJJTkdfVEFHID0gd2VsbEtub3duU3ltYm9sKCd0b1N0cmluZ1RhZycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCwgVEFHLCBTVEFUSUMpIHtcbiAgaWYgKGl0ICYmICFoYXMoaXQgPSBTVEFUSUMgPyBpdCA6IGl0LnByb3RvdHlwZSwgVE9fU1RSSU5HX1RBRykpIHtcbiAgICBkZWZpbmVQcm9wZXJ0eShpdCwgVE9fU1RSSU5HX1RBRywgeyBjb25maWd1cmFibGU6IHRydWUsIHZhbHVlOiBUQUcgfSk7XG4gIH1cbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/set-to-string-tag.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/shared-key.js": +/*!******************************************************!*\ + !*** ./node_modules/core-js/internals/shared-key.js ***! + \******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var shared = __webpack_require__(/*! ../internals/shared */ \"./node_modules/core-js/internals/shared.js\");\nvar uid = __webpack_require__(/*! ../internals/uid */ \"./node_modules/core-js/internals/uid.js\");\n\nvar keys = shared('keys');\n\nmodule.exports = function (key) {\n return keys[key] || (keys[key] = uid(key));\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvc2hhcmVkLWtleS5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL3NoYXJlZC1rZXkuanM/Zjc3MiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgc2hhcmVkID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3NoYXJlZCcpO1xudmFyIHVpZCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy91aWQnKTtcblxudmFyIGtleXMgPSBzaGFyZWQoJ2tleXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoa2V5KSB7XG4gIHJldHVybiBrZXlzW2tleV0gfHwgKGtleXNba2V5XSA9IHVpZChrZXkpKTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/shared-key.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/shared.js": +/*!**************************************************!*\ + !*** ./node_modules/core-js/internals/shared.js ***! + \**************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var global = __webpack_require__(/*! ../internals/global */ \"./node_modules/core-js/internals/global.js\");\nvar setGlobal = __webpack_require__(/*! ../internals/set-global */ \"./node_modules/core-js/internals/set-global.js\");\nvar IS_PURE = __webpack_require__(/*! ../internals/is-pure */ \"./node_modules/core-js/internals/is-pure.js\");\n\nvar SHARED = '__core-js_shared__';\nvar store = global[SHARED] || setGlobal(SHARED, {});\n\n(module.exports = function (key, value) {\n return store[key] || (store[key] = value !== undefined ? value : {});\n})('versions', []).push({\n version: '3.1.3',\n mode: IS_PURE ? 'pure' : 'global',\n copyright: '© 2019 Denis Pushkarev (zloirock.ru)'\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvc2hhcmVkLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvc2hhcmVkLmpzPzU2OTIiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9nbG9iYWwnKTtcbnZhciBzZXRHbG9iYWwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvc2V0LWdsb2JhbCcpO1xudmFyIElTX1BVUkUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaXMtcHVyZScpO1xuXG52YXIgU0hBUkVEID0gJ19fY29yZS1qc19zaGFyZWRfXyc7XG52YXIgc3RvcmUgPSBnbG9iYWxbU0hBUkVEXSB8fCBzZXRHbG9iYWwoU0hBUkVELCB7fSk7XG5cbihtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gIHJldHVybiBzdG9yZVtrZXldIHx8IChzdG9yZVtrZXldID0gdmFsdWUgIT09IHVuZGVmaW5lZCA/IHZhbHVlIDoge30pO1xufSkoJ3ZlcnNpb25zJywgW10pLnB1c2goe1xuICB2ZXJzaW9uOiAnMy4xLjMnLFxuICBtb2RlOiBJU19QVVJFID8gJ3B1cmUnIDogJ2dsb2JhbCcsXG4gIGNvcHlyaWdodDogJ8KpIDIwMTkgRGVuaXMgUHVzaGthcmV2ICh6bG9pcm9jay5ydSknXG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/shared.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/species-constructor.js": +/*!***************************************************************!*\ + !*** ./node_modules/core-js/internals/species-constructor.js ***! + \***************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var anObject = __webpack_require__(/*! ../internals/an-object */ \"./node_modules/core-js/internals/an-object.js\");\nvar aFunction = __webpack_require__(/*! ../internals/a-function */ \"./node_modules/core-js/internals/a-function.js\");\nvar wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ \"./node_modules/core-js/internals/well-known-symbol.js\");\n\nvar SPECIES = wellKnownSymbol('species');\n\n// `SpeciesConstructor` abstract operation\n// https://tc39.github.io/ecma262/#sec-speciesconstructor\nmodule.exports = function (O, defaultConstructor) {\n var C = anObject(O).constructor;\n var S;\n return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? defaultConstructor : aFunction(S);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvc3BlY2llcy1jb25zdHJ1Y3Rvci5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL3NwZWNpZXMtY29uc3RydWN0b3IuanM/NDg0MCJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvYW4tb2JqZWN0Jyk7XG52YXIgYUZ1bmN0aW9uID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2EtZnVuY3Rpb24nKTtcbnZhciB3ZWxsS25vd25TeW1ib2wgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvd2VsbC1rbm93bi1zeW1ib2wnKTtcblxudmFyIFNQRUNJRVMgPSB3ZWxsS25vd25TeW1ib2woJ3NwZWNpZXMnKTtcblxuLy8gYFNwZWNpZXNDb25zdHJ1Y3RvcmAgYWJzdHJhY3Qgb3BlcmF0aW9uXG4vLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1zcGVjaWVzY29uc3RydWN0b3Jcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKE8sIGRlZmF1bHRDb25zdHJ1Y3Rvcikge1xuICB2YXIgQyA9IGFuT2JqZWN0KE8pLmNvbnN0cnVjdG9yO1xuICB2YXIgUztcbiAgcmV0dXJuIEMgPT09IHVuZGVmaW5lZCB8fCAoUyA9IGFuT2JqZWN0KEMpW1NQRUNJRVNdKSA9PSB1bmRlZmluZWQgPyBkZWZhdWx0Q29uc3RydWN0b3IgOiBhRnVuY3Rpb24oUyk7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/species-constructor.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/string-at.js": +/*!*****************************************************!*\ + !*** ./node_modules/core-js/internals/string-at.js ***! + \*****************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var toInteger = __webpack_require__(/*! ../internals/to-integer */ \"./node_modules/core-js/internals/to-integer.js\");\nvar requireObjectCoercible = __webpack_require__(/*! ../internals/require-object-coercible */ \"./node_modules/core-js/internals/require-object-coercible.js\");\n\n// CONVERT_TO_STRING: true -> String#at\n// CONVERT_TO_STRING: false -> String#codePointAt\nmodule.exports = function (that, pos, CONVERT_TO_STRING) {\n var S = String(requireObjectCoercible(that));\n var position = toInteger(pos);\n var size = S.length;\n var first, second;\n if (position < 0 || position >= size) return CONVERT_TO_STRING ? '' : undefined;\n first = S.charCodeAt(position);\n return first < 0xD800 || first > 0xDBFF || position + 1 === size\n || (second = S.charCodeAt(position + 1)) < 0xDC00 || second > 0xDFFF\n ? CONVERT_TO_STRING ? S.charAt(position) : first\n : CONVERT_TO_STRING ? S.slice(position, position + 2) : (first - 0xD800 << 10) + (second - 0xDC00) + 0x10000;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvc3RyaW5nLWF0LmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvc3RyaW5nLWF0LmpzP2U1ZDUiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4uL2ludGVybmFscy90by1pbnRlZ2VyJyk7XG52YXIgcmVxdWlyZU9iamVjdENvZXJjaWJsZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9yZXF1aXJlLW9iamVjdC1jb2VyY2libGUnKTtcblxuLy8gQ09OVkVSVF9UT19TVFJJTkc6IHRydWUgIC0+IFN0cmluZyNhdFxuLy8gQ09OVkVSVF9UT19TVFJJTkc6IGZhbHNlIC0+IFN0cmluZyNjb2RlUG9pbnRBdFxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAodGhhdCwgcG9zLCBDT05WRVJUX1RPX1NUUklORykge1xuICB2YXIgUyA9IFN0cmluZyhyZXF1aXJlT2JqZWN0Q29lcmNpYmxlKHRoYXQpKTtcbiAgdmFyIHBvc2l0aW9uID0gdG9JbnRlZ2VyKHBvcyk7XG4gIHZhciBzaXplID0gUy5sZW5ndGg7XG4gIHZhciBmaXJzdCwgc2Vjb25kO1xuICBpZiAocG9zaXRpb24gPCAwIHx8IHBvc2l0aW9uID49IHNpemUpIHJldHVybiBDT05WRVJUX1RPX1NUUklORyA/ICcnIDogdW5kZWZpbmVkO1xuICBmaXJzdCA9IFMuY2hhckNvZGVBdChwb3NpdGlvbik7XG4gIHJldHVybiBmaXJzdCA8IDB4RDgwMCB8fCBmaXJzdCA+IDB4REJGRiB8fCBwb3NpdGlvbiArIDEgPT09IHNpemVcbiAgICB8fCAoc2Vjb25kID0gUy5jaGFyQ29kZUF0KHBvc2l0aW9uICsgMSkpIDwgMHhEQzAwIHx8IHNlY29uZCA+IDB4REZGRlxuICAgICAgPyBDT05WRVJUX1RPX1NUUklORyA/IFMuY2hhckF0KHBvc2l0aW9uKSA6IGZpcnN0XG4gICAgICA6IENPTlZFUlRfVE9fU1RSSU5HID8gUy5zbGljZShwb3NpdGlvbiwgcG9zaXRpb24gKyAyKSA6IChmaXJzdCAtIDB4RDgwMCA8PCAxMCkgKyAoc2Vjb25kIC0gMHhEQzAwKSArIDB4MTAwMDA7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/string-at.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/string-pad.js": +/*!******************************************************!*\ + !*** ./node_modules/core-js/internals/string-pad.js ***! + \******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("// https://github.com/tc39/proposal-string-pad-start-end\nvar toLength = __webpack_require__(/*! ../internals/to-length */ \"./node_modules/core-js/internals/to-length.js\");\nvar repeat = __webpack_require__(/*! ../internals/string-repeat */ \"./node_modules/core-js/internals/string-repeat.js\");\nvar requireObjectCoercible = __webpack_require__(/*! ../internals/require-object-coercible */ \"./node_modules/core-js/internals/require-object-coercible.js\");\n\nmodule.exports = function (that, maxLength, fillString, left) {\n var S = String(requireObjectCoercible(that));\n var stringLength = S.length;\n var fillStr = fillString === undefined ? ' ' : String(fillString);\n var intMaxLength = toLength(maxLength);\n var fillLen, stringFiller;\n if (intMaxLength <= stringLength || fillStr == '') return S;\n fillLen = intMaxLength - stringLength;\n stringFiller = repeat.call(fillStr, Math.ceil(fillLen / fillStr.length));\n if (stringFiller.length > fillLen) stringFiller = stringFiller.slice(0, fillLen);\n return left ? stringFiller + S : S + stringFiller;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvc3RyaW5nLXBhZC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL3N0cmluZy1wYWQuanM/MGNjYiJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBodHRwczovL2dpdGh1Yi5jb20vdGMzOS9wcm9wb3NhbC1zdHJpbmctcGFkLXN0YXJ0LWVuZFxudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3RvLWxlbmd0aCcpO1xudmFyIHJlcGVhdCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9zdHJpbmctcmVwZWF0Jyk7XG52YXIgcmVxdWlyZU9iamVjdENvZXJjaWJsZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9yZXF1aXJlLW9iamVjdC1jb2VyY2libGUnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAodGhhdCwgbWF4TGVuZ3RoLCBmaWxsU3RyaW5nLCBsZWZ0KSB7XG4gIHZhciBTID0gU3RyaW5nKHJlcXVpcmVPYmplY3RDb2VyY2libGUodGhhdCkpO1xuICB2YXIgc3RyaW5nTGVuZ3RoID0gUy5sZW5ndGg7XG4gIHZhciBmaWxsU3RyID0gZmlsbFN0cmluZyA9PT0gdW5kZWZpbmVkID8gJyAnIDogU3RyaW5nKGZpbGxTdHJpbmcpO1xuICB2YXIgaW50TWF4TGVuZ3RoID0gdG9MZW5ndGgobWF4TGVuZ3RoKTtcbiAgdmFyIGZpbGxMZW4sIHN0cmluZ0ZpbGxlcjtcbiAgaWYgKGludE1heExlbmd0aCA8PSBzdHJpbmdMZW5ndGggfHwgZmlsbFN0ciA9PSAnJykgcmV0dXJuIFM7XG4gIGZpbGxMZW4gPSBpbnRNYXhMZW5ndGggLSBzdHJpbmdMZW5ndGg7XG4gIHN0cmluZ0ZpbGxlciA9IHJlcGVhdC5jYWxsKGZpbGxTdHIsIE1hdGguY2VpbChmaWxsTGVuIC8gZmlsbFN0ci5sZW5ndGgpKTtcbiAgaWYgKHN0cmluZ0ZpbGxlci5sZW5ndGggPiBmaWxsTGVuKSBzdHJpbmdGaWxsZXIgPSBzdHJpbmdGaWxsZXIuc2xpY2UoMCwgZmlsbExlbik7XG4gIHJldHVybiBsZWZ0ID8gc3RyaW5nRmlsbGVyICsgUyA6IFMgKyBzdHJpbmdGaWxsZXI7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/string-pad.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/string-repeat.js": +/*!*********************************************************!*\ + !*** ./node_modules/core-js/internals/string-repeat.js ***! + \*********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar toInteger = __webpack_require__(/*! ../internals/to-integer */ \"./node_modules/core-js/internals/to-integer.js\");\nvar requireObjectCoercible = __webpack_require__(/*! ../internals/require-object-coercible */ \"./node_modules/core-js/internals/require-object-coercible.js\");\n\n// `String.prototype.repeat` method implementation\n// https://tc39.github.io/ecma262/#sec-string.prototype.repeat\nmodule.exports = ''.repeat || function repeat(count) {\n var str = String(requireObjectCoercible(this));\n var result = '';\n var n = toInteger(count);\n if (n < 0 || n == Infinity) throw RangeError('Wrong number of repetitions');\n for (;n > 0; (n >>>= 1) && (str += str)) if (n & 1) result += str;\n return result;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvc3RyaW5nLXJlcGVhdC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL3N0cmluZy1yZXBlYXQuanM/MTE0OCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG52YXIgdG9JbnRlZ2VyID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3RvLWludGVnZXInKTtcbnZhciByZXF1aXJlT2JqZWN0Q29lcmNpYmxlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3JlcXVpcmUtb2JqZWN0LWNvZXJjaWJsZScpO1xuXG4vLyBgU3RyaW5nLnByb3RvdHlwZS5yZXBlYXRgIG1ldGhvZCBpbXBsZW1lbnRhdGlvblxuLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtc3RyaW5nLnByb3RvdHlwZS5yZXBlYXRcbm1vZHVsZS5leHBvcnRzID0gJycucmVwZWF0IHx8IGZ1bmN0aW9uIHJlcGVhdChjb3VudCkge1xuICB2YXIgc3RyID0gU3RyaW5nKHJlcXVpcmVPYmplY3RDb2VyY2libGUodGhpcykpO1xuICB2YXIgcmVzdWx0ID0gJyc7XG4gIHZhciBuID0gdG9JbnRlZ2VyKGNvdW50KTtcbiAgaWYgKG4gPCAwIHx8IG4gPT0gSW5maW5pdHkpIHRocm93IFJhbmdlRXJyb3IoJ1dyb25nIG51bWJlciBvZiByZXBldGl0aW9ucycpO1xuICBmb3IgKDtuID4gMDsgKG4gPj4+PSAxKSAmJiAoc3RyICs9IHN0cikpIGlmIChuICYgMSkgcmVzdWx0ICs9IHN0cjtcbiAgcmV0dXJuIHJlc3VsdDtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/string-repeat.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/string-trim.js": +/*!*******************************************************!*\ + !*** ./node_modules/core-js/internals/string-trim.js ***! + \*******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var requireObjectCoercible = __webpack_require__(/*! ../internals/require-object-coercible */ \"./node_modules/core-js/internals/require-object-coercible.js\");\nvar whitespaces = __webpack_require__(/*! ../internals/whitespaces */ \"./node_modules/core-js/internals/whitespaces.js\");\n\nvar whitespace = '[' + whitespaces + ']';\nvar ltrim = RegExp('^' + whitespace + whitespace + '*');\nvar rtrim = RegExp(whitespace + whitespace + '*$');\n\n// 1 -> String#trimStart\n// 2 -> String#trimEnd\n// 3 -> String#trim\nmodule.exports = function (string, TYPE) {\n string = String(requireObjectCoercible(string));\n if (TYPE & 1) string = string.replace(ltrim, '');\n if (TYPE & 2) string = string.replace(rtrim, '');\n return string;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvc3RyaW5nLXRyaW0uanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9zdHJpbmctdHJpbS5qcz81OGE4Il0sInNvdXJjZXNDb250ZW50IjpbInZhciByZXF1aXJlT2JqZWN0Q29lcmNpYmxlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3JlcXVpcmUtb2JqZWN0LWNvZXJjaWJsZScpO1xudmFyIHdoaXRlc3BhY2VzID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3doaXRlc3BhY2VzJyk7XG5cbnZhciB3aGl0ZXNwYWNlID0gJ1snICsgd2hpdGVzcGFjZXMgKyAnXSc7XG52YXIgbHRyaW0gPSBSZWdFeHAoJ14nICsgd2hpdGVzcGFjZSArIHdoaXRlc3BhY2UgKyAnKicpO1xudmFyIHJ0cmltID0gUmVnRXhwKHdoaXRlc3BhY2UgKyB3aGl0ZXNwYWNlICsgJyokJyk7XG5cbi8vIDEgLT4gU3RyaW5nI3RyaW1TdGFydFxuLy8gMiAtPiBTdHJpbmcjdHJpbUVuZFxuLy8gMyAtPiBTdHJpbmcjdHJpbVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoc3RyaW5nLCBUWVBFKSB7XG4gIHN0cmluZyA9IFN0cmluZyhyZXF1aXJlT2JqZWN0Q29lcmNpYmxlKHN0cmluZykpO1xuICBpZiAoVFlQRSAmIDEpIHN0cmluZyA9IHN0cmluZy5yZXBsYWNlKGx0cmltLCAnJyk7XG4gIGlmIChUWVBFICYgMikgc3RyaW5nID0gc3RyaW5nLnJlcGxhY2UocnRyaW0sICcnKTtcbiAgcmV0dXJuIHN0cmluZztcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/string-trim.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/task.js": +/*!************************************************!*\ + !*** ./node_modules/core-js/internals/task.js ***! + \************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var global = __webpack_require__(/*! ../internals/global */ \"./node_modules/core-js/internals/global.js\");\nvar fails = __webpack_require__(/*! ../internals/fails */ \"./node_modules/core-js/internals/fails.js\");\nvar classof = __webpack_require__(/*! ../internals/classof-raw */ \"./node_modules/core-js/internals/classof-raw.js\");\nvar bind = __webpack_require__(/*! ../internals/bind-context */ \"./node_modules/core-js/internals/bind-context.js\");\nvar html = __webpack_require__(/*! ../internals/html */ \"./node_modules/core-js/internals/html.js\");\nvar createElement = __webpack_require__(/*! ../internals/document-create-element */ \"./node_modules/core-js/internals/document-create-element.js\");\n\nvar location = global.location;\nvar set = global.setImmediate;\nvar clear = global.clearImmediate;\nvar process = global.process;\nvar MessageChannel = global.MessageChannel;\nvar Dispatch = global.Dispatch;\nvar counter = 0;\nvar queue = {};\nvar ONREADYSTATECHANGE = 'onreadystatechange';\nvar defer, channel, port;\n\nvar run = function (id) {\n // eslint-disable-next-line no-prototype-builtins\n if (queue.hasOwnProperty(id)) {\n var fn = queue[id];\n delete queue[id];\n fn();\n }\n};\n\nvar runner = function (id) {\n return function () {\n run(id);\n };\n};\n\nvar listener = function (event) {\n run(event.data);\n};\n\nvar post = function (id) {\n // old engines have not location.origin\n global.postMessage(id + '', location.protocol + '//' + location.host);\n};\n\n// Node.js 0.9+ & IE10+ has setImmediate, otherwise:\nif (!set || !clear) {\n set = function setImmediate(fn) {\n var args = [];\n var i = 1;\n while (arguments.length > i) args.push(arguments[i++]);\n queue[++counter] = function () {\n // eslint-disable-next-line no-new-func\n (typeof fn == 'function' ? fn : Function(fn)).apply(undefined, args);\n };\n defer(counter);\n return counter;\n };\n clear = function clearImmediate(id) {\n delete queue[id];\n };\n // Node.js 0.8-\n if (classof(process) == 'process') {\n defer = function (id) {\n process.nextTick(runner(id));\n };\n // Sphere (JS game engine) Dispatch API\n } else if (Dispatch && Dispatch.now) {\n defer = function (id) {\n Dispatch.now(runner(id));\n };\n // Browsers with MessageChannel, includes WebWorkers\n } else if (MessageChannel) {\n channel = new MessageChannel();\n port = channel.port2;\n channel.port1.onmessage = listener;\n defer = bind(port.postMessage, port, 1);\n // Browsers with postMessage, skip WebWorkers\n // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'\n } else if (global.addEventListener && typeof postMessage == 'function' && !global.importScripts && !fails(post)) {\n defer = post;\n global.addEventListener('message', listener, false);\n // IE8-\n } else if (ONREADYSTATECHANGE in createElement('script')) {\n defer = function (id) {\n html.appendChild(createElement('script'))[ONREADYSTATECHANGE] = function () {\n html.removeChild(this);\n run(id);\n };\n };\n // Rest old browsers\n } else {\n defer = function (id) {\n setTimeout(runner(id), 0);\n };\n }\n}\n\nmodule.exports = {\n set: set,\n clear: clear\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvdGFzay5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL3Rhc2suanM/MmNmNCJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2dsb2JhbCcpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2ZhaWxzJyk7XG52YXIgY2xhc3NvZiA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9jbGFzc29mLXJhdycpO1xudmFyIGJpbmQgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvYmluZC1jb250ZXh0Jyk7XG52YXIgaHRtbCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9odG1sJyk7XG52YXIgY3JlYXRlRWxlbWVudCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9kb2N1bWVudC1jcmVhdGUtZWxlbWVudCcpO1xuXG52YXIgbG9jYXRpb24gPSBnbG9iYWwubG9jYXRpb247XG52YXIgc2V0ID0gZ2xvYmFsLnNldEltbWVkaWF0ZTtcbnZhciBjbGVhciA9IGdsb2JhbC5jbGVhckltbWVkaWF0ZTtcbnZhciBwcm9jZXNzID0gZ2xvYmFsLnByb2Nlc3M7XG52YXIgTWVzc2FnZUNoYW5uZWwgPSBnbG9iYWwuTWVzc2FnZUNoYW5uZWw7XG52YXIgRGlzcGF0Y2ggPSBnbG9iYWwuRGlzcGF0Y2g7XG52YXIgY291bnRlciA9IDA7XG52YXIgcXVldWUgPSB7fTtcbnZhciBPTlJFQURZU1RBVEVDSEFOR0UgPSAnb25yZWFkeXN0YXRlY2hhbmdlJztcbnZhciBkZWZlciwgY2hhbm5lbCwgcG9ydDtcblxudmFyIHJ1biA9IGZ1bmN0aW9uIChpZCkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcHJvdG90eXBlLWJ1aWx0aW5zXG4gIGlmIChxdWV1ZS5oYXNPd25Qcm9wZXJ0eShpZCkpIHtcbiAgICB2YXIgZm4gPSBxdWV1ZVtpZF07XG4gICAgZGVsZXRlIHF1ZXVlW2lkXTtcbiAgICBmbigpO1xuICB9XG59O1xuXG52YXIgcnVubmVyID0gZnVuY3Rpb24gKGlkKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgcnVuKGlkKTtcbiAgfTtcbn07XG5cbnZhciBsaXN0ZW5lciA9IGZ1bmN0aW9uIChldmVudCkge1xuICBydW4oZXZlbnQuZGF0YSk7XG59O1xuXG52YXIgcG9zdCA9IGZ1bmN0aW9uIChpZCkge1xuICAvLyBvbGQgZW5naW5lcyBoYXZlIG5vdCBsb2NhdGlvbi5vcmlnaW5cbiAgZ2xvYmFsLnBvc3RNZXNzYWdlKGlkICsgJycsIGxvY2F0aW9uLnByb3RvY29sICsgJy8vJyArIGxvY2F0aW9uLmhvc3QpO1xufTtcblxuLy8gTm9kZS5qcyAwLjkrICYgSUUxMCsgaGFzIHNldEltbWVkaWF0ZSwgb3RoZXJ3aXNlOlxuaWYgKCFzZXQgfHwgIWNsZWFyKSB7XG4gIHNldCA9IGZ1bmN0aW9uIHNldEltbWVkaWF0ZShmbikge1xuICAgIHZhciBhcmdzID0gW107XG4gICAgdmFyIGkgPSAxO1xuICAgIHdoaWxlIChhcmd1bWVudHMubGVuZ3RoID4gaSkgYXJncy5wdXNoKGFyZ3VtZW50c1tpKytdKTtcbiAgICBxdWV1ZVsrK2NvdW50ZXJdID0gZnVuY3Rpb24gKCkge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLW5ldy1mdW5jXG4gICAgICAodHlwZW9mIGZuID09ICdmdW5jdGlvbicgPyBmbiA6IEZ1bmN0aW9uKGZuKSkuYXBwbHkodW5kZWZpbmVkLCBhcmdzKTtcbiAgICB9O1xuICAgIGRlZmVyKGNvdW50ZXIpO1xuICAgIHJldHVybiBjb3VudGVyO1xuICB9O1xuICBjbGVhciA9IGZ1bmN0aW9uIGNsZWFySW1tZWRpYXRlKGlkKSB7XG4gICAgZGVsZXRlIHF1ZXVlW2lkXTtcbiAgfTtcbiAgLy8gTm9kZS5qcyAwLjgtXG4gIGlmIChjbGFzc29mKHByb2Nlc3MpID09ICdwcm9jZXNzJykge1xuICAgIGRlZmVyID0gZnVuY3Rpb24gKGlkKSB7XG4gICAgICBwcm9jZXNzLm5leHRUaWNrKHJ1bm5lcihpZCkpO1xuICAgIH07XG4gIC8vIFNwaGVyZSAoSlMgZ2FtZSBlbmdpbmUpIERpc3BhdGNoIEFQSVxuICB9IGVsc2UgaWYgKERpc3BhdGNoICYmIERpc3BhdGNoLm5vdykge1xuICAgIGRlZmVyID0gZnVuY3Rpb24gKGlkKSB7XG4gICAgICBEaXNwYXRjaC5ub3cocnVubmVyKGlkKSk7XG4gICAgfTtcbiAgLy8gQnJvd3NlcnMgd2l0aCBNZXNzYWdlQ2hhbm5lbCwgaW5jbHVkZXMgV2ViV29ya2Vyc1xuICB9IGVsc2UgaWYgKE1lc3NhZ2VDaGFubmVsKSB7XG4gICAgY2hhbm5lbCA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICAgIHBvcnQgPSBjaGFubmVsLnBvcnQyO1xuICAgIGNoYW5uZWwucG9ydDEub25tZXNzYWdlID0gbGlzdGVuZXI7XG4gICAgZGVmZXIgPSBiaW5kKHBvcnQucG9zdE1lc3NhZ2UsIHBvcnQsIDEpO1xuICAvLyBCcm93c2VycyB3aXRoIHBvc3RNZXNzYWdlLCBza2lwIFdlYldvcmtlcnNcbiAgLy8gSUU4IGhhcyBwb3N0TWVzc2FnZSwgYnV0IGl0J3Mgc3luYyAmIHR5cGVvZiBpdHMgcG9zdE1lc3NhZ2UgaXMgJ29iamVjdCdcbiAgfSBlbHNlIGlmIChnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lciAmJiB0eXBlb2YgcG9zdE1lc3NhZ2UgPT0gJ2Z1bmN0aW9uJyAmJiAhZ2xvYmFsLmltcG9ydFNjcmlwdHMgJiYgIWZhaWxzKHBvc3QpKSB7XG4gICAgZGVmZXIgPSBwb3N0O1xuICAgIGdsb2JhbC5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgbGlzdGVuZXIsIGZhbHNlKTtcbiAgLy8gSUU4LVxuICB9IGVsc2UgaWYgKE9OUkVBRFlTVEFURUNIQU5HRSBpbiBjcmVhdGVFbGVtZW50KCdzY3JpcHQnKSkge1xuICAgIGRlZmVyID0gZnVuY3Rpb24gKGlkKSB7XG4gICAgICBodG1sLmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpKVtPTlJFQURZU1RBVEVDSEFOR0VdID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBodG1sLnJlbW92ZUNoaWxkKHRoaXMpO1xuICAgICAgICBydW4oaWQpO1xuICAgICAgfTtcbiAgICB9O1xuICAvLyBSZXN0IG9sZCBicm93c2Vyc1xuICB9IGVsc2Uge1xuICAgIGRlZmVyID0gZnVuY3Rpb24gKGlkKSB7XG4gICAgICBzZXRUaW1lb3V0KHJ1bm5lcihpZCksIDApO1xuICAgIH07XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHNldDogc2V0LFxuICBjbGVhcjogY2xlYXJcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/task.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/to-absolute-index.js": +/*!*************************************************************!*\ + !*** ./node_modules/core-js/internals/to-absolute-index.js ***! + \*************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var toInteger = __webpack_require__(/*! ../internals/to-integer */ \"./node_modules/core-js/internals/to-integer.js\");\n\nvar max = Math.max;\nvar min = Math.min;\n\n// Helper for a popular repeating case of the spec:\n// Let integer be ? ToInteger(index).\n// If integer < 0, let result be max((length + integer), 0); else let result be min(length, length).\nmodule.exports = function (index, length) {\n var integer = toInteger(index);\n return integer < 0 ? max(integer + length, 0) : min(integer, length);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvdG8tYWJzb2x1dGUtaW5kZXguanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy90by1hYnNvbHV0ZS1pbmRleC5qcz8yM2NiIl0sInNvdXJjZXNDb250ZW50IjpbInZhciB0b0ludGVnZXIgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvdG8taW50ZWdlcicpO1xuXG52YXIgbWF4ID0gTWF0aC5tYXg7XG52YXIgbWluID0gTWF0aC5taW47XG5cbi8vIEhlbHBlciBmb3IgYSBwb3B1bGFyIHJlcGVhdGluZyBjYXNlIG9mIHRoZSBzcGVjOlxuLy8gTGV0IGludGVnZXIgYmUgPyBUb0ludGVnZXIoaW5kZXgpLlxuLy8gSWYgaW50ZWdlciA8IDAsIGxldCByZXN1bHQgYmUgbWF4KChsZW5ndGggKyBpbnRlZ2VyKSwgMCk7IGVsc2UgbGV0IHJlc3VsdCBiZSBtaW4obGVuZ3RoLCBsZW5ndGgpLlxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaW5kZXgsIGxlbmd0aCkge1xuICB2YXIgaW50ZWdlciA9IHRvSW50ZWdlcihpbmRleCk7XG4gIHJldHVybiBpbnRlZ2VyIDwgMCA/IG1heChpbnRlZ2VyICsgbGVuZ3RoLCAwKSA6IG1pbihpbnRlZ2VyLCBsZW5ndGgpO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/to-absolute-index.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/to-indexed-object.js": +/*!*************************************************************!*\ + !*** ./node_modules/core-js/internals/to-indexed-object.js ***! + \*************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("// toObject with fallback for non-array-like ES3 strings\nvar IndexedObject = __webpack_require__(/*! ../internals/indexed-object */ \"./node_modules/core-js/internals/indexed-object.js\");\nvar requireObjectCoercible = __webpack_require__(/*! ../internals/require-object-coercible */ \"./node_modules/core-js/internals/require-object-coercible.js\");\n\nmodule.exports = function (it) {\n return IndexedObject(requireObjectCoercible(it));\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvdG8taW5kZXhlZC1vYmplY3QuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy90by1pbmRleGVkLW9iamVjdC5qcz9mYzZhIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIHRvT2JqZWN0IHdpdGggZmFsbGJhY2sgZm9yIG5vbi1hcnJheS1saWtlIEVTMyBzdHJpbmdzXG52YXIgSW5kZXhlZE9iamVjdCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9pbmRleGVkLW9iamVjdCcpO1xudmFyIHJlcXVpcmVPYmplY3RDb2VyY2libGUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvcmVxdWlyZS1vYmplY3QtY29lcmNpYmxlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiBJbmRleGVkT2JqZWN0KHJlcXVpcmVPYmplY3RDb2VyY2libGUoaXQpKTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/to-indexed-object.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/to-integer.js": +/*!******************************************************!*\ + !*** ./node_modules/core-js/internals/to-integer.js ***! + \******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("var ceil = Math.ceil;\nvar floor = Math.floor;\n\n// `ToInteger` abstract operation\n// https://tc39.github.io/ecma262/#sec-tointeger\nmodule.exports = function (argument) {\n return isNaN(argument = +argument) ? 0 : (argument > 0 ? floor : ceil)(argument);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvdG8taW50ZWdlci5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL3RvLWludGVnZXIuanM/YTY5MSJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgY2VpbCA9IE1hdGguY2VpbDtcbnZhciBmbG9vciA9IE1hdGguZmxvb3I7XG5cbi8vIGBUb0ludGVnZXJgIGFic3RyYWN0IG9wZXJhdGlvblxuLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtdG9pbnRlZ2VyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChhcmd1bWVudCkge1xuICByZXR1cm4gaXNOYU4oYXJndW1lbnQgPSArYXJndW1lbnQpID8gMCA6IChhcmd1bWVudCA+IDAgPyBmbG9vciA6IGNlaWwpKGFyZ3VtZW50KTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/to-integer.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/to-length.js": +/*!*****************************************************!*\ + !*** ./node_modules/core-js/internals/to-length.js ***! + \*****************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var toInteger = __webpack_require__(/*! ../internals/to-integer */ \"./node_modules/core-js/internals/to-integer.js\");\n\nvar min = Math.min;\n\n// `ToLength` abstract operation\n// https://tc39.github.io/ecma262/#sec-tolength\nmodule.exports = function (argument) {\n return argument > 0 ? min(toInteger(argument), 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvdG8tbGVuZ3RoLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvdG8tbGVuZ3RoLmpzPzUwYzQiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4uL2ludGVybmFscy90by1pbnRlZ2VyJyk7XG5cbnZhciBtaW4gPSBNYXRoLm1pbjtcblxuLy8gYFRvTGVuZ3RoYCBhYnN0cmFjdCBvcGVyYXRpb25cbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXRvbGVuZ3RoXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChhcmd1bWVudCkge1xuICByZXR1cm4gYXJndW1lbnQgPiAwID8gbWluKHRvSW50ZWdlcihhcmd1bWVudCksIDB4MUZGRkZGRkZGRkZGRkYpIDogMDsgLy8gMiAqKiA1MyAtIDEgPT0gOTAwNzE5OTI1NDc0MDk5MVxufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/to-length.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/to-object.js": +/*!*****************************************************!*\ + !*** ./node_modules/core-js/internals/to-object.js ***! + \*****************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var requireObjectCoercible = __webpack_require__(/*! ../internals/require-object-coercible */ \"./node_modules/core-js/internals/require-object-coercible.js\");\n\n// `ToObject` abstract operation\n// https://tc39.github.io/ecma262/#sec-toobject\nmodule.exports = function (argument) {\n return Object(requireObjectCoercible(argument));\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvdG8tb2JqZWN0LmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvdG8tb2JqZWN0LmpzPzdiMGIiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIHJlcXVpcmVPYmplY3RDb2VyY2libGUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvcmVxdWlyZS1vYmplY3QtY29lcmNpYmxlJyk7XG5cbi8vIGBUb09iamVjdGAgYWJzdHJhY3Qgb3BlcmF0aW9uXG4vLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy10b29iamVjdFxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoYXJndW1lbnQpIHtcbiAgcmV0dXJuIE9iamVjdChyZXF1aXJlT2JqZWN0Q29lcmNpYmxlKGFyZ3VtZW50KSk7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/to-object.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/to-primitive.js": +/*!********************************************************!*\ + !*** ./node_modules/core-js/internals/to-primitive.js ***! + \********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var isObject = __webpack_require__(/*! ../internals/is-object */ \"./node_modules/core-js/internals/is-object.js\");\n\n// 7.1.1 ToPrimitive(input [, PreferredType])\n// instead of the ES6 spec version, we didn't implement @@toPrimitive case\n// and the second argument - flag - preferred type is a string\nmodule.exports = function (it, S) {\n if (!isObject(it)) return it;\n var fn, val;\n if (S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;\n if (typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it))) return val;\n if (!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;\n throw TypeError(\"Can't convert object to primitive value\");\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvdG8tcHJpbWl0aXZlLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvdG8tcHJpbWl0aXZlLmpzP2MwNGUiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2lzLW9iamVjdCcpO1xuXG4vLyA3LjEuMSBUb1ByaW1pdGl2ZShpbnB1dCBbLCBQcmVmZXJyZWRUeXBlXSlcbi8vIGluc3RlYWQgb2YgdGhlIEVTNiBzcGVjIHZlcnNpb24sIHdlIGRpZG4ndCBpbXBsZW1lbnQgQEB0b1ByaW1pdGl2ZSBjYXNlXG4vLyBhbmQgdGhlIHNlY29uZCBhcmd1bWVudCAtIGZsYWcgLSBwcmVmZXJyZWQgdHlwZSBpcyBhIHN0cmluZ1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQsIFMpIHtcbiAgaWYgKCFpc09iamVjdChpdCkpIHJldHVybiBpdDtcbiAgdmFyIGZuLCB2YWw7XG4gIGlmIChTICYmIHR5cGVvZiAoZm4gPSBpdC50b1N0cmluZykgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNPYmplY3QodmFsID0gZm4uY2FsbChpdCkpKSByZXR1cm4gdmFsO1xuICBpZiAodHlwZW9mIChmbiA9IGl0LnZhbHVlT2YpID09ICdmdW5jdGlvbicgJiYgIWlzT2JqZWN0KHZhbCA9IGZuLmNhbGwoaXQpKSkgcmV0dXJuIHZhbDtcbiAgaWYgKCFTICYmIHR5cGVvZiAoZm4gPSBpdC50b1N0cmluZykgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNPYmplY3QodmFsID0gZm4uY2FsbChpdCkpKSByZXR1cm4gdmFsO1xuICB0aHJvdyBUeXBlRXJyb3IoXCJDYW4ndCBjb252ZXJ0IG9iamVjdCB0byBwcmltaXRpdmUgdmFsdWVcIik7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/to-primitive.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/uid.js": +/*!***********************************************!*\ + !*** ./node_modules/core-js/internals/uid.js ***! + \***********************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("var id = 0;\nvar postfix = Math.random();\n\nmodule.exports = function (key) {\n return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + postfix).toString(36));\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvdWlkLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvdWlkLmpzPzkwZTMiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIGlkID0gMDtcbnZhciBwb3N0Zml4ID0gTWF0aC5yYW5kb20oKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoa2V5KSB7XG4gIHJldHVybiAnU3ltYm9sKCcuY29uY2F0KGtleSA9PT0gdW5kZWZpbmVkID8gJycgOiBrZXksICcpXycsICgrK2lkICsgcG9zdGZpeCkudG9TdHJpbmcoMzYpKTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/uid.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/user-agent.js": +/*!******************************************************!*\ + !*** ./node_modules/core-js/internals/user-agent.js ***! + \******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var global = __webpack_require__(/*! ../internals/global */ \"./node_modules/core-js/internals/global.js\");\n\nvar navigator = global.navigator;\n\nmodule.exports = navigator && navigator.userAgent || '';\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvdXNlci1hZ2VudC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvaW50ZXJuYWxzL3VzZXItYWdlbnQuanM/YjM5YSJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2dsb2JhbCcpO1xuXG52YXIgbmF2aWdhdG9yID0gZ2xvYmFsLm5hdmlnYXRvcjtcblxubW9kdWxlLmV4cG9ydHMgPSBuYXZpZ2F0b3IgJiYgbmF2aWdhdG9yLnVzZXJBZ2VudCB8fCAnJztcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/user-agent.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/validate-set-prototype-of-arguments.js": +/*!*******************************************************************************!*\ + !*** ./node_modules/core-js/internals/validate-set-prototype-of-arguments.js ***! + \*******************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var isObject = __webpack_require__(/*! ../internals/is-object */ \"./node_modules/core-js/internals/is-object.js\");\nvar anObject = __webpack_require__(/*! ../internals/an-object */ \"./node_modules/core-js/internals/an-object.js\");\n\nmodule.exports = function (O, proto) {\n anObject(O);\n if (!isObject(proto) && proto !== null) {\n throw TypeError(\"Can't set \" + String(proto) + ' as a prototype');\n }\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvdmFsaWRhdGUtc2V0LXByb3RvdHlwZS1vZi1hcmd1bWVudHMuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy92YWxpZGF0ZS1zZXQtcHJvdG90eXBlLW9mLWFyZ3VtZW50cy5qcz8yZTFhIl0sInNvdXJjZXNDb250ZW50IjpbInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9pcy1vYmplY3QnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9hbi1vYmplY3QnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoTywgcHJvdG8pIHtcbiAgYW5PYmplY3QoTyk7XG4gIGlmICghaXNPYmplY3QocHJvdG8pICYmIHByb3RvICE9PSBudWxsKSB7XG4gICAgdGhyb3cgVHlwZUVycm9yKFwiQ2FuJ3Qgc2V0IFwiICsgU3RyaW5nKHByb3RvKSArICcgYXMgYSBwcm90b3R5cGUnKTtcbiAgfVxufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/validate-set-prototype-of-arguments.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/validate-string-method-arguments.js": +/*!****************************************************************************!*\ + !*** ./node_modules/core-js/internals/validate-string-method-arguments.js ***! + \****************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("// helper for String#{startsWith, endsWith, includes}\nvar isRegExp = __webpack_require__(/*! ../internals/is-regexp */ \"./node_modules/core-js/internals/is-regexp.js\");\nvar requireObjectCoercible = __webpack_require__(/*! ../internals/require-object-coercible */ \"./node_modules/core-js/internals/require-object-coercible.js\");\n\nmodule.exports = function (that, searchString, NAME) {\n if (isRegExp(searchString)) {\n throw TypeError('String.prototype.' + NAME + \" doesn't accept regex\");\n } return String(requireObjectCoercible(that));\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvdmFsaWRhdGUtc3RyaW5nLW1ldGhvZC1hcmd1bWVudHMuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy92YWxpZGF0ZS1zdHJpbmctbWV0aG9kLWFyZ3VtZW50cy5qcz8zNDBlIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIGhlbHBlciBmb3IgU3RyaW5nI3tzdGFydHNXaXRoLCBlbmRzV2l0aCwgaW5jbHVkZXN9XG52YXIgaXNSZWdFeHAgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaXMtcmVnZXhwJyk7XG52YXIgcmVxdWlyZU9iamVjdENvZXJjaWJsZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9yZXF1aXJlLW9iamVjdC1jb2VyY2libGUnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAodGhhdCwgc2VhcmNoU3RyaW5nLCBOQU1FKSB7XG4gIGlmIChpc1JlZ0V4cChzZWFyY2hTdHJpbmcpKSB7XG4gICAgdGhyb3cgVHlwZUVycm9yKCdTdHJpbmcucHJvdG90eXBlLicgKyBOQU1FICsgXCIgZG9lc24ndCBhY2NlcHQgcmVnZXhcIik7XG4gIH0gcmV0dXJuIFN0cmluZyhyZXF1aXJlT2JqZWN0Q29lcmNpYmxlKHRoYXQpKTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/validate-string-method-arguments.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/webkit-string-pad-bug.js": +/*!*****************************************************************!*\ + !*** ./node_modules/core-js/internals/webkit-string-pad-bug.js ***! + \*****************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("// https://github.com/zloirock/core-js/issues/280\nvar userAgent = __webpack_require__(/*! ../internals/user-agent */ \"./node_modules/core-js/internals/user-agent.js\");\n\n// eslint-disable-next-line unicorn/no-unsafe-regex\nmodule.exports = /Version\\/10\\.\\d+(\\.\\d+)?( Mobile\\/\\w+)? Safari\\//.test(userAgent);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvd2Via2l0LXN0cmluZy1wYWQtYnVnLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvd2Via2l0LXN0cmluZy1wYWQtYnVnLmpzPzY5OWMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gaHR0cHM6Ly9naXRodWIuY29tL3psb2lyb2NrL2NvcmUtanMvaXNzdWVzLzI4MFxudmFyIHVzZXJBZ2VudCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy91c2VyLWFnZW50Jyk7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSB1bmljb3JuL25vLXVuc2FmZS1yZWdleFxubW9kdWxlLmV4cG9ydHMgPSAvVmVyc2lvblxcLzEwXFwuXFxkKyhcXC5cXGQrKT8oIE1vYmlsZVxcL1xcdyspPyBTYWZhcmlcXC8vLnRlc3QodXNlckFnZW50KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/webkit-string-pad-bug.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/well-known-symbol.js": +/*!*************************************************************!*\ + !*** ./node_modules/core-js/internals/well-known-symbol.js ***! + \*************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var global = __webpack_require__(/*! ../internals/global */ \"./node_modules/core-js/internals/global.js\");\nvar shared = __webpack_require__(/*! ../internals/shared */ \"./node_modules/core-js/internals/shared.js\");\nvar uid = __webpack_require__(/*! ../internals/uid */ \"./node_modules/core-js/internals/uid.js\");\nvar NATIVE_SYMBOL = __webpack_require__(/*! ../internals/native-symbol */ \"./node_modules/core-js/internals/native-symbol.js\");\n\nvar Symbol = global.Symbol;\nvar store = shared('wks');\n\nmodule.exports = function (name) {\n return store[name] || (store[name] = NATIVE_SYMBOL && Symbol[name]\n || (NATIVE_SYMBOL ? Symbol : uid)('Symbol.' + name));\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvd2VsbC1rbm93bi1zeW1ib2wuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy93ZWxsLWtub3duLXN5bWJvbC5qcz9iNjIyIl0sInNvdXJjZXNDb250ZW50IjpbInZhciBnbG9iYWwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZ2xvYmFsJyk7XG52YXIgc2hhcmVkID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3NoYXJlZCcpO1xudmFyIHVpZCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy91aWQnKTtcbnZhciBOQVRJVkVfU1lNQk9MID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL25hdGl2ZS1zeW1ib2wnKTtcblxudmFyIFN5bWJvbCA9IGdsb2JhbC5TeW1ib2w7XG52YXIgc3RvcmUgPSBzaGFyZWQoJ3drcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIHJldHVybiBzdG9yZVtuYW1lXSB8fCAoc3RvcmVbbmFtZV0gPSBOQVRJVkVfU1lNQk9MICYmIFN5bWJvbFtuYW1lXVxuICAgIHx8IChOQVRJVkVfU1lNQk9MID8gU3ltYm9sIDogdWlkKSgnU3ltYm9sLicgKyBuYW1lKSk7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/well-known-symbol.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/internals/whitespaces.js": +/*!*******************************************************!*\ + !*** ./node_modules/core-js/internals/whitespaces.js ***! + \*******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("// a string of all valid unicode whitespaces\n// eslint-disable-next-line max-len\nmodule.exports = '\\u0009\\u000A\\u000B\\u000C\\u000D\\u0020\\u00A0\\u1680\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028\\u2029\\uFEFF';\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9pbnRlcm5hbHMvd2hpdGVzcGFjZXMuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy93aGl0ZXNwYWNlcy5qcz81ODk5Il0sInNvdXJjZXNDb250ZW50IjpbIi8vIGEgc3RyaW5nIG9mIGFsbCB2YWxpZCB1bmljb2RlIHdoaXRlc3BhY2VzXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxlblxubW9kdWxlLmV4cG9ydHMgPSAnXFx1MDAwOVxcdTAwMEFcXHUwMDBCXFx1MDAwQ1xcdTAwMERcXHUwMDIwXFx1MDBBMFxcdTE2ODBcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwQVxcdTIwMkZcXHUyMDVGXFx1MzAwMFxcdTIwMjhcXHUyMDI5XFx1RkVGRic7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/internals/whitespaces.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.array.iterator.js": +/*!***********************************************************!*\ + !*** ./node_modules/core-js/modules/es.array.iterator.js ***! + \***********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar toIndexedObject = __webpack_require__(/*! ../internals/to-indexed-object */ \"./node_modules/core-js/internals/to-indexed-object.js\");\nvar addToUnscopables = __webpack_require__(/*! ../internals/add-to-unscopables */ \"./node_modules/core-js/internals/add-to-unscopables.js\");\nvar Iterators = __webpack_require__(/*! ../internals/iterators */ \"./node_modules/core-js/internals/iterators.js\");\nvar InternalStateModule = __webpack_require__(/*! ../internals/internal-state */ \"./node_modules/core-js/internals/internal-state.js\");\nvar defineIterator = __webpack_require__(/*! ../internals/define-iterator */ \"./node_modules/core-js/internals/define-iterator.js\");\n\nvar ARRAY_ITERATOR = 'Array Iterator';\nvar setInternalState = InternalStateModule.set;\nvar getInternalState = InternalStateModule.getterFor(ARRAY_ITERATOR);\n\n// `Array.prototype.entries` method\n// https://tc39.github.io/ecma262/#sec-array.prototype.entries\n// `Array.prototype.keys` method\n// https://tc39.github.io/ecma262/#sec-array.prototype.keys\n// `Array.prototype.values` method\n// https://tc39.github.io/ecma262/#sec-array.prototype.values\n// `Array.prototype[@@iterator]` method\n// https://tc39.github.io/ecma262/#sec-array.prototype-@@iterator\n// `CreateArrayIterator` internal method\n// https://tc39.github.io/ecma262/#sec-createarrayiterator\nmodule.exports = defineIterator(Array, 'Array', function (iterated, kind) {\n setInternalState(this, {\n type: ARRAY_ITERATOR,\n target: toIndexedObject(iterated), // target\n index: 0, // next index\n kind: kind // kind\n });\n// `%ArrayIteratorPrototype%.next` method\n// https://tc39.github.io/ecma262/#sec-%arrayiteratorprototype%.next\n}, function () {\n var state = getInternalState(this);\n var target = state.target;\n var kind = state.kind;\n var index = state.index++;\n if (!target || index >= target.length) {\n state.target = undefined;\n return { value: undefined, done: true };\n }\n if (kind == 'keys') return { value: index, done: false };\n if (kind == 'values') return { value: target[index], done: false };\n return { value: [index, target[index]], done: false };\n}, 'values');\n\n// argumentsList[@@iterator] is %ArrayProto_values%\n// https://tc39.github.io/ecma262/#sec-createunmappedargumentsobject\n// https://tc39.github.io/ecma262/#sec-createmappedargumentsobject\nIterators.Arguments = Iterators.Array;\n\n// https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables\naddToUnscopables('keys');\naddToUnscopables('values');\naddToUnscopables('entries');\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLmFycmF5Lml0ZXJhdG9yLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLmFycmF5Lml0ZXJhdG9yLmpzP2UyNjAiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xudmFyIHRvSW5kZXhlZE9iamVjdCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy90by1pbmRleGVkLW9iamVjdCcpO1xudmFyIGFkZFRvVW5zY29wYWJsZXMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvYWRkLXRvLXVuc2NvcGFibGVzJyk7XG52YXIgSXRlcmF0b3JzID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2l0ZXJhdG9ycycpO1xudmFyIEludGVybmFsU3RhdGVNb2R1bGUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaW50ZXJuYWwtc3RhdGUnKTtcbnZhciBkZWZpbmVJdGVyYXRvciA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9kZWZpbmUtaXRlcmF0b3InKTtcblxudmFyIEFSUkFZX0lURVJBVE9SID0gJ0FycmF5IEl0ZXJhdG9yJztcbnZhciBzZXRJbnRlcm5hbFN0YXRlID0gSW50ZXJuYWxTdGF0ZU1vZHVsZS5zZXQ7XG52YXIgZ2V0SW50ZXJuYWxTdGF0ZSA9IEludGVybmFsU3RhdGVNb2R1bGUuZ2V0dGVyRm9yKEFSUkFZX0lURVJBVE9SKTtcblxuLy8gYEFycmF5LnByb3RvdHlwZS5lbnRyaWVzYCBtZXRob2Rcbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLWFycmF5LnByb3RvdHlwZS5lbnRyaWVzXG4vLyBgQXJyYXkucHJvdG90eXBlLmtleXNgIG1ldGhvZFxuLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtYXJyYXkucHJvdG90eXBlLmtleXNcbi8vIGBBcnJheS5wcm90b3R5cGUudmFsdWVzYCBtZXRob2Rcbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLWFycmF5LnByb3RvdHlwZS52YWx1ZXNcbi8vIGBBcnJheS5wcm90b3R5cGVbQEBpdGVyYXRvcl1gIG1ldGhvZFxuLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtYXJyYXkucHJvdG90eXBlLUBAaXRlcmF0b3Jcbi8vIGBDcmVhdGVBcnJheUl0ZXJhdG9yYCBpbnRlcm5hbCBtZXRob2Rcbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLWNyZWF0ZWFycmF5aXRlcmF0b3Jcbm1vZHVsZS5leHBvcnRzID0gZGVmaW5lSXRlcmF0b3IoQXJyYXksICdBcnJheScsIGZ1bmN0aW9uIChpdGVyYXRlZCwga2luZCkge1xuICBzZXRJbnRlcm5hbFN0YXRlKHRoaXMsIHtcbiAgICB0eXBlOiBBUlJBWV9JVEVSQVRPUixcbiAgICB0YXJnZXQ6IHRvSW5kZXhlZE9iamVjdChpdGVyYXRlZCksIC8vIHRhcmdldFxuICAgIGluZGV4OiAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbmV4dCBpbmRleFxuICAgIGtpbmQ6IGtpbmQgICAgICAgICAgICAgICAgICAgICAgICAgLy8ga2luZFxuICB9KTtcbi8vIGAlQXJyYXlJdGVyYXRvclByb3RvdHlwZSUubmV4dGAgbWV0aG9kXG4vLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy0lYXJyYXlpdGVyYXRvcnByb3RvdHlwZSUubmV4dFxufSwgZnVuY3Rpb24gKCkge1xuICB2YXIgc3RhdGUgPSBnZXRJbnRlcm5hbFN0YXRlKHRoaXMpO1xuICB2YXIgdGFyZ2V0ID0gc3RhdGUudGFyZ2V0O1xuICB2YXIga2luZCA9IHN0YXRlLmtpbmQ7XG4gIHZhciBpbmRleCA9IHN0YXRlLmluZGV4Kys7XG4gIGlmICghdGFyZ2V0IHx8IGluZGV4ID49IHRhcmdldC5sZW5ndGgpIHtcbiAgICBzdGF0ZS50YXJnZXQgPSB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIHsgdmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZSB9O1xuICB9XG4gIGlmIChraW5kID09ICdrZXlzJykgcmV0dXJuIHsgdmFsdWU6IGluZGV4LCBkb25lOiBmYWxzZSB9O1xuICBpZiAoa2luZCA9PSAndmFsdWVzJykgcmV0dXJuIHsgdmFsdWU6IHRhcmdldFtpbmRleF0sIGRvbmU6IGZhbHNlIH07XG4gIHJldHVybiB7IHZhbHVlOiBbaW5kZXgsIHRhcmdldFtpbmRleF1dLCBkb25lOiBmYWxzZSB9O1xufSwgJ3ZhbHVlcycpO1xuXG4vLyBhcmd1bWVudHNMaXN0W0BAaXRlcmF0b3JdIGlzICVBcnJheVByb3RvX3ZhbHVlcyVcbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLWNyZWF0ZXVubWFwcGVkYXJndW1lbnRzb2JqZWN0XG4vLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1jcmVhdGVtYXBwZWRhcmd1bWVudHNvYmplY3Rcbkl0ZXJhdG9ycy5Bcmd1bWVudHMgPSBJdGVyYXRvcnMuQXJyYXk7XG5cbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLWFycmF5LnByb3RvdHlwZS1AQHVuc2NvcGFibGVzXG5hZGRUb1Vuc2NvcGFibGVzKCdrZXlzJyk7XG5hZGRUb1Vuc2NvcGFibGVzKCd2YWx1ZXMnKTtcbmFkZFRvVW5zY29wYWJsZXMoJ2VudHJpZXMnKTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.array.iterator.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.object.to-string.js": +/*!*************************************************************!*\ + !*** ./node_modules/core-js/modules/es.object.to-string.js ***! + \*************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var redefine = __webpack_require__(/*! ../internals/redefine */ \"./node_modules/core-js/internals/redefine.js\");\nvar toString = __webpack_require__(/*! ../internals/object-to-string */ \"./node_modules/core-js/internals/object-to-string.js\");\n\nvar ObjectPrototype = Object.prototype;\n\n// `Object.prototype.toString` method\n// https://tc39.github.io/ecma262/#sec-object.prototype.tostring\nif (toString !== ObjectPrototype.toString) {\n redefine(ObjectPrototype, 'toString', toString, { unsafe: true });\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLm9iamVjdC50by1zdHJpbmcuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXMub2JqZWN0LnRvLXN0cmluZy5qcz9kM2I3Il0sInNvdXJjZXNDb250ZW50IjpbInZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9yZWRlZmluZScpO1xudmFyIHRvU3RyaW5nID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL29iamVjdC10by1zdHJpbmcnKTtcblxudmFyIE9iamVjdFByb3RvdHlwZSA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8vIGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nYCBtZXRob2Rcbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmdcbmlmICh0b1N0cmluZyAhPT0gT2JqZWN0UHJvdG90eXBlLnRvU3RyaW5nKSB7XG4gIHJlZGVmaW5lKE9iamVjdFByb3RvdHlwZSwgJ3RvU3RyaW5nJywgdG9TdHJpbmcsIHsgdW5zYWZlOiB0cnVlIH0pO1xufVxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.object.to-string.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.promise.finally.js": +/*!************************************************************!*\ + !*** ./node_modules/core-js/modules/es.promise.finally.js ***! + \************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar getBuiltIn = __webpack_require__(/*! ../internals/get-built-in */ \"./node_modules/core-js/internals/get-built-in.js\");\nvar speciesConstructor = __webpack_require__(/*! ../internals/species-constructor */ \"./node_modules/core-js/internals/species-constructor.js\");\nvar promiseResolve = __webpack_require__(/*! ../internals/promise-resolve */ \"./node_modules/core-js/internals/promise-resolve.js\");\n\n// `Promise.prototype.finally` method\n// https://tc39.github.io/ecma262/#sec-promise.prototype.finally\n$({ target: 'Promise', proto: true, real: true }, {\n 'finally': function (onFinally) {\n var C = speciesConstructor(this, getBuiltIn('Promise'));\n var isFunction = typeof onFinally == 'function';\n return this.then(\n isFunction ? function (x) {\n return promiseResolve(C, onFinally()).then(function () { return x; });\n } : onFinally,\n isFunction ? function (e) {\n return promiseResolve(C, onFinally()).then(function () { throw e; });\n } : onFinally\n );\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnByb21pc2UuZmluYWxseS5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lcy5wcm9taXNlLmZpbmFsbHkuanM/YTc5ZCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG52YXIgJCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9leHBvcnQnKTtcbnZhciBnZXRCdWlsdEluID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2dldC1idWlsdC1pbicpO1xudmFyIHNwZWNpZXNDb25zdHJ1Y3RvciA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9zcGVjaWVzLWNvbnN0cnVjdG9yJyk7XG52YXIgcHJvbWlzZVJlc29sdmUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvcHJvbWlzZS1yZXNvbHZlJyk7XG5cbi8vIGBQcm9taXNlLnByb3RvdHlwZS5maW5hbGx5YCBtZXRob2Rcbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXByb21pc2UucHJvdG90eXBlLmZpbmFsbHlcbiQoeyB0YXJnZXQ6ICdQcm9taXNlJywgcHJvdG86IHRydWUsIHJlYWw6IHRydWUgfSwge1xuICAnZmluYWxseSc6IGZ1bmN0aW9uIChvbkZpbmFsbHkpIHtcbiAgICB2YXIgQyA9IHNwZWNpZXNDb25zdHJ1Y3Rvcih0aGlzLCBnZXRCdWlsdEluKCdQcm9taXNlJykpO1xuICAgIHZhciBpc0Z1bmN0aW9uID0gdHlwZW9mIG9uRmluYWxseSA9PSAnZnVuY3Rpb24nO1xuICAgIHJldHVybiB0aGlzLnRoZW4oXG4gICAgICBpc0Z1bmN0aW9uID8gZnVuY3Rpb24gKHgpIHtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlKEMsIG9uRmluYWxseSgpKS50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHg7IH0pO1xuICAgICAgfSA6IG9uRmluYWxseSxcbiAgICAgIGlzRnVuY3Rpb24gPyBmdW5jdGlvbiAoZSkge1xuICAgICAgICByZXR1cm4gcHJvbWlzZVJlc29sdmUoQywgb25GaW5hbGx5KCkpLnRoZW4oZnVuY3Rpb24gKCkgeyB0aHJvdyBlOyB9KTtcbiAgICAgIH0gOiBvbkZpbmFsbHlcbiAgICApO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.promise.finally.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.promise.js": +/*!****************************************************!*\ + !*** ./node_modules/core-js/modules/es.promise.js ***! + \****************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar IS_PURE = __webpack_require__(/*! ../internals/is-pure */ \"./node_modules/core-js/internals/is-pure.js\");\nvar global = __webpack_require__(/*! ../internals/global */ \"./node_modules/core-js/internals/global.js\");\nvar path = __webpack_require__(/*! ../internals/path */ \"./node_modules/core-js/internals/path.js\");\nvar redefineAll = __webpack_require__(/*! ../internals/redefine-all */ \"./node_modules/core-js/internals/redefine-all.js\");\nvar setToStringTag = __webpack_require__(/*! ../internals/set-to-string-tag */ \"./node_modules/core-js/internals/set-to-string-tag.js\");\nvar setSpecies = __webpack_require__(/*! ../internals/set-species */ \"./node_modules/core-js/internals/set-species.js\");\nvar isObject = __webpack_require__(/*! ../internals/is-object */ \"./node_modules/core-js/internals/is-object.js\");\nvar aFunction = __webpack_require__(/*! ../internals/a-function */ \"./node_modules/core-js/internals/a-function.js\");\nvar anInstance = __webpack_require__(/*! ../internals/an-instance */ \"./node_modules/core-js/internals/an-instance.js\");\nvar classof = __webpack_require__(/*! ../internals/classof-raw */ \"./node_modules/core-js/internals/classof-raw.js\");\nvar iterate = __webpack_require__(/*! ../internals/iterate */ \"./node_modules/core-js/internals/iterate.js\");\nvar checkCorrectnessOfIteration = __webpack_require__(/*! ../internals/check-correctness-of-iteration */ \"./node_modules/core-js/internals/check-correctness-of-iteration.js\");\nvar speciesConstructor = __webpack_require__(/*! ../internals/species-constructor */ \"./node_modules/core-js/internals/species-constructor.js\");\nvar task = __webpack_require__(/*! ../internals/task */ \"./node_modules/core-js/internals/task.js\").set;\nvar microtask = __webpack_require__(/*! ../internals/microtask */ \"./node_modules/core-js/internals/microtask.js\");\nvar promiseResolve = __webpack_require__(/*! ../internals/promise-resolve */ \"./node_modules/core-js/internals/promise-resolve.js\");\nvar hostReportErrors = __webpack_require__(/*! ../internals/host-report-errors */ \"./node_modules/core-js/internals/host-report-errors.js\");\nvar newPromiseCapabilityModule = __webpack_require__(/*! ../internals/new-promise-capability */ \"./node_modules/core-js/internals/new-promise-capability.js\");\nvar perform = __webpack_require__(/*! ../internals/perform */ \"./node_modules/core-js/internals/perform.js\");\nvar userAgent = __webpack_require__(/*! ../internals/user-agent */ \"./node_modules/core-js/internals/user-agent.js\");\nvar InternalStateModule = __webpack_require__(/*! ../internals/internal-state */ \"./node_modules/core-js/internals/internal-state.js\");\nvar isForced = __webpack_require__(/*! ../internals/is-forced */ \"./node_modules/core-js/internals/is-forced.js\");\nvar wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ \"./node_modules/core-js/internals/well-known-symbol.js\");\n\nvar SPECIES = wellKnownSymbol('species');\nvar PROMISE = 'Promise';\nvar getInternalState = InternalStateModule.get;\nvar setInternalState = InternalStateModule.set;\nvar getInternalPromiseState = InternalStateModule.getterFor(PROMISE);\nvar PromiseConstructor = global[PROMISE];\nvar TypeError = global.TypeError;\nvar document = global.document;\nvar process = global.process;\nvar $fetch = global.fetch;\nvar versions = process && process.versions;\nvar v8 = versions && versions.v8 || '';\nvar newPromiseCapability = newPromiseCapabilityModule.f;\nvar newGenericPromiseCapability = newPromiseCapability;\nvar IS_NODE = classof(process) == 'process';\nvar DISPATCH_EVENT = !!(document && document.createEvent && global.dispatchEvent);\nvar UNHANDLED_REJECTION = 'unhandledrejection';\nvar REJECTION_HANDLED = 'rejectionhandled';\nvar PENDING = 0;\nvar FULFILLED = 1;\nvar REJECTED = 2;\nvar HANDLED = 1;\nvar UNHANDLED = 2;\nvar Internal, OwnPromiseCapability, PromiseWrapper;\n\nvar FORCED = isForced(PROMISE, function () {\n // correct subclassing with @@species support\n var promise = PromiseConstructor.resolve(1);\n var empty = function () { /* empty */ };\n var FakePromise = (promise.constructor = {})[SPECIES] = function (exec) {\n exec(empty, empty);\n };\n // unhandled rejections tracking support, NodeJS Promise without it fails @@species test\n return !((IS_NODE || typeof PromiseRejectionEvent == 'function')\n && (!IS_PURE || promise['finally'])\n && promise.then(empty) instanceof FakePromise\n // v8 6.6 (Node 10 and Chrome 66) have a bug with resolving custom thenables\n // https://bugs.chromium.org/p/chromium/issues/detail?id=830565\n // we can't detect it synchronously, so just check versions\n && v8.indexOf('6.6') !== 0\n && userAgent.indexOf('Chrome/66') === -1);\n});\n\nvar INCORRECT_ITERATION = FORCED || !checkCorrectnessOfIteration(function (iterable) {\n PromiseConstructor.all(iterable)['catch'](function () { /* empty */ });\n});\n\n// helpers\nvar isThenable = function (it) {\n var then;\n return isObject(it) && typeof (then = it.then) == 'function' ? then : false;\n};\n\nvar notify = function (promise, state, isReject) {\n if (state.notified) return;\n state.notified = true;\n var chain = state.reactions;\n microtask(function () {\n var value = state.value;\n var ok = state.state == FULFILLED;\n var i = 0;\n var run = function (reaction) {\n var handler = ok ? reaction.ok : reaction.fail;\n var resolve = reaction.resolve;\n var reject = reaction.reject;\n var domain = reaction.domain;\n var result, then, exited;\n try {\n if (handler) {\n if (!ok) {\n if (state.rejection === UNHANDLED) onHandleUnhandled(promise, state);\n state.rejection = HANDLED;\n }\n if (handler === true) result = value;\n else {\n if (domain) domain.enter();\n result = handler(value); // may throw\n if (domain) {\n domain.exit();\n exited = true;\n }\n }\n if (result === reaction.promise) {\n reject(TypeError('Promise-chain cycle'));\n } else if (then = isThenable(result)) {\n then.call(result, resolve, reject);\n } else resolve(result);\n } else reject(value);\n } catch (error) {\n if (domain && !exited) domain.exit();\n reject(error);\n }\n };\n while (chain.length > i) run(chain[i++]); // variable length - can't use forEach\n state.reactions = [];\n state.notified = false;\n if (isReject && !state.rejection) onUnhandled(promise, state);\n });\n};\n\nvar dispatchEvent = function (name, promise, reason) {\n var event, handler;\n if (DISPATCH_EVENT) {\n event = document.createEvent('Event');\n event.promise = promise;\n event.reason = reason;\n event.initEvent(name, false, true);\n global.dispatchEvent(event);\n } else event = { promise: promise, reason: reason };\n if (handler = global['on' + name]) handler(event);\n else if (name === UNHANDLED_REJECTION) hostReportErrors('Unhandled promise rejection', reason);\n};\n\nvar onUnhandled = function (promise, state) {\n task.call(global, function () {\n var value = state.value;\n var IS_UNHANDLED = isUnhandled(state);\n var result;\n if (IS_UNHANDLED) {\n result = perform(function () {\n if (IS_NODE) {\n process.emit('unhandledRejection', value, promise);\n } else dispatchEvent(UNHANDLED_REJECTION, promise, value);\n });\n // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should\n state.rejection = IS_NODE || isUnhandled(state) ? UNHANDLED : HANDLED;\n if (result.error) throw result.value;\n }\n });\n};\n\nvar isUnhandled = function (state) {\n return state.rejection !== HANDLED && !state.parent;\n};\n\nvar onHandleUnhandled = function (promise, state) {\n task.call(global, function () {\n if (IS_NODE) {\n process.emit('rejectionHandled', promise);\n } else dispatchEvent(REJECTION_HANDLED, promise, state.value);\n });\n};\n\nvar bind = function (fn, promise, state, unwrap) {\n return function (value) {\n fn(promise, state, value, unwrap);\n };\n};\n\nvar internalReject = function (promise, state, value, unwrap) {\n if (state.done) return;\n state.done = true;\n if (unwrap) state = unwrap;\n state.value = value;\n state.state = REJECTED;\n notify(promise, state, true);\n};\n\nvar internalResolve = function (promise, state, value, unwrap) {\n if (state.done) return;\n state.done = true;\n if (unwrap) state = unwrap;\n try {\n if (promise === value) throw TypeError(\"Promise can't be resolved itself\");\n var then = isThenable(value);\n if (then) {\n microtask(function () {\n var wrapper = { done: false };\n try {\n then.call(value,\n bind(internalResolve, promise, wrapper, state),\n bind(internalReject, promise, wrapper, state)\n );\n } catch (error) {\n internalReject(promise, wrapper, error, state);\n }\n });\n } else {\n state.value = value;\n state.state = FULFILLED;\n notify(promise, state, false);\n }\n } catch (error) {\n internalReject(promise, { done: false }, error, state);\n }\n};\n\n// constructor polyfill\nif (FORCED) {\n // 25.4.3.1 Promise(executor)\n PromiseConstructor = function Promise(executor) {\n anInstance(this, PromiseConstructor, PROMISE);\n aFunction(executor);\n Internal.call(this);\n var state = getInternalState(this);\n try {\n executor(bind(internalResolve, this, state), bind(internalReject, this, state));\n } catch (error) {\n internalReject(this, state, error);\n }\n };\n // eslint-disable-next-line no-unused-vars\n Internal = function Promise(executor) {\n setInternalState(this, {\n type: PROMISE,\n done: false,\n notified: false,\n parent: false,\n reactions: [],\n rejection: false,\n state: PENDING,\n value: undefined\n });\n };\n Internal.prototype = redefineAll(PromiseConstructor.prototype, {\n // `Promise.prototype.then` method\n // https://tc39.github.io/ecma262/#sec-promise.prototype.then\n then: function then(onFulfilled, onRejected) {\n var state = getInternalPromiseState(this);\n var reaction = newPromiseCapability(speciesConstructor(this, PromiseConstructor));\n reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;\n reaction.fail = typeof onRejected == 'function' && onRejected;\n reaction.domain = IS_NODE ? process.domain : undefined;\n state.parent = true;\n state.reactions.push(reaction);\n if (state.state != PENDING) notify(this, state, false);\n return reaction.promise;\n },\n // `Promise.prototype.catch` method\n // https://tc39.github.io/ecma262/#sec-promise.prototype.catch\n 'catch': function (onRejected) {\n return this.then(undefined, onRejected);\n }\n });\n OwnPromiseCapability = function () {\n var promise = new Internal();\n var state = getInternalState(promise);\n this.promise = promise;\n this.resolve = bind(internalResolve, promise, state);\n this.reject = bind(internalReject, promise, state);\n };\n newPromiseCapabilityModule.f = newPromiseCapability = function (C) {\n return C === PromiseConstructor || C === PromiseWrapper\n ? new OwnPromiseCapability(C)\n : newGenericPromiseCapability(C);\n };\n\n // wrap fetch result\n if (!IS_PURE && typeof $fetch == 'function') $({ global: true, enumerable: true, forced: true }, {\n // eslint-disable-next-line no-unused-vars\n fetch: function fetch(input) {\n return promiseResolve(PromiseConstructor, $fetch.apply(global, arguments));\n }\n });\n}\n\n$({ global: true, wrap: true, forced: FORCED }, {\n Promise: PromiseConstructor\n});\n\nsetToStringTag(PromiseConstructor, PROMISE, false, true);\nsetSpecies(PROMISE);\n\nPromiseWrapper = path[PROMISE];\n\n// statics\n$({ target: PROMISE, stat: true, forced: FORCED }, {\n // `Promise.reject` method\n // https://tc39.github.io/ecma262/#sec-promise.reject\n reject: function reject(r) {\n var capability = newPromiseCapability(this);\n capability.reject.call(undefined, r);\n return capability.promise;\n }\n});\n\n$({ target: PROMISE, stat: true, forced: IS_PURE || FORCED }, {\n // `Promise.resolve` method\n // https://tc39.github.io/ecma262/#sec-promise.resolve\n resolve: function resolve(x) {\n return promiseResolve(IS_PURE && this === PromiseWrapper ? PromiseConstructor : this, x);\n }\n});\n\n$({ target: PROMISE, stat: true, forced: INCORRECT_ITERATION }, {\n // `Promise.all` method\n // https://tc39.github.io/ecma262/#sec-promise.all\n all: function all(iterable) {\n var C = this;\n var capability = newPromiseCapability(C);\n var resolve = capability.resolve;\n var reject = capability.reject;\n var result = perform(function () {\n var $promiseResolve = aFunction(C.resolve);\n var values = [];\n var counter = 0;\n var remaining = 1;\n iterate(iterable, function (promise) {\n var index = counter++;\n var alreadyCalled = false;\n values.push(undefined);\n remaining++;\n $promiseResolve.call(C, promise).then(function (value) {\n if (alreadyCalled) return;\n alreadyCalled = true;\n values[index] = value;\n --remaining || resolve(values);\n }, reject);\n });\n --remaining || resolve(values);\n });\n if (result.error) reject(result.value);\n return capability.promise;\n },\n // `Promise.race` method\n // https://tc39.github.io/ecma262/#sec-promise.race\n race: function race(iterable) {\n var C = this;\n var capability = newPromiseCapability(C);\n var reject = capability.reject;\n var result = perform(function () {\n var $promiseResolve = aFunction(C.resolve);\n iterate(iterable, function (promise) {\n $promiseResolve.call(C, promise).then(capability.resolve, reject);\n });\n });\n if (result.error) reject(result.value);\n return capability.promise;\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnByb21pc2UuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXMucHJvbWlzZS5qcz9lNmNmIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcbnZhciAkID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2V4cG9ydCcpO1xudmFyIElTX1BVUkUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaXMtcHVyZScpO1xudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9nbG9iYWwnKTtcbnZhciBwYXRoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3BhdGgnKTtcbnZhciByZWRlZmluZUFsbCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9yZWRlZmluZS1hbGwnKTtcbnZhciBzZXRUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9zZXQtdG8tc3RyaW5nLXRhZycpO1xudmFyIHNldFNwZWNpZXMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvc2V0LXNwZWNpZXMnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9pcy1vYmplY3QnKTtcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvYS1mdW5jdGlvbicpO1xudmFyIGFuSW5zdGFuY2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvYW4taW5zdGFuY2UnKTtcbnZhciBjbGFzc29mID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2NsYXNzb2YtcmF3Jyk7XG52YXIgaXRlcmF0ZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9pdGVyYXRlJyk7XG52YXIgY2hlY2tDb3JyZWN0bmVzc09mSXRlcmF0aW9uID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2NoZWNrLWNvcnJlY3RuZXNzLW9mLWl0ZXJhdGlvbicpO1xudmFyIHNwZWNpZXNDb25zdHJ1Y3RvciA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9zcGVjaWVzLWNvbnN0cnVjdG9yJyk7XG52YXIgdGFzayA9IHJlcXVpcmUoJy4uL2ludGVybmFscy90YXNrJykuc2V0O1xudmFyIG1pY3JvdGFzayA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9taWNyb3Rhc2snKTtcbnZhciBwcm9taXNlUmVzb2x2ZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9wcm9taXNlLXJlc29sdmUnKTtcbnZhciBob3N0UmVwb3J0RXJyb3JzID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2hvc3QtcmVwb3J0LWVycm9ycycpO1xudmFyIG5ld1Byb21pc2VDYXBhYmlsaXR5TW9kdWxlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL25ldy1wcm9taXNlLWNhcGFiaWxpdHknKTtcbnZhciBwZXJmb3JtID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3BlcmZvcm0nKTtcbnZhciB1c2VyQWdlbnQgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvdXNlci1hZ2VudCcpO1xudmFyIEludGVybmFsU3RhdGVNb2R1bGUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaW50ZXJuYWwtc3RhdGUnKTtcbnZhciBpc0ZvcmNlZCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9pcy1mb3JjZWQnKTtcbnZhciB3ZWxsS25vd25TeW1ib2wgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvd2VsbC1rbm93bi1zeW1ib2wnKTtcblxudmFyIFNQRUNJRVMgPSB3ZWxsS25vd25TeW1ib2woJ3NwZWNpZXMnKTtcbnZhciBQUk9NSVNFID0gJ1Byb21pc2UnO1xudmFyIGdldEludGVybmFsU3RhdGUgPSBJbnRlcm5hbFN0YXRlTW9kdWxlLmdldDtcbnZhciBzZXRJbnRlcm5hbFN0YXRlID0gSW50ZXJuYWxTdGF0ZU1vZHVsZS5zZXQ7XG52YXIgZ2V0SW50ZXJuYWxQcm9taXNlU3RhdGUgPSBJbnRlcm5hbFN0YXRlTW9kdWxlLmdldHRlckZvcihQUk9NSVNFKTtcbnZhciBQcm9taXNlQ29uc3RydWN0b3IgPSBnbG9iYWxbUFJPTUlTRV07XG52YXIgVHlwZUVycm9yID0gZ2xvYmFsLlR5cGVFcnJvcjtcbnZhciBkb2N1bWVudCA9IGdsb2JhbC5kb2N1bWVudDtcbnZhciBwcm9jZXNzID0gZ2xvYmFsLnByb2Nlc3M7XG52YXIgJGZldGNoID0gZ2xvYmFsLmZldGNoO1xudmFyIHZlcnNpb25zID0gcHJvY2VzcyAmJiBwcm9jZXNzLnZlcnNpb25zO1xudmFyIHY4ID0gdmVyc2lvbnMgJiYgdmVyc2lvbnMudjggfHwgJyc7XG52YXIgbmV3UHJvbWlzZUNhcGFiaWxpdHkgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eU1vZHVsZS5mO1xudmFyIG5ld0dlbmVyaWNQcm9taXNlQ2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5O1xudmFyIElTX05PREUgPSBjbGFzc29mKHByb2Nlc3MpID09ICdwcm9jZXNzJztcbnZhciBESVNQQVRDSF9FVkVOVCA9ICEhKGRvY3VtZW50ICYmIGRvY3VtZW50LmNyZWF0ZUV2ZW50ICYmIGdsb2JhbC5kaXNwYXRjaEV2ZW50KTtcbnZhciBVTkhBTkRMRURfUkVKRUNUSU9OID0gJ3VuaGFuZGxlZHJlamVjdGlvbic7XG52YXIgUkVKRUNUSU9OX0hBTkRMRUQgPSAncmVqZWN0aW9uaGFuZGxlZCc7XG52YXIgUEVORElORyA9IDA7XG52YXIgRlVMRklMTEVEID0gMTtcbnZhciBSRUpFQ1RFRCA9IDI7XG52YXIgSEFORExFRCA9IDE7XG52YXIgVU5IQU5ETEVEID0gMjtcbnZhciBJbnRlcm5hbCwgT3duUHJvbWlzZUNhcGFiaWxpdHksIFByb21pc2VXcmFwcGVyO1xuXG52YXIgRk9SQ0VEID0gaXNGb3JjZWQoUFJPTUlTRSwgZnVuY3Rpb24gKCkge1xuICAvLyBjb3JyZWN0IHN1YmNsYXNzaW5nIHdpdGggQEBzcGVjaWVzIHN1cHBvcnRcbiAgdmFyIHByb21pc2UgPSBQcm9taXNlQ29uc3RydWN0b3IucmVzb2x2ZSgxKTtcbiAgdmFyIGVtcHR5ID0gZnVuY3Rpb24gKCkgeyAvKiBlbXB0eSAqLyB9O1xuICB2YXIgRmFrZVByb21pc2UgPSAocHJvbWlzZS5jb25zdHJ1Y3RvciA9IHt9KVtTUEVDSUVTXSA9IGZ1bmN0aW9uIChleGVjKSB7XG4gICAgZXhlYyhlbXB0eSwgZW1wdHkpO1xuICB9O1xuICAvLyB1bmhhbmRsZWQgcmVqZWN0aW9ucyB0cmFja2luZyBzdXBwb3J0LCBOb2RlSlMgUHJvbWlzZSB3aXRob3V0IGl0IGZhaWxzIEBAc3BlY2llcyB0ZXN0XG4gIHJldHVybiAhKChJU19OT0RFIHx8IHR5cGVvZiBQcm9taXNlUmVqZWN0aW9uRXZlbnQgPT0gJ2Z1bmN0aW9uJylcbiAgICAmJiAoIUlTX1BVUkUgfHwgcHJvbWlzZVsnZmluYWxseSddKVxuICAgICYmIHByb21pc2UudGhlbihlbXB0eSkgaW5zdGFuY2VvZiBGYWtlUHJvbWlzZVxuICAgIC8vIHY4IDYuNiAoTm9kZSAxMCBhbmQgQ2hyb21lIDY2KSBoYXZlIGEgYnVnIHdpdGggcmVzb2x2aW5nIGN1c3RvbSB0aGVuYWJsZXNcbiAgICAvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD04MzA1NjVcbiAgICAvLyB3ZSBjYW4ndCBkZXRlY3QgaXQgc3luY2hyb25vdXNseSwgc28ganVzdCBjaGVjayB2ZXJzaW9uc1xuICAgICYmIHY4LmluZGV4T2YoJzYuNicpICE9PSAwXG4gICAgJiYgdXNlckFnZW50LmluZGV4T2YoJ0Nocm9tZS82NicpID09PSAtMSk7XG59KTtcblxudmFyIElOQ09SUkVDVF9JVEVSQVRJT04gPSBGT1JDRUQgfHwgIWNoZWNrQ29ycmVjdG5lc3NPZkl0ZXJhdGlvbihmdW5jdGlvbiAoaXRlcmFibGUpIHtcbiAgUHJvbWlzZUNvbnN0cnVjdG9yLmFsbChpdGVyYWJsZSlbJ2NhdGNoJ10oZnVuY3Rpb24gKCkgeyAvKiBlbXB0eSAqLyB9KTtcbn0pO1xuXG4vLyBoZWxwZXJzXG52YXIgaXNUaGVuYWJsZSA9IGZ1bmN0aW9uIChpdCkge1xuICB2YXIgdGhlbjtcbiAgcmV0dXJuIGlzT2JqZWN0KGl0KSAmJiB0eXBlb2YgKHRoZW4gPSBpdC50aGVuKSA9PSAnZnVuY3Rpb24nID8gdGhlbiA6IGZhbHNlO1xufTtcblxudmFyIG5vdGlmeSA9IGZ1bmN0aW9uIChwcm9taXNlLCBzdGF0ZSwgaXNSZWplY3QpIHtcbiAgaWYgKHN0YXRlLm5vdGlmaWVkKSByZXR1cm47XG4gIHN0YXRlLm5vdGlmaWVkID0gdHJ1ZTtcbiAgdmFyIGNoYWluID0gc3RhdGUucmVhY3Rpb25zO1xuICBtaWNyb3Rhc2soZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZSA9IHN0YXRlLnZhbHVlO1xuICAgIHZhciBvayA9IHN0YXRlLnN0YXRlID09IEZVTEZJTExFRDtcbiAgICB2YXIgaSA9IDA7XG4gICAgdmFyIHJ1biA9IGZ1bmN0aW9uIChyZWFjdGlvbikge1xuICAgICAgdmFyIGhhbmRsZXIgPSBvayA/IHJlYWN0aW9uLm9rIDogcmVhY3Rpb24uZmFpbDtcbiAgICAgIHZhciByZXNvbHZlID0gcmVhY3Rpb24ucmVzb2x2ZTtcbiAgICAgIHZhciByZWplY3QgPSByZWFjdGlvbi5yZWplY3Q7XG4gICAgICB2YXIgZG9tYWluID0gcmVhY3Rpb24uZG9tYWluO1xuICAgICAgdmFyIHJlc3VsdCwgdGhlbiwgZXhpdGVkO1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKGhhbmRsZXIpIHtcbiAgICAgICAgICBpZiAoIW9rKSB7XG4gICAgICAgICAgICBpZiAoc3RhdGUucmVqZWN0aW9uID09PSBVTkhBTkRMRUQpIG9uSGFuZGxlVW5oYW5kbGVkKHByb21pc2UsIHN0YXRlKTtcbiAgICAgICAgICAgIHN0YXRlLnJlamVjdGlvbiA9IEhBTkRMRUQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChoYW5kbGVyID09PSB0cnVlKSByZXN1bHQgPSB2YWx1ZTtcbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChkb21haW4pIGRvbWFpbi5lbnRlcigpO1xuICAgICAgICAgICAgcmVzdWx0ID0gaGFuZGxlcih2YWx1ZSk7IC8vIG1heSB0aHJvd1xuICAgICAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgICBkb21haW4uZXhpdCgpO1xuICAgICAgICAgICAgICBleGl0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocmVzdWx0ID09PSByZWFjdGlvbi5wcm9taXNlKSB7XG4gICAgICAgICAgICByZWplY3QoVHlwZUVycm9yKCdQcm9taXNlLWNoYWluIGN5Y2xlJykpO1xuICAgICAgICAgIH0gZWxzZSBpZiAodGhlbiA9IGlzVGhlbmFibGUocmVzdWx0KSkge1xuICAgICAgICAgICAgdGhlbi5jYWxsKHJlc3VsdCwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgICB9IGVsc2UgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9IGVsc2UgcmVqZWN0KHZhbHVlKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGlmIChkb21haW4gJiYgIWV4aXRlZCkgZG9tYWluLmV4aXQoKTtcbiAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIHdoaWxlIChjaGFpbi5sZW5ndGggPiBpKSBydW4oY2hhaW5baSsrXSk7IC8vIHZhcmlhYmxlIGxlbmd0aCAtIGNhbid0IHVzZSBmb3JFYWNoXG4gICAgc3RhdGUucmVhY3Rpb25zID0gW107XG4gICAgc3RhdGUubm90aWZpZWQgPSBmYWxzZTtcbiAgICBpZiAoaXNSZWplY3QgJiYgIXN0YXRlLnJlamVjdGlvbikgb25VbmhhbmRsZWQocHJvbWlzZSwgc3RhdGUpO1xuICB9KTtcbn07XG5cbnZhciBkaXNwYXRjaEV2ZW50ID0gZnVuY3Rpb24gKG5hbWUsIHByb21pc2UsIHJlYXNvbikge1xuICB2YXIgZXZlbnQsIGhhbmRsZXI7XG4gIGlmIChESVNQQVRDSF9FVkVOVCkge1xuICAgIGV2ZW50ID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoJ0V2ZW50Jyk7XG4gICAgZXZlbnQucHJvbWlzZSA9IHByb21pc2U7XG4gICAgZXZlbnQucmVhc29uID0gcmVhc29uO1xuICAgIGV2ZW50LmluaXRFdmVudChuYW1lLCBmYWxzZSwgdHJ1ZSk7XG4gICAgZ2xvYmFsLmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuICB9IGVsc2UgZXZlbnQgPSB7IHByb21pc2U6IHByb21pc2UsIHJlYXNvbjogcmVhc29uIH07XG4gIGlmIChoYW5kbGVyID0gZ2xvYmFsWydvbicgKyBuYW1lXSkgaGFuZGxlcihldmVudCk7XG4gIGVsc2UgaWYgKG5hbWUgPT09IFVOSEFORExFRF9SRUpFQ1RJT04pIGhvc3RSZXBvcnRFcnJvcnMoJ1VuaGFuZGxlZCBwcm9taXNlIHJlamVjdGlvbicsIHJlYXNvbik7XG59O1xuXG52YXIgb25VbmhhbmRsZWQgPSBmdW5jdGlvbiAocHJvbWlzZSwgc3RhdGUpIHtcbiAgdGFzay5jYWxsKGdsb2JhbCwgZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZSA9IHN0YXRlLnZhbHVlO1xuICAgIHZhciBJU19VTkhBTkRMRUQgPSBpc1VuaGFuZGxlZChzdGF0ZSk7XG4gICAgdmFyIHJlc3VsdDtcbiAgICBpZiAoSVNfVU5IQU5ETEVEKSB7XG4gICAgICByZXN1bHQgPSBwZXJmb3JtKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKElTX05PREUpIHtcbiAgICAgICAgICBwcm9jZXNzLmVtaXQoJ3VuaGFuZGxlZFJlamVjdGlvbicsIHZhbHVlLCBwcm9taXNlKTtcbiAgICAgICAgfSBlbHNlIGRpc3BhdGNoRXZlbnQoVU5IQU5ETEVEX1JFSkVDVElPTiwgcHJvbWlzZSwgdmFsdWUpO1xuICAgICAgfSk7XG4gICAgICAvLyBCcm93c2VycyBzaG91bGQgbm90IHRyaWdnZXIgYHJlamVjdGlvbkhhbmRsZWRgIGV2ZW50IGlmIGl0IHdhcyBoYW5kbGVkIGhlcmUsIE5vZGVKUyAtIHNob3VsZFxuICAgICAgc3RhdGUucmVqZWN0aW9uID0gSVNfTk9ERSB8fCBpc1VuaGFuZGxlZChzdGF0ZSkgPyBVTkhBTkRMRUQgOiBIQU5ETEVEO1xuICAgICAgaWYgKHJlc3VsdC5lcnJvcikgdGhyb3cgcmVzdWx0LnZhbHVlO1xuICAgIH1cbiAgfSk7XG59O1xuXG52YXIgaXNVbmhhbmRsZWQgPSBmdW5jdGlvbiAoc3RhdGUpIHtcbiAgcmV0dXJuIHN0YXRlLnJlamVjdGlvbiAhPT0gSEFORExFRCAmJiAhc3RhdGUucGFyZW50O1xufTtcblxudmFyIG9uSGFuZGxlVW5oYW5kbGVkID0gZnVuY3Rpb24gKHByb21pc2UsIHN0YXRlKSB7XG4gIHRhc2suY2FsbChnbG9iYWwsIGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoSVNfTk9ERSkge1xuICAgICAgcHJvY2Vzcy5lbWl0KCdyZWplY3Rpb25IYW5kbGVkJywgcHJvbWlzZSk7XG4gICAgfSBlbHNlIGRpc3BhdGNoRXZlbnQoUkVKRUNUSU9OX0hBTkRMRUQsIHByb21pc2UsIHN0YXRlLnZhbHVlKTtcbiAgfSk7XG59O1xuXG52YXIgYmluZCA9IGZ1bmN0aW9uIChmbiwgcHJvbWlzZSwgc3RhdGUsIHVud3JhcCkge1xuICByZXR1cm4gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgZm4ocHJvbWlzZSwgc3RhdGUsIHZhbHVlLCB1bndyYXApO1xuICB9O1xufTtcblxudmFyIGludGVybmFsUmVqZWN0ID0gZnVuY3Rpb24gKHByb21pc2UsIHN0YXRlLCB2YWx1ZSwgdW53cmFwKSB7XG4gIGlmIChzdGF0ZS5kb25lKSByZXR1cm47XG4gIHN0YXRlLmRvbmUgPSB0cnVlO1xuICBpZiAodW53cmFwKSBzdGF0ZSA9IHVud3JhcDtcbiAgc3RhdGUudmFsdWUgPSB2YWx1ZTtcbiAgc3RhdGUuc3RhdGUgPSBSRUpFQ1RFRDtcbiAgbm90aWZ5KHByb21pc2UsIHN0YXRlLCB0cnVlKTtcbn07XG5cbnZhciBpbnRlcm5hbFJlc29sdmUgPSBmdW5jdGlvbiAocHJvbWlzZSwgc3RhdGUsIHZhbHVlLCB1bndyYXApIHtcbiAgaWYgKHN0YXRlLmRvbmUpIHJldHVybjtcbiAgc3RhdGUuZG9uZSA9IHRydWU7XG4gIGlmICh1bndyYXApIHN0YXRlID0gdW53cmFwO1xuICB0cnkge1xuICAgIGlmIChwcm9taXNlID09PSB2YWx1ZSkgdGhyb3cgVHlwZUVycm9yKFwiUHJvbWlzZSBjYW4ndCBiZSByZXNvbHZlZCBpdHNlbGZcIik7XG4gICAgdmFyIHRoZW4gPSBpc1RoZW5hYmxlKHZhbHVlKTtcbiAgICBpZiAodGhlbikge1xuICAgICAgbWljcm90YXNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHdyYXBwZXIgPSB7IGRvbmU6IGZhbHNlIH07XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdGhlbi5jYWxsKHZhbHVlLFxuICAgICAgICAgICAgYmluZChpbnRlcm5hbFJlc29sdmUsIHByb21pc2UsIHdyYXBwZXIsIHN0YXRlKSxcbiAgICAgICAgICAgIGJpbmQoaW50ZXJuYWxSZWplY3QsIHByb21pc2UsIHdyYXBwZXIsIHN0YXRlKVxuICAgICAgICAgICk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgaW50ZXJuYWxSZWplY3QocHJvbWlzZSwgd3JhcHBlciwgZXJyb3IsIHN0YXRlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXRlLnZhbHVlID0gdmFsdWU7XG4gICAgICBzdGF0ZS5zdGF0ZSA9IEZVTEZJTExFRDtcbiAgICAgIG5vdGlmeShwcm9taXNlLCBzdGF0ZSwgZmFsc2UpO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpbnRlcm5hbFJlamVjdChwcm9taXNlLCB7IGRvbmU6IGZhbHNlIH0sIGVycm9yLCBzdGF0ZSk7XG4gIH1cbn07XG5cbi8vIGNvbnN0cnVjdG9yIHBvbHlmaWxsXG5pZiAoRk9SQ0VEKSB7XG4gIC8vIDI1LjQuMy4xIFByb21pc2UoZXhlY3V0b3IpXG4gIFByb21pc2VDb25zdHJ1Y3RvciA9IGZ1bmN0aW9uIFByb21pc2UoZXhlY3V0b3IpIHtcbiAgICBhbkluc3RhbmNlKHRoaXMsIFByb21pc2VDb25zdHJ1Y3RvciwgUFJPTUlTRSk7XG4gICAgYUZ1bmN0aW9uKGV4ZWN1dG9yKTtcbiAgICBJbnRlcm5hbC5jYWxsKHRoaXMpO1xuICAgIHZhciBzdGF0ZSA9IGdldEludGVybmFsU3RhdGUodGhpcyk7XG4gICAgdHJ5IHtcbiAgICAgIGV4ZWN1dG9yKGJpbmQoaW50ZXJuYWxSZXNvbHZlLCB0aGlzLCBzdGF0ZSksIGJpbmQoaW50ZXJuYWxSZWplY3QsIHRoaXMsIHN0YXRlKSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGludGVybmFsUmVqZWN0KHRoaXMsIHN0YXRlLCBlcnJvcik7XG4gICAgfVxuICB9O1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgSW50ZXJuYWwgPSBmdW5jdGlvbiBQcm9taXNlKGV4ZWN1dG9yKSB7XG4gICAgc2V0SW50ZXJuYWxTdGF0ZSh0aGlzLCB7XG4gICAgICB0eXBlOiBQUk9NSVNFLFxuICAgICAgZG9uZTogZmFsc2UsXG4gICAgICBub3RpZmllZDogZmFsc2UsXG4gICAgICBwYXJlbnQ6IGZhbHNlLFxuICAgICAgcmVhY3Rpb25zOiBbXSxcbiAgICAgIHJlamVjdGlvbjogZmFsc2UsXG4gICAgICBzdGF0ZTogUEVORElORyxcbiAgICAgIHZhbHVlOiB1bmRlZmluZWRcbiAgICB9KTtcbiAgfTtcbiAgSW50ZXJuYWwucHJvdG90eXBlID0gcmVkZWZpbmVBbGwoUHJvbWlzZUNvbnN0cnVjdG9yLnByb3RvdHlwZSwge1xuICAgIC8vIGBQcm9taXNlLnByb3RvdHlwZS50aGVuYCBtZXRob2RcbiAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1wcm9taXNlLnByb3RvdHlwZS50aGVuXG4gICAgdGhlbjogZnVuY3Rpb24gdGhlbihvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCkge1xuICAgICAgdmFyIHN0YXRlID0gZ2V0SW50ZXJuYWxQcm9taXNlU3RhdGUodGhpcyk7XG4gICAgICB2YXIgcmVhY3Rpb24gPSBuZXdQcm9taXNlQ2FwYWJpbGl0eShzcGVjaWVzQ29uc3RydWN0b3IodGhpcywgUHJvbWlzZUNvbnN0cnVjdG9yKSk7XG4gICAgICByZWFjdGlvbi5vayA9IHR5cGVvZiBvbkZ1bGZpbGxlZCA9PSAnZnVuY3Rpb24nID8gb25GdWxmaWxsZWQgOiB0cnVlO1xuICAgICAgcmVhY3Rpb24uZmFpbCA9IHR5cGVvZiBvblJlamVjdGVkID09ICdmdW5jdGlvbicgJiYgb25SZWplY3RlZDtcbiAgICAgIHJlYWN0aW9uLmRvbWFpbiA9IElTX05PREUgPyBwcm9jZXNzLmRvbWFpbiA6IHVuZGVmaW5lZDtcbiAgICAgIHN0YXRlLnBhcmVudCA9IHRydWU7XG4gICAgICBzdGF0ZS5yZWFjdGlvbnMucHVzaChyZWFjdGlvbik7XG4gICAgICBpZiAoc3RhdGUuc3RhdGUgIT0gUEVORElORykgbm90aWZ5KHRoaXMsIHN0YXRlLCBmYWxzZSk7XG4gICAgICByZXR1cm4gcmVhY3Rpb24ucHJvbWlzZTtcbiAgICB9LFxuICAgIC8vIGBQcm9taXNlLnByb3RvdHlwZS5jYXRjaGAgbWV0aG9kXG4gICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtcHJvbWlzZS5wcm90b3R5cGUuY2F0Y2hcbiAgICAnY2F0Y2gnOiBmdW5jdGlvbiAob25SZWplY3RlZCkge1xuICAgICAgcmV0dXJuIHRoaXMudGhlbih1bmRlZmluZWQsIG9uUmVqZWN0ZWQpO1xuICAgIH1cbiAgfSk7XG4gIE93blByb21pc2VDYXBhYmlsaXR5ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBwcm9taXNlID0gbmV3IEludGVybmFsKCk7XG4gICAgdmFyIHN0YXRlID0gZ2V0SW50ZXJuYWxTdGF0ZShwcm9taXNlKTtcbiAgICB0aGlzLnByb21pc2UgPSBwcm9taXNlO1xuICAgIHRoaXMucmVzb2x2ZSA9IGJpbmQoaW50ZXJuYWxSZXNvbHZlLCBwcm9taXNlLCBzdGF0ZSk7XG4gICAgdGhpcy5yZWplY3QgPSBiaW5kKGludGVybmFsUmVqZWN0LCBwcm9taXNlLCBzdGF0ZSk7XG4gIH07XG4gIG5ld1Byb21pc2VDYXBhYmlsaXR5TW9kdWxlLmYgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eSA9IGZ1bmN0aW9uIChDKSB7XG4gICAgcmV0dXJuIEMgPT09IFByb21pc2VDb25zdHJ1Y3RvciB8fCBDID09PSBQcm9taXNlV3JhcHBlclxuICAgICAgPyBuZXcgT3duUHJvbWlzZUNhcGFiaWxpdHkoQylcbiAgICAgIDogbmV3R2VuZXJpY1Byb21pc2VDYXBhYmlsaXR5KEMpO1xuICB9O1xuXG4gIC8vIHdyYXAgZmV0Y2ggcmVzdWx0XG4gIGlmICghSVNfUFVSRSAmJiB0eXBlb2YgJGZldGNoID09ICdmdW5jdGlvbicpICQoeyBnbG9iYWw6IHRydWUsIGVudW1lcmFibGU6IHRydWUsIGZvcmNlZDogdHJ1ZSB9LCB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgZmV0Y2g6IGZ1bmN0aW9uIGZldGNoKGlucHV0KSB7XG4gICAgICByZXR1cm4gcHJvbWlzZVJlc29sdmUoUHJvbWlzZUNvbnN0cnVjdG9yLCAkZmV0Y2guYXBwbHkoZ2xvYmFsLCBhcmd1bWVudHMpKTtcbiAgICB9XG4gIH0pO1xufVxuXG4kKHsgZ2xvYmFsOiB0cnVlLCB3cmFwOiB0cnVlLCBmb3JjZWQ6IEZPUkNFRCB9LCB7XG4gIFByb21pc2U6IFByb21pc2VDb25zdHJ1Y3RvclxufSk7XG5cbnNldFRvU3RyaW5nVGFnKFByb21pc2VDb25zdHJ1Y3RvciwgUFJPTUlTRSwgZmFsc2UsIHRydWUpO1xuc2V0U3BlY2llcyhQUk9NSVNFKTtcblxuUHJvbWlzZVdyYXBwZXIgPSBwYXRoW1BST01JU0VdO1xuXG4vLyBzdGF0aWNzXG4kKHsgdGFyZ2V0OiBQUk9NSVNFLCBzdGF0OiB0cnVlLCBmb3JjZWQ6IEZPUkNFRCB9LCB7XG4gIC8vIGBQcm9taXNlLnJlamVjdGAgbWV0aG9kXG4gIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXByb21pc2UucmVqZWN0XG4gIHJlamVjdDogZnVuY3Rpb24gcmVqZWN0KHIpIHtcbiAgICB2YXIgY2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5KHRoaXMpO1xuICAgIGNhcGFiaWxpdHkucmVqZWN0LmNhbGwodW5kZWZpbmVkLCByKTtcbiAgICByZXR1cm4gY2FwYWJpbGl0eS5wcm9taXNlO1xuICB9XG59KTtcblxuJCh7IHRhcmdldDogUFJPTUlTRSwgc3RhdDogdHJ1ZSwgZm9yY2VkOiBJU19QVVJFIHx8IEZPUkNFRCB9LCB7XG4gIC8vIGBQcm9taXNlLnJlc29sdmVgIG1ldGhvZFxuICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1wcm9taXNlLnJlc29sdmVcbiAgcmVzb2x2ZTogZnVuY3Rpb24gcmVzb2x2ZSh4KSB7XG4gICAgcmV0dXJuIHByb21pc2VSZXNvbHZlKElTX1BVUkUgJiYgdGhpcyA9PT0gUHJvbWlzZVdyYXBwZXIgPyBQcm9taXNlQ29uc3RydWN0b3IgOiB0aGlzLCB4KTtcbiAgfVxufSk7XG5cbiQoeyB0YXJnZXQ6IFBST01JU0UsIHN0YXQ6IHRydWUsIGZvcmNlZDogSU5DT1JSRUNUX0lURVJBVElPTiB9LCB7XG4gIC8vIGBQcm9taXNlLmFsbGAgbWV0aG9kXG4gIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXByb21pc2UuYWxsXG4gIGFsbDogZnVuY3Rpb24gYWxsKGl0ZXJhYmxlKSB7XG4gICAgdmFyIEMgPSB0aGlzO1xuICAgIHZhciBjYXBhYmlsaXR5ID0gbmV3UHJvbWlzZUNhcGFiaWxpdHkoQyk7XG4gICAgdmFyIHJlc29sdmUgPSBjYXBhYmlsaXR5LnJlc29sdmU7XG4gICAgdmFyIHJlamVjdCA9IGNhcGFiaWxpdHkucmVqZWN0O1xuICAgIHZhciByZXN1bHQgPSBwZXJmb3JtKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciAkcHJvbWlzZVJlc29sdmUgPSBhRnVuY3Rpb24oQy5yZXNvbHZlKTtcbiAgICAgIHZhciB2YWx1ZXMgPSBbXTtcbiAgICAgIHZhciBjb3VudGVyID0gMDtcbiAgICAgIHZhciByZW1haW5pbmcgPSAxO1xuICAgICAgaXRlcmF0ZShpdGVyYWJsZSwgZnVuY3Rpb24gKHByb21pc2UpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gY291bnRlcisrO1xuICAgICAgICB2YXIgYWxyZWFkeUNhbGxlZCA9IGZhbHNlO1xuICAgICAgICB2YWx1ZXMucHVzaCh1bmRlZmluZWQpO1xuICAgICAgICByZW1haW5pbmcrKztcbiAgICAgICAgJHByb21pc2VSZXNvbHZlLmNhbGwoQywgcHJvbWlzZSkudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICBpZiAoYWxyZWFkeUNhbGxlZCkgcmV0dXJuO1xuICAgICAgICAgIGFscmVhZHlDYWxsZWQgPSB0cnVlO1xuICAgICAgICAgIHZhbHVlc1tpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgICAtLXJlbWFpbmluZyB8fCByZXNvbHZlKHZhbHVlcyk7XG4gICAgICAgIH0sIHJlamVjdCk7XG4gICAgICB9KTtcbiAgICAgIC0tcmVtYWluaW5nIHx8IHJlc29sdmUodmFsdWVzKTtcbiAgICB9KTtcbiAgICBpZiAocmVzdWx0LmVycm9yKSByZWplY3QocmVzdWx0LnZhbHVlKTtcbiAgICByZXR1cm4gY2FwYWJpbGl0eS5wcm9taXNlO1xuICB9LFxuICAvLyBgUHJvbWlzZS5yYWNlYCBtZXRob2RcbiAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtcHJvbWlzZS5yYWNlXG4gIHJhY2U6IGZ1bmN0aW9uIHJhY2UoaXRlcmFibGUpIHtcbiAgICB2YXIgQyA9IHRoaXM7XG4gICAgdmFyIGNhcGFiaWxpdHkgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eShDKTtcbiAgICB2YXIgcmVqZWN0ID0gY2FwYWJpbGl0eS5yZWplY3Q7XG4gICAgdmFyIHJlc3VsdCA9IHBlcmZvcm0oZnVuY3Rpb24gKCkge1xuICAgICAgdmFyICRwcm9taXNlUmVzb2x2ZSA9IGFGdW5jdGlvbihDLnJlc29sdmUpO1xuICAgICAgaXRlcmF0ZShpdGVyYWJsZSwgZnVuY3Rpb24gKHByb21pc2UpIHtcbiAgICAgICAgJHByb21pc2VSZXNvbHZlLmNhbGwoQywgcHJvbWlzZSkudGhlbihjYXBhYmlsaXR5LnJlc29sdmUsIHJlamVjdCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBpZiAocmVzdWx0LmVycm9yKSByZWplY3QocmVzdWx0LnZhbHVlKTtcbiAgICByZXR1cm4gY2FwYWJpbGl0eS5wcm9taXNlO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.promise.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.anchor.js": +/*!**********************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.anchor.js ***! + \**********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar createHTML = __webpack_require__(/*! ../internals/create-html */ \"./node_modules/core-js/internals/create-html.js\");\nvar forcedStringHTMLMethod = __webpack_require__(/*! ../internals/forced-string-html-method */ \"./node_modules/core-js/internals/forced-string-html-method.js\");\n\n// `String.prototype.anchor` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.anchor\n$({ target: 'String', proto: true, forced: forcedStringHTMLMethod('anchor') }, {\n anchor: function anchor(name) {\n return createHTML(this, 'a', 'name', name);\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5hbmNob3IuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXMuc3RyaW5nLmFuY2hvci5qcz8xOGE1Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcbnZhciAkID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2V4cG9ydCcpO1xudmFyIGNyZWF0ZUhUTUwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvY3JlYXRlLWh0bWwnKTtcbnZhciBmb3JjZWRTdHJpbmdIVE1MTWV0aG9kID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2ZvcmNlZC1zdHJpbmctaHRtbC1tZXRob2QnKTtcblxuLy8gYFN0cmluZy5wcm90b3R5cGUuYW5jaG9yYCBtZXRob2Rcbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXN0cmluZy5wcm90b3R5cGUuYW5jaG9yXG4kKHsgdGFyZ2V0OiAnU3RyaW5nJywgcHJvdG86IHRydWUsIGZvcmNlZDogZm9yY2VkU3RyaW5nSFRNTE1ldGhvZCgnYW5jaG9yJykgfSwge1xuICBhbmNob3I6IGZ1bmN0aW9uIGFuY2hvcihuYW1lKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ2EnLCAnbmFtZScsIG5hbWUpO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.anchor.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.big.js": +/*!*******************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.big.js ***! + \*******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar createHTML = __webpack_require__(/*! ../internals/create-html */ \"./node_modules/core-js/internals/create-html.js\");\nvar forcedStringHTMLMethod = __webpack_require__(/*! ../internals/forced-string-html-method */ \"./node_modules/core-js/internals/forced-string-html-method.js\");\n\n// `String.prototype.big` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.big\n$({ target: 'String', proto: true, forced: forcedStringHTMLMethod('big') }, {\n big: function big() {\n return createHTML(this, 'big', '', '');\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5iaWcuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXMuc3RyaW5nLmJpZy5qcz8xMzkzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcbnZhciAkID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2V4cG9ydCcpO1xudmFyIGNyZWF0ZUhUTUwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvY3JlYXRlLWh0bWwnKTtcbnZhciBmb3JjZWRTdHJpbmdIVE1MTWV0aG9kID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2ZvcmNlZC1zdHJpbmctaHRtbC1tZXRob2QnKTtcblxuLy8gYFN0cmluZy5wcm90b3R5cGUuYmlnYCBtZXRob2Rcbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXN0cmluZy5wcm90b3R5cGUuYmlnXG4kKHsgdGFyZ2V0OiAnU3RyaW5nJywgcHJvdG86IHRydWUsIGZvcmNlZDogZm9yY2VkU3RyaW5nSFRNTE1ldGhvZCgnYmlnJykgfSwge1xuICBiaWc6IGZ1bmN0aW9uIGJpZygpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnYmlnJywgJycsICcnKTtcbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.big.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.blink.js": +/*!*********************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.blink.js ***! + \*********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar createHTML = __webpack_require__(/*! ../internals/create-html */ \"./node_modules/core-js/internals/create-html.js\");\nvar forcedStringHTMLMethod = __webpack_require__(/*! ../internals/forced-string-html-method */ \"./node_modules/core-js/internals/forced-string-html-method.js\");\n\n// `String.prototype.blink` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.blink\n$({ target: 'String', proto: true, forced: forcedStringHTMLMethod('blink') }, {\n blink: function blink() {\n return createHTML(this, 'blink', '', '');\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5ibGluay5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lcy5zdHJpbmcuYmxpbmsuanM/MDRkMyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG52YXIgJCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9leHBvcnQnKTtcbnZhciBjcmVhdGVIVE1MID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2NyZWF0ZS1odG1sJyk7XG52YXIgZm9yY2VkU3RyaW5nSFRNTE1ldGhvZCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9mb3JjZWQtc3RyaW5nLWh0bWwtbWV0aG9kJyk7XG5cbi8vIGBTdHJpbmcucHJvdG90eXBlLmJsaW5rYCBtZXRob2Rcbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXN0cmluZy5wcm90b3R5cGUuYmxpbmtcbiQoeyB0YXJnZXQ6ICdTdHJpbmcnLCBwcm90bzogdHJ1ZSwgZm9yY2VkOiBmb3JjZWRTdHJpbmdIVE1MTWV0aG9kKCdibGluaycpIH0sIHtcbiAgYmxpbms6IGZ1bmN0aW9uIGJsaW5rKCkge1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdibGluaycsICcnLCAnJyk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.blink.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.bold.js": +/*!********************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.bold.js ***! + \********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar createHTML = __webpack_require__(/*! ../internals/create-html */ \"./node_modules/core-js/internals/create-html.js\");\nvar forcedStringHTMLMethod = __webpack_require__(/*! ../internals/forced-string-html-method */ \"./node_modules/core-js/internals/forced-string-html-method.js\");\n\n// `String.prototype.bold` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.bold\n$({ target: 'String', proto: true, forced: forcedStringHTMLMethod('bold') }, {\n bold: function bold() {\n return createHTML(this, 'b', '', '');\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5ib2xkLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5ib2xkLmpzP2NjNzEiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xudmFyICQgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZXhwb3J0Jyk7XG52YXIgY3JlYXRlSFRNTCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9jcmVhdGUtaHRtbCcpO1xudmFyIGZvcmNlZFN0cmluZ0hUTUxNZXRob2QgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZm9yY2VkLXN0cmluZy1odG1sLW1ldGhvZCcpO1xuXG4vLyBgU3RyaW5nLnByb3RvdHlwZS5ib2xkYCBtZXRob2Rcbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXN0cmluZy5wcm90b3R5cGUuYm9sZFxuJCh7IHRhcmdldDogJ1N0cmluZycsIHByb3RvOiB0cnVlLCBmb3JjZWQ6IGZvcmNlZFN0cmluZ0hUTUxNZXRob2QoJ2JvbGQnKSB9LCB7XG4gIGJvbGQ6IGZ1bmN0aW9uIGJvbGQoKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ2InLCAnJywgJycpO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.bold.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.code-point-at.js": +/*!*****************************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.code-point-at.js ***! + \*****************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar internalCodePointAt = __webpack_require__(/*! ../internals/string-at */ \"./node_modules/core-js/internals/string-at.js\");\n\n// `String.prototype.codePointAt` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.codepointat\n$({ target: 'String', proto: true }, {\n codePointAt: function codePointAt(pos) {\n return internalCodePointAt(this, pos);\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5jb2RlLXBvaW50LWF0LmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5jb2RlLXBvaW50LWF0LmpzP2Y1YjIiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xudmFyICQgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZXhwb3J0Jyk7XG52YXIgaW50ZXJuYWxDb2RlUG9pbnRBdCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9zdHJpbmctYXQnKTtcblxuLy8gYFN0cmluZy5wcm90b3R5cGUuY29kZVBvaW50QXRgIG1ldGhvZFxuLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtc3RyaW5nLnByb3RvdHlwZS5jb2RlcG9pbnRhdFxuJCh7IHRhcmdldDogJ1N0cmluZycsIHByb3RvOiB0cnVlIH0sIHtcbiAgY29kZVBvaW50QXQ6IGZ1bmN0aW9uIGNvZGVQb2ludEF0KHBvcykge1xuICAgIHJldHVybiBpbnRlcm5hbENvZGVQb2ludEF0KHRoaXMsIHBvcyk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.code-point-at.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.ends-with.js": +/*!*************************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.ends-with.js ***! + \*************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar toLength = __webpack_require__(/*! ../internals/to-length */ \"./node_modules/core-js/internals/to-length.js\");\nvar validateArguments = __webpack_require__(/*! ../internals/validate-string-method-arguments */ \"./node_modules/core-js/internals/validate-string-method-arguments.js\");\nvar correctIsRegExpLogic = __webpack_require__(/*! ../internals/correct-is-regexp-logic */ \"./node_modules/core-js/internals/correct-is-regexp-logic.js\");\n\nvar ENDS_WITH = 'endsWith';\nvar nativeEndsWith = ''[ENDS_WITH];\nvar min = Math.min;\n\n// `String.prototype.endsWith` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.endswith\n$({ target: 'String', proto: true, forced: !correctIsRegExpLogic(ENDS_WITH) }, {\n endsWith: function endsWith(searchString /* , endPosition = @length */) {\n var that = validateArguments(this, searchString, ENDS_WITH);\n var endPosition = arguments.length > 1 ? arguments[1] : undefined;\n var len = toLength(that.length);\n var end = endPosition === undefined ? len : min(toLength(endPosition), len);\n var search = String(searchString);\n return nativeEndsWith\n ? nativeEndsWith.call(that, search, end)\n : that.slice(end - search.length, end) === search;\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5lbmRzLXdpdGguanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXMuc3RyaW5nLmVuZHMtd2l0aC5qcz84YTc5Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcbnZhciAkID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2V4cG9ydCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3RvLWxlbmd0aCcpO1xudmFyIHZhbGlkYXRlQXJndW1lbnRzID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3ZhbGlkYXRlLXN0cmluZy1tZXRob2QtYXJndW1lbnRzJyk7XG52YXIgY29ycmVjdElzUmVnRXhwTG9naWMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvY29ycmVjdC1pcy1yZWdleHAtbG9naWMnKTtcblxudmFyIEVORFNfV0lUSCA9ICdlbmRzV2l0aCc7XG52YXIgbmF0aXZlRW5kc1dpdGggPSAnJ1tFTkRTX1dJVEhdO1xudmFyIG1pbiA9IE1hdGgubWluO1xuXG4vLyBgU3RyaW5nLnByb3RvdHlwZS5lbmRzV2l0aGAgbWV0aG9kXG4vLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1zdHJpbmcucHJvdG90eXBlLmVuZHN3aXRoXG4kKHsgdGFyZ2V0OiAnU3RyaW5nJywgcHJvdG86IHRydWUsIGZvcmNlZDogIWNvcnJlY3RJc1JlZ0V4cExvZ2ljKEVORFNfV0lUSCkgfSwge1xuICBlbmRzV2l0aDogZnVuY3Rpb24gZW5kc1dpdGgoc2VhcmNoU3RyaW5nIC8qICwgZW5kUG9zaXRpb24gPSBAbGVuZ3RoICovKSB7XG4gICAgdmFyIHRoYXQgPSB2YWxpZGF0ZUFyZ3VtZW50cyh0aGlzLCBzZWFyY2hTdHJpbmcsIEVORFNfV0lUSCk7XG4gICAgdmFyIGVuZFBvc2l0aW9uID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQ7XG4gICAgdmFyIGxlbiA9IHRvTGVuZ3RoKHRoYXQubGVuZ3RoKTtcbiAgICB2YXIgZW5kID0gZW5kUG9zaXRpb24gPT09IHVuZGVmaW5lZCA/IGxlbiA6IG1pbih0b0xlbmd0aChlbmRQb3NpdGlvbiksIGxlbik7XG4gICAgdmFyIHNlYXJjaCA9IFN0cmluZyhzZWFyY2hTdHJpbmcpO1xuICAgIHJldHVybiBuYXRpdmVFbmRzV2l0aFxuICAgICAgPyBuYXRpdmVFbmRzV2l0aC5jYWxsKHRoYXQsIHNlYXJjaCwgZW5kKVxuICAgICAgOiB0aGF0LnNsaWNlKGVuZCAtIHNlYXJjaC5sZW5ndGgsIGVuZCkgPT09IHNlYXJjaDtcbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.ends-with.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.fixed.js": +/*!*********************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.fixed.js ***! + \*********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar createHTML = __webpack_require__(/*! ../internals/create-html */ \"./node_modules/core-js/internals/create-html.js\");\nvar forcedStringHTMLMethod = __webpack_require__(/*! ../internals/forced-string-html-method */ \"./node_modules/core-js/internals/forced-string-html-method.js\");\n\n// `String.prototype.fixed` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.fixed\n$({ target: 'String', proto: true, forced: forcedStringHTMLMethod('fixed') }, {\n fixed: function fixed() {\n return createHTML(this, 'tt', '', '');\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5maXhlZC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lcy5zdHJpbmcuZml4ZWQuanM/YzdjZCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG52YXIgJCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9leHBvcnQnKTtcbnZhciBjcmVhdGVIVE1MID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2NyZWF0ZS1odG1sJyk7XG52YXIgZm9yY2VkU3RyaW5nSFRNTE1ldGhvZCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9mb3JjZWQtc3RyaW5nLWh0bWwtbWV0aG9kJyk7XG5cbi8vIGBTdHJpbmcucHJvdG90eXBlLmZpeGVkYCBtZXRob2Rcbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXN0cmluZy5wcm90b3R5cGUuZml4ZWRcbiQoeyB0YXJnZXQ6ICdTdHJpbmcnLCBwcm90bzogdHJ1ZSwgZm9yY2VkOiBmb3JjZWRTdHJpbmdIVE1MTWV0aG9kKCdmaXhlZCcpIH0sIHtcbiAgZml4ZWQ6IGZ1bmN0aW9uIGZpeGVkKCkge1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICd0dCcsICcnLCAnJyk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.fixed.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.fontcolor.js": +/*!*************************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.fontcolor.js ***! + \*************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar createHTML = __webpack_require__(/*! ../internals/create-html */ \"./node_modules/core-js/internals/create-html.js\");\nvar forcedStringHTMLMethod = __webpack_require__(/*! ../internals/forced-string-html-method */ \"./node_modules/core-js/internals/forced-string-html-method.js\");\n\n// `String.prototype.fontcolor` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.fontcolor\n$({ target: 'String', proto: true, forced: forcedStringHTMLMethod('fontcolor') }, {\n fontcolor: function fontcolor(color) {\n return createHTML(this, 'font', 'color', color);\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5mb250Y29sb3IuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXMuc3RyaW5nLmZvbnRjb2xvci5qcz85NzY3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcbnZhciAkID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2V4cG9ydCcpO1xudmFyIGNyZWF0ZUhUTUwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvY3JlYXRlLWh0bWwnKTtcbnZhciBmb3JjZWRTdHJpbmdIVE1MTWV0aG9kID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2ZvcmNlZC1zdHJpbmctaHRtbC1tZXRob2QnKTtcblxuLy8gYFN0cmluZy5wcm90b3R5cGUuZm9udGNvbG9yYCBtZXRob2Rcbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXN0cmluZy5wcm90b3R5cGUuZm9udGNvbG9yXG4kKHsgdGFyZ2V0OiAnU3RyaW5nJywgcHJvdG86IHRydWUsIGZvcmNlZDogZm9yY2VkU3RyaW5nSFRNTE1ldGhvZCgnZm9udGNvbG9yJykgfSwge1xuICBmb250Y29sb3I6IGZ1bmN0aW9uIGZvbnRjb2xvcihjb2xvcikge1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdmb250JywgJ2NvbG9yJywgY29sb3IpO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.fontcolor.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.fontsize.js": +/*!************************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.fontsize.js ***! + \************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar createHTML = __webpack_require__(/*! ../internals/create-html */ \"./node_modules/core-js/internals/create-html.js\");\nvar forcedStringHTMLMethod = __webpack_require__(/*! ../internals/forced-string-html-method */ \"./node_modules/core-js/internals/forced-string-html-method.js\");\n\n// `String.prototype.fontsize` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.fontsize\n$({ target: 'String', proto: true, forced: forcedStringHTMLMethod('fontsize') }, {\n fontsize: function fontsize(size) {\n return createHTML(this, 'font', 'size', size);\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5mb250c2l6ZS5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lcy5zdHJpbmcuZm9udHNpemUuanM/MTkxMyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG52YXIgJCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9leHBvcnQnKTtcbnZhciBjcmVhdGVIVE1MID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2NyZWF0ZS1odG1sJyk7XG52YXIgZm9yY2VkU3RyaW5nSFRNTE1ldGhvZCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9mb3JjZWQtc3RyaW5nLWh0bWwtbWV0aG9kJyk7XG5cbi8vIGBTdHJpbmcucHJvdG90eXBlLmZvbnRzaXplYCBtZXRob2Rcbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXN0cmluZy5wcm90b3R5cGUuZm9udHNpemVcbiQoeyB0YXJnZXQ6ICdTdHJpbmcnLCBwcm90bzogdHJ1ZSwgZm9yY2VkOiBmb3JjZWRTdHJpbmdIVE1MTWV0aG9kKCdmb250c2l6ZScpIH0sIHtcbiAgZm9udHNpemU6IGZ1bmN0aW9uIGZvbnRzaXplKHNpemUpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnZm9udCcsICdzaXplJywgc2l6ZSk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.fontsize.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.from-code-point.js": +/*!*******************************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.from-code-point.js ***! + \*******************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar toAbsoluteIndex = __webpack_require__(/*! ../internals/to-absolute-index */ \"./node_modules/core-js/internals/to-absolute-index.js\");\n\nvar fromCharCode = String.fromCharCode;\nvar nativeFromCodePoint = String.fromCodePoint;\n\n// length should be 1, old FF problem\nvar INCORRECT_LENGTH = !!nativeFromCodePoint && nativeFromCodePoint.length != 1;\n\n// `String.fromCodePoint` method\n// https://tc39.github.io/ecma262/#sec-string.fromcodepoint\n$({ target: 'String', stat: true, forced: INCORRECT_LENGTH }, {\n fromCodePoint: function fromCodePoint(x) { // eslint-disable-line no-unused-vars\n var elements = [];\n var length = arguments.length;\n var i = 0;\n var code;\n while (length > i) {\n code = +arguments[i++];\n if (toAbsoluteIndex(code, 0x10FFFF) !== code) throw RangeError(code + ' is not a valid code point');\n elements.push(code < 0x10000\n ? fromCharCode(code)\n : fromCharCode(((code -= 0x10000) >> 10) + 0xD800, code % 0x400 + 0xDC00)\n );\n } return elements.join('');\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5mcm9tLWNvZGUtcG9pbnQuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXMuc3RyaW5nLmZyb20tY29kZS1wb2ludC5qcz9mNmQ2Il0sInNvdXJjZXNDb250ZW50IjpbInZhciAkID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2V4cG9ydCcpO1xudmFyIHRvQWJzb2x1dGVJbmRleCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy90by1hYnNvbHV0ZS1pbmRleCcpO1xuXG52YXIgZnJvbUNoYXJDb2RlID0gU3RyaW5nLmZyb21DaGFyQ29kZTtcbnZhciBuYXRpdmVGcm9tQ29kZVBvaW50ID0gU3RyaW5nLmZyb21Db2RlUG9pbnQ7XG5cbi8vIGxlbmd0aCBzaG91bGQgYmUgMSwgb2xkIEZGIHByb2JsZW1cbnZhciBJTkNPUlJFQ1RfTEVOR1RIID0gISFuYXRpdmVGcm9tQ29kZVBvaW50ICYmIG5hdGl2ZUZyb21Db2RlUG9pbnQubGVuZ3RoICE9IDE7XG5cbi8vIGBTdHJpbmcuZnJvbUNvZGVQb2ludGAgbWV0aG9kXG4vLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1zdHJpbmcuZnJvbWNvZGVwb2ludFxuJCh7IHRhcmdldDogJ1N0cmluZycsIHN0YXQ6IHRydWUsIGZvcmNlZDogSU5DT1JSRUNUX0xFTkdUSCB9LCB7XG4gIGZyb21Db2RlUG9pbnQ6IGZ1bmN0aW9uIGZyb21Db2RlUG9pbnQoeCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgdmFyIGVsZW1lbnRzID0gW107XG4gICAgdmFyIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgdmFyIGkgPSAwO1xuICAgIHZhciBjb2RlO1xuICAgIHdoaWxlIChsZW5ndGggPiBpKSB7XG4gICAgICBjb2RlID0gK2FyZ3VtZW50c1tpKytdO1xuICAgICAgaWYgKHRvQWJzb2x1dGVJbmRleChjb2RlLCAweDEwRkZGRikgIT09IGNvZGUpIHRocm93IFJhbmdlRXJyb3IoY29kZSArICcgaXMgbm90IGEgdmFsaWQgY29kZSBwb2ludCcpO1xuICAgICAgZWxlbWVudHMucHVzaChjb2RlIDwgMHgxMDAwMFxuICAgICAgICA/IGZyb21DaGFyQ29kZShjb2RlKVxuICAgICAgICA6IGZyb21DaGFyQ29kZSgoKGNvZGUgLT0gMHgxMDAwMCkgPj4gMTApICsgMHhEODAwLCBjb2RlICUgMHg0MDAgKyAweERDMDApXG4gICAgICApO1xuICAgIH0gcmV0dXJuIGVsZW1lbnRzLmpvaW4oJycpO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.from-code-point.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.includes.js": +/*!************************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.includes.js ***! + \************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar validateArguments = __webpack_require__(/*! ../internals/validate-string-method-arguments */ \"./node_modules/core-js/internals/validate-string-method-arguments.js\");\nvar correctIsRegExpLogic = __webpack_require__(/*! ../internals/correct-is-regexp-logic */ \"./node_modules/core-js/internals/correct-is-regexp-logic.js\");\n\n// `String.prototype.includes` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.includes\n$({ target: 'String', proto: true, forced: !correctIsRegExpLogic('includes') }, {\n includes: function includes(searchString /* , position = 0 */) {\n return !!~validateArguments(this, searchString, 'includes')\n .indexOf(searchString, arguments.length > 1 ? arguments[1] : undefined);\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5pbmNsdWRlcy5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lcy5zdHJpbmcuaW5jbHVkZXMuanM/MjUzMiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG52YXIgJCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9leHBvcnQnKTtcbnZhciB2YWxpZGF0ZUFyZ3VtZW50cyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy92YWxpZGF0ZS1zdHJpbmctbWV0aG9kLWFyZ3VtZW50cycpO1xudmFyIGNvcnJlY3RJc1JlZ0V4cExvZ2ljID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2NvcnJlY3QtaXMtcmVnZXhwLWxvZ2ljJyk7XG5cbi8vIGBTdHJpbmcucHJvdG90eXBlLmluY2x1ZGVzYCBtZXRob2Rcbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXN0cmluZy5wcm90b3R5cGUuaW5jbHVkZXNcbiQoeyB0YXJnZXQ6ICdTdHJpbmcnLCBwcm90bzogdHJ1ZSwgZm9yY2VkOiAhY29ycmVjdElzUmVnRXhwTG9naWMoJ2luY2x1ZGVzJykgfSwge1xuICBpbmNsdWRlczogZnVuY3Rpb24gaW5jbHVkZXMoc2VhcmNoU3RyaW5nIC8qICwgcG9zaXRpb24gPSAwICovKSB7XG4gICAgcmV0dXJuICEhfnZhbGlkYXRlQXJndW1lbnRzKHRoaXMsIHNlYXJjaFN0cmluZywgJ2luY2x1ZGVzJylcbiAgICAgIC5pbmRleE9mKHNlYXJjaFN0cmluZywgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.includes.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.italics.js": +/*!***********************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.italics.js ***! + \***********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar createHTML = __webpack_require__(/*! ../internals/create-html */ \"./node_modules/core-js/internals/create-html.js\");\nvar forcedStringHTMLMethod = __webpack_require__(/*! ../internals/forced-string-html-method */ \"./node_modules/core-js/internals/forced-string-html-method.js\");\n\n// `String.prototype.italics` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.italics\n$({ target: 'String', proto: true, forced: forcedStringHTMLMethod('italics') }, {\n italics: function italics() {\n return createHTML(this, 'i', '', '');\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5pdGFsaWNzLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5pdGFsaWNzLmpzP2M1ZDAiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xudmFyICQgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZXhwb3J0Jyk7XG52YXIgY3JlYXRlSFRNTCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9jcmVhdGUtaHRtbCcpO1xudmFyIGZvcmNlZFN0cmluZ0hUTUxNZXRob2QgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZm9yY2VkLXN0cmluZy1odG1sLW1ldGhvZCcpO1xuXG4vLyBgU3RyaW5nLnByb3RvdHlwZS5pdGFsaWNzYCBtZXRob2Rcbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXN0cmluZy5wcm90b3R5cGUuaXRhbGljc1xuJCh7IHRhcmdldDogJ1N0cmluZycsIHByb3RvOiB0cnVlLCBmb3JjZWQ6IGZvcmNlZFN0cmluZ0hUTUxNZXRob2QoJ2l0YWxpY3MnKSB9LCB7XG4gIGl0YWxpY3M6IGZ1bmN0aW9uIGl0YWxpY3MoKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ2knLCAnJywgJycpO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.italics.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.iterator.js": +/*!************************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.iterator.js ***! + \************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar codePointAt = __webpack_require__(/*! ../internals/string-at */ \"./node_modules/core-js/internals/string-at.js\");\nvar InternalStateModule = __webpack_require__(/*! ../internals/internal-state */ \"./node_modules/core-js/internals/internal-state.js\");\nvar defineIterator = __webpack_require__(/*! ../internals/define-iterator */ \"./node_modules/core-js/internals/define-iterator.js\");\n\nvar STRING_ITERATOR = 'String Iterator';\nvar setInternalState = InternalStateModule.set;\nvar getInternalState = InternalStateModule.getterFor(STRING_ITERATOR);\n\n// `String.prototype[@@iterator]` method\n// https://tc39.github.io/ecma262/#sec-string.prototype-@@iterator\ndefineIterator(String, 'String', function (iterated) {\n setInternalState(this, {\n type: STRING_ITERATOR,\n string: String(iterated),\n index: 0\n });\n// `%StringIteratorPrototype%.next` method\n// https://tc39.github.io/ecma262/#sec-%stringiteratorprototype%.next\n}, function next() {\n var state = getInternalState(this);\n var string = state.string;\n var index = state.index;\n var point;\n if (index >= string.length) return { value: undefined, done: true };\n point = codePointAt(string, index, true);\n state.index += point.length;\n return { value: point, done: false };\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5pdGVyYXRvci5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lcy5zdHJpbmcuaXRlcmF0b3IuanM/M2NhMyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG52YXIgY29kZVBvaW50QXQgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvc3RyaW5nLWF0Jyk7XG52YXIgSW50ZXJuYWxTdGF0ZU1vZHVsZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9pbnRlcm5hbC1zdGF0ZScpO1xudmFyIGRlZmluZUl0ZXJhdG9yID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2RlZmluZS1pdGVyYXRvcicpO1xuXG52YXIgU1RSSU5HX0lURVJBVE9SID0gJ1N0cmluZyBJdGVyYXRvcic7XG52YXIgc2V0SW50ZXJuYWxTdGF0ZSA9IEludGVybmFsU3RhdGVNb2R1bGUuc2V0O1xudmFyIGdldEludGVybmFsU3RhdGUgPSBJbnRlcm5hbFN0YXRlTW9kdWxlLmdldHRlckZvcihTVFJJTkdfSVRFUkFUT1IpO1xuXG4vLyBgU3RyaW5nLnByb3RvdHlwZVtAQGl0ZXJhdG9yXWAgbWV0aG9kXG4vLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1zdHJpbmcucHJvdG90eXBlLUBAaXRlcmF0b3JcbmRlZmluZUl0ZXJhdG9yKFN0cmluZywgJ1N0cmluZycsIGZ1bmN0aW9uIChpdGVyYXRlZCkge1xuICBzZXRJbnRlcm5hbFN0YXRlKHRoaXMsIHtcbiAgICB0eXBlOiBTVFJJTkdfSVRFUkFUT1IsXG4gICAgc3RyaW5nOiBTdHJpbmcoaXRlcmF0ZWQpLFxuICAgIGluZGV4OiAwXG4gIH0pO1xuLy8gYCVTdHJpbmdJdGVyYXRvclByb3RvdHlwZSUubmV4dGAgbWV0aG9kXG4vLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy0lc3RyaW5naXRlcmF0b3Jwcm90b3R5cGUlLm5leHRcbn0sIGZ1bmN0aW9uIG5leHQoKSB7XG4gIHZhciBzdGF0ZSA9IGdldEludGVybmFsU3RhdGUodGhpcyk7XG4gIHZhciBzdHJpbmcgPSBzdGF0ZS5zdHJpbmc7XG4gIHZhciBpbmRleCA9IHN0YXRlLmluZGV4O1xuICB2YXIgcG9pbnQ7XG4gIGlmIChpbmRleCA+PSBzdHJpbmcubGVuZ3RoKSByZXR1cm4geyB2YWx1ZTogdW5kZWZpbmVkLCBkb25lOiB0cnVlIH07XG4gIHBvaW50ID0gY29kZVBvaW50QXQoc3RyaW5nLCBpbmRleCwgdHJ1ZSk7XG4gIHN0YXRlLmluZGV4ICs9IHBvaW50Lmxlbmd0aDtcbiAgcmV0dXJuIHsgdmFsdWU6IHBvaW50LCBkb25lOiBmYWxzZSB9O1xufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.iterator.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.link.js": +/*!********************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.link.js ***! + \********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar createHTML = __webpack_require__(/*! ../internals/create-html */ \"./node_modules/core-js/internals/create-html.js\");\nvar forcedStringHTMLMethod = __webpack_require__(/*! ../internals/forced-string-html-method */ \"./node_modules/core-js/internals/forced-string-html-method.js\");\n\n// `String.prototype.link` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.link\n$({ target: 'String', proto: true, forced: forcedStringHTMLMethod('link') }, {\n link: function link(url) {\n return createHTML(this, 'a', 'href', url);\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5saW5rLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5saW5rLmpzPzk5MTEiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xudmFyICQgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZXhwb3J0Jyk7XG52YXIgY3JlYXRlSFRNTCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9jcmVhdGUtaHRtbCcpO1xudmFyIGZvcmNlZFN0cmluZ0hUTUxNZXRob2QgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZm9yY2VkLXN0cmluZy1odG1sLW1ldGhvZCcpO1xuXG4vLyBgU3RyaW5nLnByb3RvdHlwZS5saW5rYCBtZXRob2Rcbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXN0cmluZy5wcm90b3R5cGUubGlua1xuJCh7IHRhcmdldDogJ1N0cmluZycsIHByb3RvOiB0cnVlLCBmb3JjZWQ6IGZvcmNlZFN0cmluZ0hUTUxNZXRob2QoJ2xpbmsnKSB9LCB7XG4gIGxpbms6IGZ1bmN0aW9uIGxpbmsodXJsKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ2EnLCAnaHJlZicsIHVybCk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.link.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.match-all.js": +/*!*************************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.match-all.js ***! + \*************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar createIteratorConstructor = __webpack_require__(/*! ../internals/create-iterator-constructor */ \"./node_modules/core-js/internals/create-iterator-constructor.js\");\nvar requireObjectCoercible = __webpack_require__(/*! ../internals/require-object-coercible */ \"./node_modules/core-js/internals/require-object-coercible.js\");\nvar toLength = __webpack_require__(/*! ../internals/to-length */ \"./node_modules/core-js/internals/to-length.js\");\nvar aFunction = __webpack_require__(/*! ../internals/a-function */ \"./node_modules/core-js/internals/a-function.js\");\nvar anObject = __webpack_require__(/*! ../internals/an-object */ \"./node_modules/core-js/internals/an-object.js\");\nvar classof = __webpack_require__(/*! ../internals/classof */ \"./node_modules/core-js/internals/classof.js\");\nvar getFlags = __webpack_require__(/*! ../internals/regexp-flags */ \"./node_modules/core-js/internals/regexp-flags.js\");\nvar hide = __webpack_require__(/*! ../internals/hide */ \"./node_modules/core-js/internals/hide.js\");\nvar wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ \"./node_modules/core-js/internals/well-known-symbol.js\");\nvar speciesConstructor = __webpack_require__(/*! ../internals/species-constructor */ \"./node_modules/core-js/internals/species-constructor.js\");\nvar advanceStringIndex = __webpack_require__(/*! ../internals/advance-string-index */ \"./node_modules/core-js/internals/advance-string-index.js\");\nvar InternalStateModule = __webpack_require__(/*! ../internals/internal-state */ \"./node_modules/core-js/internals/internal-state.js\");\nvar IS_PURE = __webpack_require__(/*! ../internals/is-pure */ \"./node_modules/core-js/internals/is-pure.js\");\n\nvar MATCH_ALL = wellKnownSymbol('matchAll');\nvar REGEXP_STRING = 'RegExp String';\nvar REGEXP_STRING_ITERATOR = REGEXP_STRING + ' Iterator';\nvar setInternalState = InternalStateModule.set;\nvar getInternalState = InternalStateModule.getterFor(REGEXP_STRING_ITERATOR);\nvar RegExpPrototype = RegExp.prototype;\nvar regExpBuiltinExec = RegExpPrototype.exec;\n\nvar regExpExec = function (R, S) {\n var exec = R.exec;\n var result;\n if (typeof exec == 'function') {\n result = exec.call(R, S);\n if (typeof result != 'object') throw TypeError('Incorrect exec result');\n return result;\n } return regExpBuiltinExec.call(R, S);\n};\n\n// eslint-disable-next-line max-len\nvar $RegExpStringIterator = createIteratorConstructor(function RegExpStringIterator(regexp, string, global, fullUnicode) {\n setInternalState(this, {\n type: REGEXP_STRING_ITERATOR,\n regexp: regexp,\n string: string,\n global: global,\n unicode: fullUnicode,\n done: false\n });\n}, REGEXP_STRING, function next() {\n var state = getInternalState(this);\n if (state.done) return { value: undefined, done: true };\n var R = state.regexp;\n var S = state.string;\n var match = regExpExec(R, S);\n if (match === null) return { value: undefined, done: state.done = true };\n if (state.global) {\n if (String(match[0]) == '') R.lastIndex = advanceStringIndex(S, toLength(R.lastIndex), state.unicode);\n return { value: match, done: false };\n }\n state.done = true;\n return { value: match, done: false };\n});\n\nvar $matchAll = function (string) {\n var R = anObject(this);\n var S = String(string);\n var C, flagsValue, flags, matcher, global, fullUnicode;\n C = speciesConstructor(R, RegExp);\n flagsValue = R.flags;\n if (flagsValue === undefined && R instanceof RegExp && !('flags' in RegExpPrototype)) {\n flagsValue = getFlags.call(R);\n }\n flags = flagsValue === undefined ? '' : String(flagsValue);\n matcher = new C(C === RegExp ? R.source : R, flags);\n global = !!~flags.indexOf('g');\n fullUnicode = !!~flags.indexOf('u');\n matcher.lastIndex = toLength(R.lastIndex);\n return new $RegExpStringIterator(matcher, S, global, fullUnicode);\n};\n\n// `String.prototype.matchAll` method\n// https://github.com/tc39/proposal-string-matchall\n$({ target: 'String', proto: true }, {\n matchAll: function matchAll(regexp) {\n var O = requireObjectCoercible(this);\n var S, matcher, rx;\n if (regexp != null) {\n matcher = regexp[MATCH_ALL];\n if (matcher === undefined && IS_PURE && classof(regexp) == 'RegExp') matcher = $matchAll;\n if (matcher != null) return aFunction(matcher).call(regexp, O);\n }\n S = String(O);\n rx = new RegExp(regexp, 'g');\n return IS_PURE ? $matchAll.call(rx, S) : rx[MATCH_ALL](S);\n }\n});\n\nIS_PURE || MATCH_ALL in RegExpPrototype || hide(RegExpPrototype, MATCH_ALL, $matchAll);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5tYXRjaC1hbGwuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXMuc3RyaW5nLm1hdGNoLWFsbC5qcz9hMWYwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcbnZhciAkID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2V4cG9ydCcpO1xudmFyIGNyZWF0ZUl0ZXJhdG9yQ29uc3RydWN0b3IgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvY3JlYXRlLWl0ZXJhdG9yLWNvbnN0cnVjdG9yJyk7XG52YXIgcmVxdWlyZU9iamVjdENvZXJjaWJsZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9yZXF1aXJlLW9iamVjdC1jb2VyY2libGUnKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy90by1sZW5ndGgnKTtcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvYS1mdW5jdGlvbicpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2FuLW9iamVjdCcpO1xudmFyIGNsYXNzb2YgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvY2xhc3NvZicpO1xudmFyIGdldEZsYWdzID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3JlZ2V4cC1mbGFncycpO1xudmFyIGhpZGUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaGlkZScpO1xudmFyIHdlbGxLbm93blN5bWJvbCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy93ZWxsLWtub3duLXN5bWJvbCcpO1xudmFyIHNwZWNpZXNDb25zdHJ1Y3RvciA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9zcGVjaWVzLWNvbnN0cnVjdG9yJyk7XG52YXIgYWR2YW5jZVN0cmluZ0luZGV4ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2FkdmFuY2Utc3RyaW5nLWluZGV4Jyk7XG52YXIgSW50ZXJuYWxTdGF0ZU1vZHVsZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9pbnRlcm5hbC1zdGF0ZScpO1xudmFyIElTX1BVUkUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaXMtcHVyZScpO1xuXG52YXIgTUFUQ0hfQUxMID0gd2VsbEtub3duU3ltYm9sKCdtYXRjaEFsbCcpO1xudmFyIFJFR0VYUF9TVFJJTkcgPSAnUmVnRXhwIFN0cmluZyc7XG52YXIgUkVHRVhQX1NUUklOR19JVEVSQVRPUiA9IFJFR0VYUF9TVFJJTkcgKyAnIEl0ZXJhdG9yJztcbnZhciBzZXRJbnRlcm5hbFN0YXRlID0gSW50ZXJuYWxTdGF0ZU1vZHVsZS5zZXQ7XG52YXIgZ2V0SW50ZXJuYWxTdGF0ZSA9IEludGVybmFsU3RhdGVNb2R1bGUuZ2V0dGVyRm9yKFJFR0VYUF9TVFJJTkdfSVRFUkFUT1IpO1xudmFyIFJlZ0V4cFByb3RvdHlwZSA9IFJlZ0V4cC5wcm90b3R5cGU7XG52YXIgcmVnRXhwQnVpbHRpbkV4ZWMgPSBSZWdFeHBQcm90b3R5cGUuZXhlYztcblxudmFyIHJlZ0V4cEV4ZWMgPSBmdW5jdGlvbiAoUiwgUykge1xuICB2YXIgZXhlYyA9IFIuZXhlYztcbiAgdmFyIHJlc3VsdDtcbiAgaWYgKHR5cGVvZiBleGVjID09ICdmdW5jdGlvbicpIHtcbiAgICByZXN1bHQgPSBleGVjLmNhbGwoUiwgUyk7XG4gICAgaWYgKHR5cGVvZiByZXN1bHQgIT0gJ29iamVjdCcpIHRocm93IFR5cGVFcnJvcignSW5jb3JyZWN0IGV4ZWMgcmVzdWx0Jyk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSByZXR1cm4gcmVnRXhwQnVpbHRpbkV4ZWMuY2FsbChSLCBTKTtcbn07XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGVuXG52YXIgJFJlZ0V4cFN0cmluZ0l0ZXJhdG9yID0gY3JlYXRlSXRlcmF0b3JDb25zdHJ1Y3RvcihmdW5jdGlvbiBSZWdFeHBTdHJpbmdJdGVyYXRvcihyZWdleHAsIHN0cmluZywgZ2xvYmFsLCBmdWxsVW5pY29kZSkge1xuICBzZXRJbnRlcm5hbFN0YXRlKHRoaXMsIHtcbiAgICB0eXBlOiBSRUdFWFBfU1RSSU5HX0lURVJBVE9SLFxuICAgIHJlZ2V4cDogcmVnZXhwLFxuICAgIHN0cmluZzogc3RyaW5nLFxuICAgIGdsb2JhbDogZ2xvYmFsLFxuICAgIHVuaWNvZGU6IGZ1bGxVbmljb2RlLFxuICAgIGRvbmU6IGZhbHNlXG4gIH0pO1xufSwgUkVHRVhQX1NUUklORywgZnVuY3Rpb24gbmV4dCgpIHtcbiAgdmFyIHN0YXRlID0gZ2V0SW50ZXJuYWxTdGF0ZSh0aGlzKTtcbiAgaWYgKHN0YXRlLmRvbmUpIHJldHVybiB7IHZhbHVlOiB1bmRlZmluZWQsIGRvbmU6IHRydWUgfTtcbiAgdmFyIFIgPSBzdGF0ZS5yZWdleHA7XG4gIHZhciBTID0gc3RhdGUuc3RyaW5nO1xuICB2YXIgbWF0Y2ggPSByZWdFeHBFeGVjKFIsIFMpO1xuICBpZiAobWF0Y2ggPT09IG51bGwpIHJldHVybiB7IHZhbHVlOiB1bmRlZmluZWQsIGRvbmU6IHN0YXRlLmRvbmUgPSB0cnVlIH07XG4gIGlmIChzdGF0ZS5nbG9iYWwpIHtcbiAgICBpZiAoU3RyaW5nKG1hdGNoWzBdKSA9PSAnJykgUi5sYXN0SW5kZXggPSBhZHZhbmNlU3RyaW5nSW5kZXgoUywgdG9MZW5ndGgoUi5sYXN0SW5kZXgpLCBzdGF0ZS51bmljb2RlKTtcbiAgICByZXR1cm4geyB2YWx1ZTogbWF0Y2gsIGRvbmU6IGZhbHNlIH07XG4gIH1cbiAgc3RhdGUuZG9uZSA9IHRydWU7XG4gIHJldHVybiB7IHZhbHVlOiBtYXRjaCwgZG9uZTogZmFsc2UgfTtcbn0pO1xuXG52YXIgJG1hdGNoQWxsID0gZnVuY3Rpb24gKHN0cmluZykge1xuICB2YXIgUiA9IGFuT2JqZWN0KHRoaXMpO1xuICB2YXIgUyA9IFN0cmluZyhzdHJpbmcpO1xuICB2YXIgQywgZmxhZ3NWYWx1ZSwgZmxhZ3MsIG1hdGNoZXIsIGdsb2JhbCwgZnVsbFVuaWNvZGU7XG4gIEMgPSBzcGVjaWVzQ29uc3RydWN0b3IoUiwgUmVnRXhwKTtcbiAgZmxhZ3NWYWx1ZSA9IFIuZmxhZ3M7XG4gIGlmIChmbGFnc1ZhbHVlID09PSB1bmRlZmluZWQgJiYgUiBpbnN0YW5jZW9mIFJlZ0V4cCAmJiAhKCdmbGFncycgaW4gUmVnRXhwUHJvdG90eXBlKSkge1xuICAgIGZsYWdzVmFsdWUgPSBnZXRGbGFncy5jYWxsKFIpO1xuICB9XG4gIGZsYWdzID0gZmxhZ3NWYWx1ZSA9PT0gdW5kZWZpbmVkID8gJycgOiBTdHJpbmcoZmxhZ3NWYWx1ZSk7XG4gIG1hdGNoZXIgPSBuZXcgQyhDID09PSBSZWdFeHAgPyBSLnNvdXJjZSA6IFIsIGZsYWdzKTtcbiAgZ2xvYmFsID0gISF+ZmxhZ3MuaW5kZXhPZignZycpO1xuICBmdWxsVW5pY29kZSA9ICEhfmZsYWdzLmluZGV4T2YoJ3UnKTtcbiAgbWF0Y2hlci5sYXN0SW5kZXggPSB0b0xlbmd0aChSLmxhc3RJbmRleCk7XG4gIHJldHVybiBuZXcgJFJlZ0V4cFN0cmluZ0l0ZXJhdG9yKG1hdGNoZXIsIFMsIGdsb2JhbCwgZnVsbFVuaWNvZGUpO1xufTtcblxuLy8gYFN0cmluZy5wcm90b3R5cGUubWF0Y2hBbGxgIG1ldGhvZFxuLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtc3RyaW5nLW1hdGNoYWxsXG4kKHsgdGFyZ2V0OiAnU3RyaW5nJywgcHJvdG86IHRydWUgfSwge1xuICBtYXRjaEFsbDogZnVuY3Rpb24gbWF0Y2hBbGwocmVnZXhwKSB7XG4gICAgdmFyIE8gPSByZXF1aXJlT2JqZWN0Q29lcmNpYmxlKHRoaXMpO1xuICAgIHZhciBTLCBtYXRjaGVyLCByeDtcbiAgICBpZiAocmVnZXhwICE9IG51bGwpIHtcbiAgICAgIG1hdGNoZXIgPSByZWdleHBbTUFUQ0hfQUxMXTtcbiAgICAgIGlmIChtYXRjaGVyID09PSB1bmRlZmluZWQgJiYgSVNfUFVSRSAmJiBjbGFzc29mKHJlZ2V4cCkgPT0gJ1JlZ0V4cCcpIG1hdGNoZXIgPSAkbWF0Y2hBbGw7XG4gICAgICBpZiAobWF0Y2hlciAhPSBudWxsKSByZXR1cm4gYUZ1bmN0aW9uKG1hdGNoZXIpLmNhbGwocmVnZXhwLCBPKTtcbiAgICB9XG4gICAgUyA9IFN0cmluZyhPKTtcbiAgICByeCA9IG5ldyBSZWdFeHAocmVnZXhwLCAnZycpO1xuICAgIHJldHVybiBJU19QVVJFID8gJG1hdGNoQWxsLmNhbGwocngsIFMpIDogcnhbTUFUQ0hfQUxMXShTKTtcbiAgfVxufSk7XG5cbklTX1BVUkUgfHwgTUFUQ0hfQUxMIGluIFJlZ0V4cFByb3RvdHlwZSB8fCBoaWRlKFJlZ0V4cFByb3RvdHlwZSwgTUFUQ0hfQUxMLCAkbWF0Y2hBbGwpO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.match-all.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.match.js": +/*!*********************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.match.js ***! + \*********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar fixRegExpWellKnownSymbolLogic = __webpack_require__(/*! ../internals/fix-regexp-well-known-symbol-logic */ \"./node_modules/core-js/internals/fix-regexp-well-known-symbol-logic.js\");\nvar anObject = __webpack_require__(/*! ../internals/an-object */ \"./node_modules/core-js/internals/an-object.js\");\nvar toLength = __webpack_require__(/*! ../internals/to-length */ \"./node_modules/core-js/internals/to-length.js\");\nvar requireObjectCoercible = __webpack_require__(/*! ../internals/require-object-coercible */ \"./node_modules/core-js/internals/require-object-coercible.js\");\nvar advanceStringIndex = __webpack_require__(/*! ../internals/advance-string-index */ \"./node_modules/core-js/internals/advance-string-index.js\");\nvar regExpExec = __webpack_require__(/*! ../internals/regexp-exec-abstract */ \"./node_modules/core-js/internals/regexp-exec-abstract.js\");\n\n// @@match logic\nfixRegExpWellKnownSymbolLogic('match', 1, function (MATCH, nativeMatch, maybeCallNative) {\n return [\n // `String.prototype.match` method\n // https://tc39.github.io/ecma262/#sec-string.prototype.match\n function match(regexp) {\n var O = requireObjectCoercible(this);\n var matcher = regexp == undefined ? undefined : regexp[MATCH];\n return matcher !== undefined ? matcher.call(regexp, O) : new RegExp(regexp)[MATCH](String(O));\n },\n // `RegExp.prototype[@@match]` method\n // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@match\n function (regexp) {\n var res = maybeCallNative(nativeMatch, regexp, this);\n if (res.done) return res.value;\n\n var rx = anObject(regexp);\n var S = String(this);\n\n if (!rx.global) return regExpExec(rx, S);\n\n var fullUnicode = rx.unicode;\n rx.lastIndex = 0;\n var A = [];\n var n = 0;\n var result;\n while ((result = regExpExec(rx, S)) !== null) {\n var matchStr = String(result[0]);\n A[n] = matchStr;\n if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);\n n++;\n }\n return n === 0 ? null : A;\n }\n ];\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5tYXRjaC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lcy5zdHJpbmcubWF0Y2guanM/NDY2ZCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG52YXIgZml4UmVnRXhwV2VsbEtub3duU3ltYm9sTG9naWMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZml4LXJlZ2V4cC13ZWxsLWtub3duLXN5bWJvbC1sb2dpYycpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2FuLW9iamVjdCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3RvLWxlbmd0aCcpO1xudmFyIHJlcXVpcmVPYmplY3RDb2VyY2libGUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvcmVxdWlyZS1vYmplY3QtY29lcmNpYmxlJyk7XG52YXIgYWR2YW5jZVN0cmluZ0luZGV4ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2FkdmFuY2Utc3RyaW5nLWluZGV4Jyk7XG52YXIgcmVnRXhwRXhlYyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9yZWdleHAtZXhlYy1hYnN0cmFjdCcpO1xuXG4vLyBAQG1hdGNoIGxvZ2ljXG5maXhSZWdFeHBXZWxsS25vd25TeW1ib2xMb2dpYygnbWF0Y2gnLCAxLCBmdW5jdGlvbiAoTUFUQ0gsIG5hdGl2ZU1hdGNoLCBtYXliZUNhbGxOYXRpdmUpIHtcbiAgcmV0dXJuIFtcbiAgICAvLyBgU3RyaW5nLnByb3RvdHlwZS5tYXRjaGAgbWV0aG9kXG4gICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtc3RyaW5nLnByb3RvdHlwZS5tYXRjaFxuICAgIGZ1bmN0aW9uIG1hdGNoKHJlZ2V4cCkge1xuICAgICAgdmFyIE8gPSByZXF1aXJlT2JqZWN0Q29lcmNpYmxlKHRoaXMpO1xuICAgICAgdmFyIG1hdGNoZXIgPSByZWdleHAgPT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogcmVnZXhwW01BVENIXTtcbiAgICAgIHJldHVybiBtYXRjaGVyICE9PSB1bmRlZmluZWQgPyBtYXRjaGVyLmNhbGwocmVnZXhwLCBPKSA6IG5ldyBSZWdFeHAocmVnZXhwKVtNQVRDSF0oU3RyaW5nKE8pKTtcbiAgICB9LFxuICAgIC8vIGBSZWdFeHAucHJvdG90eXBlW0BAbWF0Y2hdYCBtZXRob2RcbiAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1yZWdleHAucHJvdG90eXBlLUBAbWF0Y2hcbiAgICBmdW5jdGlvbiAocmVnZXhwKSB7XG4gICAgICB2YXIgcmVzID0gbWF5YmVDYWxsTmF0aXZlKG5hdGl2ZU1hdGNoLCByZWdleHAsIHRoaXMpO1xuICAgICAgaWYgKHJlcy5kb25lKSByZXR1cm4gcmVzLnZhbHVlO1xuXG4gICAgICB2YXIgcnggPSBhbk9iamVjdChyZWdleHApO1xuICAgICAgdmFyIFMgPSBTdHJpbmcodGhpcyk7XG5cbiAgICAgIGlmICghcnguZ2xvYmFsKSByZXR1cm4gcmVnRXhwRXhlYyhyeCwgUyk7XG5cbiAgICAgIHZhciBmdWxsVW5pY29kZSA9IHJ4LnVuaWNvZGU7XG4gICAgICByeC5sYXN0SW5kZXggPSAwO1xuICAgICAgdmFyIEEgPSBbXTtcbiAgICAgIHZhciBuID0gMDtcbiAgICAgIHZhciByZXN1bHQ7XG4gICAgICB3aGlsZSAoKHJlc3VsdCA9IHJlZ0V4cEV4ZWMocngsIFMpKSAhPT0gbnVsbCkge1xuICAgICAgICB2YXIgbWF0Y2hTdHIgPSBTdHJpbmcocmVzdWx0WzBdKTtcbiAgICAgICAgQVtuXSA9IG1hdGNoU3RyO1xuICAgICAgICBpZiAobWF0Y2hTdHIgPT09ICcnKSByeC5sYXN0SW5kZXggPSBhZHZhbmNlU3RyaW5nSW5kZXgoUywgdG9MZW5ndGgocngubGFzdEluZGV4KSwgZnVsbFVuaWNvZGUpO1xuICAgICAgICBuKys7XG4gICAgICB9XG4gICAgICByZXR1cm4gbiA9PT0gMCA/IG51bGwgOiBBO1xuICAgIH1cbiAgXTtcbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.match.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.pad-end.js": +/*!***********************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.pad-end.js ***! + \***********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar internalStringPad = __webpack_require__(/*! ../internals/string-pad */ \"./node_modules/core-js/internals/string-pad.js\");\nvar WEBKIT_BUG = __webpack_require__(/*! ../internals/webkit-string-pad-bug */ \"./node_modules/core-js/internals/webkit-string-pad-bug.js\");\n\n// `String.prototype.padEnd` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.padend\n$({ target: 'String', proto: true, forced: WEBKIT_BUG }, {\n padEnd: function padEnd(maxLength /* , fillString = ' ' */) {\n return internalStringPad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, false);\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5wYWQtZW5kLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5wYWQtZW5kLmpzPzg0M2MiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xudmFyICQgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZXhwb3J0Jyk7XG52YXIgaW50ZXJuYWxTdHJpbmdQYWQgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvc3RyaW5nLXBhZCcpO1xudmFyIFdFQktJVF9CVUcgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvd2Via2l0LXN0cmluZy1wYWQtYnVnJyk7XG5cbi8vIGBTdHJpbmcucHJvdG90eXBlLnBhZEVuZGAgbWV0aG9kXG4vLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1zdHJpbmcucHJvdG90eXBlLnBhZGVuZFxuJCh7IHRhcmdldDogJ1N0cmluZycsIHByb3RvOiB0cnVlLCBmb3JjZWQ6IFdFQktJVF9CVUcgfSwge1xuICBwYWRFbmQ6IGZ1bmN0aW9uIHBhZEVuZChtYXhMZW5ndGggLyogLCBmaWxsU3RyaW5nID0gJyAnICovKSB7XG4gICAgcmV0dXJuIGludGVybmFsU3RyaW5nUGFkKHRoaXMsIG1heExlbmd0aCwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQsIGZhbHNlKTtcbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.pad-end.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.pad-start.js": +/*!*************************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.pad-start.js ***! + \*************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar internalStringPad = __webpack_require__(/*! ../internals/string-pad */ \"./node_modules/core-js/internals/string-pad.js\");\nvar WEBKIT_BUG = __webpack_require__(/*! ../internals/webkit-string-pad-bug */ \"./node_modules/core-js/internals/webkit-string-pad-bug.js\");\n\n// `String.prototype.padStart` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.padstart\n$({ target: 'String', proto: true, forced: WEBKIT_BUG }, {\n padStart: function padStart(maxLength /* , fillString = ' ' */) {\n return internalStringPad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, true);\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5wYWQtc3RhcnQuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXMuc3RyaW5nLnBhZC1zdGFydC5qcz80ZDkwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcbnZhciAkID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2V4cG9ydCcpO1xudmFyIGludGVybmFsU3RyaW5nUGFkID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3N0cmluZy1wYWQnKTtcbnZhciBXRUJLSVRfQlVHID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3dlYmtpdC1zdHJpbmctcGFkLWJ1ZycpO1xuXG4vLyBgU3RyaW5nLnByb3RvdHlwZS5wYWRTdGFydGAgbWV0aG9kXG4vLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1zdHJpbmcucHJvdG90eXBlLnBhZHN0YXJ0XG4kKHsgdGFyZ2V0OiAnU3RyaW5nJywgcHJvdG86IHRydWUsIGZvcmNlZDogV0VCS0lUX0JVRyB9LCB7XG4gIHBhZFN0YXJ0OiBmdW5jdGlvbiBwYWRTdGFydChtYXhMZW5ndGggLyogLCBmaWxsU3RyaW5nID0gJyAnICovKSB7XG4gICAgcmV0dXJuIGludGVybmFsU3RyaW5nUGFkKHRoaXMsIG1heExlbmd0aCwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQsIHRydWUpO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.pad-start.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.raw.js": +/*!*******************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.raw.js ***! + \*******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar toIndexedObject = __webpack_require__(/*! ../internals/to-indexed-object */ \"./node_modules/core-js/internals/to-indexed-object.js\");\nvar toLength = __webpack_require__(/*! ../internals/to-length */ \"./node_modules/core-js/internals/to-length.js\");\n\n// `String.raw` method\n// https://tc39.github.io/ecma262/#sec-string.raw\n$({ target: 'String', stat: true }, {\n raw: function raw(template) {\n var rawTemplate = toIndexedObject(template.raw);\n var literalSegments = toLength(rawTemplate.length);\n var argumentsLength = arguments.length;\n var elements = [];\n var i = 0;\n while (literalSegments > i) {\n elements.push(String(rawTemplate[i++]));\n if (i < argumentsLength) elements.push(String(arguments[i]));\n } return elements.join('');\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5yYXcuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXMuc3RyaW5nLnJhdy5qcz9kODBmIl0sInNvdXJjZXNDb250ZW50IjpbInZhciAkID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2V4cG9ydCcpO1xudmFyIHRvSW5kZXhlZE9iamVjdCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy90by1pbmRleGVkLW9iamVjdCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3RvLWxlbmd0aCcpO1xuXG4vLyBgU3RyaW5nLnJhd2AgbWV0aG9kXG4vLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1zdHJpbmcucmF3XG4kKHsgdGFyZ2V0OiAnU3RyaW5nJywgc3RhdDogdHJ1ZSB9LCB7XG4gIHJhdzogZnVuY3Rpb24gcmF3KHRlbXBsYXRlKSB7XG4gICAgdmFyIHJhd1RlbXBsYXRlID0gdG9JbmRleGVkT2JqZWN0KHRlbXBsYXRlLnJhdyk7XG4gICAgdmFyIGxpdGVyYWxTZWdtZW50cyA9IHRvTGVuZ3RoKHJhd1RlbXBsYXRlLmxlbmd0aCk7XG4gICAgdmFyIGFyZ3VtZW50c0xlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgdmFyIGVsZW1lbnRzID0gW107XG4gICAgdmFyIGkgPSAwO1xuICAgIHdoaWxlIChsaXRlcmFsU2VnbWVudHMgPiBpKSB7XG4gICAgICBlbGVtZW50cy5wdXNoKFN0cmluZyhyYXdUZW1wbGF0ZVtpKytdKSk7XG4gICAgICBpZiAoaSA8IGFyZ3VtZW50c0xlbmd0aCkgZWxlbWVudHMucHVzaChTdHJpbmcoYXJndW1lbnRzW2ldKSk7XG4gICAgfSByZXR1cm4gZWxlbWVudHMuam9pbignJyk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.raw.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.repeat.js": +/*!**********************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.repeat.js ***! + \**********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar repeat = __webpack_require__(/*! ../internals/string-repeat */ \"./node_modules/core-js/internals/string-repeat.js\");\n\n// `String.prototype.repeat` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.repeat\n$({ target: 'String', proto: true }, {\n repeat: repeat\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5yZXBlYXQuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXMuc3RyaW5nLnJlcGVhdC5qcz8zOGNmIl0sInNvdXJjZXNDb250ZW50IjpbInZhciAkID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2V4cG9ydCcpO1xudmFyIHJlcGVhdCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9zdHJpbmctcmVwZWF0Jyk7XG5cbi8vIGBTdHJpbmcucHJvdG90eXBlLnJlcGVhdGAgbWV0aG9kXG4vLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1zdHJpbmcucHJvdG90eXBlLnJlcGVhdFxuJCh7IHRhcmdldDogJ1N0cmluZycsIHByb3RvOiB0cnVlIH0sIHtcbiAgcmVwZWF0OiByZXBlYXRcbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.repeat.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.replace.js": +/*!***********************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.replace.js ***! + \***********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar fixRegExpWellKnownSymbolLogic = __webpack_require__(/*! ../internals/fix-regexp-well-known-symbol-logic */ \"./node_modules/core-js/internals/fix-regexp-well-known-symbol-logic.js\");\nvar anObject = __webpack_require__(/*! ../internals/an-object */ \"./node_modules/core-js/internals/an-object.js\");\nvar toObject = __webpack_require__(/*! ../internals/to-object */ \"./node_modules/core-js/internals/to-object.js\");\nvar toLength = __webpack_require__(/*! ../internals/to-length */ \"./node_modules/core-js/internals/to-length.js\");\nvar toInteger = __webpack_require__(/*! ../internals/to-integer */ \"./node_modules/core-js/internals/to-integer.js\");\nvar requireObjectCoercible = __webpack_require__(/*! ../internals/require-object-coercible */ \"./node_modules/core-js/internals/require-object-coercible.js\");\nvar advanceStringIndex = __webpack_require__(/*! ../internals/advance-string-index */ \"./node_modules/core-js/internals/advance-string-index.js\");\nvar regExpExec = __webpack_require__(/*! ../internals/regexp-exec-abstract */ \"./node_modules/core-js/internals/regexp-exec-abstract.js\");\n\nvar max = Math.max;\nvar min = Math.min;\nvar floor = Math.floor;\nvar SUBSTITUTION_SYMBOLS = /\\$([$&'`]|\\d\\d?|<[^>]*>)/g;\nvar SUBSTITUTION_SYMBOLS_NO_NAMED = /\\$([$&'`]|\\d\\d?)/g;\n\nvar maybeToString = function (it) {\n return it === undefined ? it : String(it);\n};\n\n// @@replace logic\nfixRegExpWellKnownSymbolLogic('replace', 2, function (REPLACE, nativeReplace, maybeCallNative) {\n return [\n // `String.prototype.replace` method\n // https://tc39.github.io/ecma262/#sec-string.prototype.replace\n function replace(searchValue, replaceValue) {\n var O = requireObjectCoercible(this);\n var replacer = searchValue == undefined ? undefined : searchValue[REPLACE];\n return replacer !== undefined\n ? replacer.call(searchValue, O, replaceValue)\n : nativeReplace.call(String(O), searchValue, replaceValue);\n },\n // `RegExp.prototype[@@replace]` method\n // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@replace\n function (regexp, replaceValue) {\n var res = maybeCallNative(nativeReplace, regexp, this, replaceValue);\n if (res.done) return res.value;\n\n var rx = anObject(regexp);\n var S = String(this);\n\n var functionalReplace = typeof replaceValue === 'function';\n if (!functionalReplace) replaceValue = String(replaceValue);\n\n var global = rx.global;\n if (global) {\n var fullUnicode = rx.unicode;\n rx.lastIndex = 0;\n }\n var results = [];\n while (true) {\n var result = regExpExec(rx, S);\n if (result === null) break;\n\n results.push(result);\n if (!global) break;\n\n var matchStr = String(result[0]);\n if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);\n }\n\n var accumulatedResult = '';\n var nextSourcePosition = 0;\n for (var i = 0; i < results.length; i++) {\n result = results[i];\n\n var matched = String(result[0]);\n var position = max(min(toInteger(result.index), S.length), 0);\n var captures = [];\n // NOTE: This is equivalent to\n // captures = result.slice(1).map(maybeToString)\n // but for some reason `nativeSlice.call(result, 1, result.length)` (called in\n // the slice polyfill when slicing native arrays) \"doesn't work\" in safari 9 and\n // causes a crash (https://pastebin.com/N21QzeQA) when trying to debug it.\n for (var j = 1; j < result.length; j++) captures.push(maybeToString(result[j]));\n var namedCaptures = result.groups;\n if (functionalReplace) {\n var replacerArgs = [matched].concat(captures, position, S);\n if (namedCaptures !== undefined) replacerArgs.push(namedCaptures);\n var replacement = String(replaceValue.apply(undefined, replacerArgs));\n } else {\n replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue);\n }\n if (position >= nextSourcePosition) {\n accumulatedResult += S.slice(nextSourcePosition, position) + replacement;\n nextSourcePosition = position + matched.length;\n }\n }\n return accumulatedResult + S.slice(nextSourcePosition);\n }\n ];\n\n // https://tc39.github.io/ecma262/#sec-getsubstitution\n function getSubstitution(matched, str, position, captures, namedCaptures, replacement) {\n var tailPos = position + matched.length;\n var m = captures.length;\n var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED;\n if (namedCaptures !== undefined) {\n namedCaptures = toObject(namedCaptures);\n symbols = SUBSTITUTION_SYMBOLS;\n }\n return nativeReplace.call(replacement, symbols, function (match, ch) {\n var capture;\n switch (ch.charAt(0)) {\n case '$': return '$';\n case '&': return matched;\n case '`': return str.slice(0, position);\n case \"'\": return str.slice(tailPos);\n case '<':\n capture = namedCaptures[ch.slice(1, -1)];\n break;\n default: // \\d\\d?\n var n = +ch;\n if (n === 0) return match;\n if (n > m) {\n var f = floor(n / 10);\n if (f === 0) return match;\n if (f <= m) return captures[f - 1] === undefined ? ch.charAt(1) : captures[f - 1] + ch.charAt(1);\n return match;\n }\n capture = captures[n - 1];\n }\n return capture === undefined ? '' : capture;\n });\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5yZXBsYWNlLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5yZXBsYWNlLmpzPzUzMTkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xudmFyIGZpeFJlZ0V4cFdlbGxLbm93blN5bWJvbExvZ2ljID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2ZpeC1yZWdleHAtd2VsbC1rbm93bi1zeW1ib2wtbG9naWMnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9hbi1vYmplY3QnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy90by1vYmplY3QnKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy90by1sZW5ndGgnKTtcbnZhciB0b0ludGVnZXIgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvdG8taW50ZWdlcicpO1xudmFyIHJlcXVpcmVPYmplY3RDb2VyY2libGUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvcmVxdWlyZS1vYmplY3QtY29lcmNpYmxlJyk7XG52YXIgYWR2YW5jZVN0cmluZ0luZGV4ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2FkdmFuY2Utc3RyaW5nLWluZGV4Jyk7XG52YXIgcmVnRXhwRXhlYyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9yZWdleHAtZXhlYy1hYnN0cmFjdCcpO1xuXG52YXIgbWF4ID0gTWF0aC5tYXg7XG52YXIgbWluID0gTWF0aC5taW47XG52YXIgZmxvb3IgPSBNYXRoLmZsb29yO1xudmFyIFNVQlNUSVRVVElPTl9TWU1CT0xTID0gL1xcJChbJCYnYF18XFxkXFxkP3w8W14+XSo+KS9nO1xudmFyIFNVQlNUSVRVVElPTl9TWU1CT0xTX05PX05BTUVEID0gL1xcJChbJCYnYF18XFxkXFxkPykvZztcblxudmFyIG1heWJlVG9TdHJpbmcgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIGl0ID09PSB1bmRlZmluZWQgPyBpdCA6IFN0cmluZyhpdCk7XG59O1xuXG4vLyBAQHJlcGxhY2UgbG9naWNcbmZpeFJlZ0V4cFdlbGxLbm93blN5bWJvbExvZ2ljKCdyZXBsYWNlJywgMiwgZnVuY3Rpb24gKFJFUExBQ0UsIG5hdGl2ZVJlcGxhY2UsIG1heWJlQ2FsbE5hdGl2ZSkge1xuICByZXR1cm4gW1xuICAgIC8vIGBTdHJpbmcucHJvdG90eXBlLnJlcGxhY2VgIG1ldGhvZFxuICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXN0cmluZy5wcm90b3R5cGUucmVwbGFjZVxuICAgIGZ1bmN0aW9uIHJlcGxhY2Uoc2VhcmNoVmFsdWUsIHJlcGxhY2VWYWx1ZSkge1xuICAgICAgdmFyIE8gPSByZXF1aXJlT2JqZWN0Q29lcmNpYmxlKHRoaXMpO1xuICAgICAgdmFyIHJlcGxhY2VyID0gc2VhcmNoVmFsdWUgPT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogc2VhcmNoVmFsdWVbUkVQTEFDRV07XG4gICAgICByZXR1cm4gcmVwbGFjZXIgIT09IHVuZGVmaW5lZFxuICAgICAgICA/IHJlcGxhY2VyLmNhbGwoc2VhcmNoVmFsdWUsIE8sIHJlcGxhY2VWYWx1ZSlcbiAgICAgICAgOiBuYXRpdmVSZXBsYWNlLmNhbGwoU3RyaW5nKE8pLCBzZWFyY2hWYWx1ZSwgcmVwbGFjZVZhbHVlKTtcbiAgICB9LFxuICAgIC8vIGBSZWdFeHAucHJvdG90eXBlW0BAcmVwbGFjZV1gIG1ldGhvZFxuICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXJlZ2V4cC5wcm90b3R5cGUtQEByZXBsYWNlXG4gICAgZnVuY3Rpb24gKHJlZ2V4cCwgcmVwbGFjZVZhbHVlKSB7XG4gICAgICB2YXIgcmVzID0gbWF5YmVDYWxsTmF0aXZlKG5hdGl2ZVJlcGxhY2UsIHJlZ2V4cCwgdGhpcywgcmVwbGFjZVZhbHVlKTtcbiAgICAgIGlmIChyZXMuZG9uZSkgcmV0dXJuIHJlcy52YWx1ZTtcblxuICAgICAgdmFyIHJ4ID0gYW5PYmplY3QocmVnZXhwKTtcbiAgICAgIHZhciBTID0gU3RyaW5nKHRoaXMpO1xuXG4gICAgICB2YXIgZnVuY3Rpb25hbFJlcGxhY2UgPSB0eXBlb2YgcmVwbGFjZVZhbHVlID09PSAnZnVuY3Rpb24nO1xuICAgICAgaWYgKCFmdW5jdGlvbmFsUmVwbGFjZSkgcmVwbGFjZVZhbHVlID0gU3RyaW5nKHJlcGxhY2VWYWx1ZSk7XG5cbiAgICAgIHZhciBnbG9iYWwgPSByeC5nbG9iYWw7XG4gICAgICBpZiAoZ2xvYmFsKSB7XG4gICAgICAgIHZhciBmdWxsVW5pY29kZSA9IHJ4LnVuaWNvZGU7XG4gICAgICAgIHJ4Lmxhc3RJbmRleCA9IDA7XG4gICAgICB9XG4gICAgICB2YXIgcmVzdWx0cyA9IFtdO1xuICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IHJlZ0V4cEV4ZWMocngsIFMpO1xuICAgICAgICBpZiAocmVzdWx0ID09PSBudWxsKSBicmVhaztcblxuICAgICAgICByZXN1bHRzLnB1c2gocmVzdWx0KTtcbiAgICAgICAgaWYgKCFnbG9iYWwpIGJyZWFrO1xuXG4gICAgICAgIHZhciBtYXRjaFN0ciA9IFN0cmluZyhyZXN1bHRbMF0pO1xuICAgICAgICBpZiAobWF0Y2hTdHIgPT09ICcnKSByeC5sYXN0SW5kZXggPSBhZHZhbmNlU3RyaW5nSW5kZXgoUywgdG9MZW5ndGgocngubGFzdEluZGV4KSwgZnVsbFVuaWNvZGUpO1xuICAgICAgfVxuXG4gICAgICB2YXIgYWNjdW11bGF0ZWRSZXN1bHQgPSAnJztcbiAgICAgIHZhciBuZXh0U291cmNlUG9zaXRpb24gPSAwO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZXN1bHRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHJlc3VsdCA9IHJlc3VsdHNbaV07XG5cbiAgICAgICAgdmFyIG1hdGNoZWQgPSBTdHJpbmcocmVzdWx0WzBdKTtcbiAgICAgICAgdmFyIHBvc2l0aW9uID0gbWF4KG1pbih0b0ludGVnZXIocmVzdWx0LmluZGV4KSwgUy5sZW5ndGgpLCAwKTtcbiAgICAgICAgdmFyIGNhcHR1cmVzID0gW107XG4gICAgICAgIC8vIE5PVEU6IFRoaXMgaXMgZXF1aXZhbGVudCB0b1xuICAgICAgICAvLyAgIGNhcHR1cmVzID0gcmVzdWx0LnNsaWNlKDEpLm1hcChtYXliZVRvU3RyaW5nKVxuICAgICAgICAvLyBidXQgZm9yIHNvbWUgcmVhc29uIGBuYXRpdmVTbGljZS5jYWxsKHJlc3VsdCwgMSwgcmVzdWx0Lmxlbmd0aClgIChjYWxsZWQgaW5cbiAgICAgICAgLy8gdGhlIHNsaWNlIHBvbHlmaWxsIHdoZW4gc2xpY2luZyBuYXRpdmUgYXJyYXlzKSBcImRvZXNuJ3Qgd29ya1wiIGluIHNhZmFyaSA5IGFuZFxuICAgICAgICAvLyBjYXVzZXMgYSBjcmFzaCAoaHR0cHM6Ly9wYXN0ZWJpbi5jb20vTjIxUXplUUEpIHdoZW4gdHJ5aW5nIHRvIGRlYnVnIGl0LlxuICAgICAgICBmb3IgKHZhciBqID0gMTsgaiA8IHJlc3VsdC5sZW5ndGg7IGorKykgY2FwdHVyZXMucHVzaChtYXliZVRvU3RyaW5nKHJlc3VsdFtqXSkpO1xuICAgICAgICB2YXIgbmFtZWRDYXB0dXJlcyA9IHJlc3VsdC5ncm91cHM7XG4gICAgICAgIGlmIChmdW5jdGlvbmFsUmVwbGFjZSkge1xuICAgICAgICAgIHZhciByZXBsYWNlckFyZ3MgPSBbbWF0Y2hlZF0uY29uY2F0KGNhcHR1cmVzLCBwb3NpdGlvbiwgUyk7XG4gICAgICAgICAgaWYgKG5hbWVkQ2FwdHVyZXMgIT09IHVuZGVmaW5lZCkgcmVwbGFjZXJBcmdzLnB1c2gobmFtZWRDYXB0dXJlcyk7XG4gICAgICAgICAgdmFyIHJlcGxhY2VtZW50ID0gU3RyaW5nKHJlcGxhY2VWYWx1ZS5hcHBseSh1bmRlZmluZWQsIHJlcGxhY2VyQXJncykpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlcGxhY2VtZW50ID0gZ2V0U3Vic3RpdHV0aW9uKG1hdGNoZWQsIFMsIHBvc2l0aW9uLCBjYXB0dXJlcywgbmFtZWRDYXB0dXJlcywgcmVwbGFjZVZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocG9zaXRpb24gPj0gbmV4dFNvdXJjZVBvc2l0aW9uKSB7XG4gICAgICAgICAgYWNjdW11bGF0ZWRSZXN1bHQgKz0gUy5zbGljZShuZXh0U291cmNlUG9zaXRpb24sIHBvc2l0aW9uKSArIHJlcGxhY2VtZW50O1xuICAgICAgICAgIG5leHRTb3VyY2VQb3NpdGlvbiA9IHBvc2l0aW9uICsgbWF0Y2hlZC5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBhY2N1bXVsYXRlZFJlc3VsdCArIFMuc2xpY2UobmV4dFNvdXJjZVBvc2l0aW9uKTtcbiAgICB9XG4gIF07XG5cbiAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtZ2V0c3Vic3RpdHV0aW9uXG4gIGZ1bmN0aW9uIGdldFN1YnN0aXR1dGlvbihtYXRjaGVkLCBzdHIsIHBvc2l0aW9uLCBjYXB0dXJlcywgbmFtZWRDYXB0dXJlcywgcmVwbGFjZW1lbnQpIHtcbiAgICB2YXIgdGFpbFBvcyA9IHBvc2l0aW9uICsgbWF0Y2hlZC5sZW5ndGg7XG4gICAgdmFyIG0gPSBjYXB0dXJlcy5sZW5ndGg7XG4gICAgdmFyIHN5bWJvbHMgPSBTVUJTVElUVVRJT05fU1lNQk9MU19OT19OQU1FRDtcbiAgICBpZiAobmFtZWRDYXB0dXJlcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBuYW1lZENhcHR1cmVzID0gdG9PYmplY3QobmFtZWRDYXB0dXJlcyk7XG4gICAgICBzeW1ib2xzID0gU1VCU1RJVFVUSU9OX1NZTUJPTFM7XG4gICAgfVxuICAgIHJldHVybiBuYXRpdmVSZXBsYWNlLmNhbGwocmVwbGFjZW1lbnQsIHN5bWJvbHMsIGZ1bmN0aW9uIChtYXRjaCwgY2gpIHtcbiAgICAgIHZhciBjYXB0dXJlO1xuICAgICAgc3dpdGNoIChjaC5jaGFyQXQoMCkpIHtcbiAgICAgICAgY2FzZSAnJCc6IHJldHVybiAnJCc7XG4gICAgICAgIGNhc2UgJyYnOiByZXR1cm4gbWF0Y2hlZDtcbiAgICAgICAgY2FzZSAnYCc6IHJldHVybiBzdHIuc2xpY2UoMCwgcG9zaXRpb24pO1xuICAgICAgICBjYXNlIFwiJ1wiOiByZXR1cm4gc3RyLnNsaWNlKHRhaWxQb3MpO1xuICAgICAgICBjYXNlICc8JzpcbiAgICAgICAgICBjYXB0dXJlID0gbmFtZWRDYXB0dXJlc1tjaC5zbGljZSgxLCAtMSldO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OiAvLyBcXGRcXGQ/XG4gICAgICAgICAgdmFyIG4gPSArY2g7XG4gICAgICAgICAgaWYgKG4gPT09IDApIHJldHVybiBtYXRjaDtcbiAgICAgICAgICBpZiAobiA+IG0pIHtcbiAgICAgICAgICAgIHZhciBmID0gZmxvb3IobiAvIDEwKTtcbiAgICAgICAgICAgIGlmIChmID09PSAwKSByZXR1cm4gbWF0Y2g7XG4gICAgICAgICAgICBpZiAoZiA8PSBtKSByZXR1cm4gY2FwdHVyZXNbZiAtIDFdID09PSB1bmRlZmluZWQgPyBjaC5jaGFyQXQoMSkgOiBjYXB0dXJlc1tmIC0gMV0gKyBjaC5jaGFyQXQoMSk7XG4gICAgICAgICAgICByZXR1cm4gbWF0Y2g7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhcHR1cmUgPSBjYXB0dXJlc1tuIC0gMV07XG4gICAgICB9XG4gICAgICByZXR1cm4gY2FwdHVyZSA9PT0gdW5kZWZpbmVkID8gJycgOiBjYXB0dXJlO1xuICAgIH0pO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.replace.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.search.js": +/*!**********************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.search.js ***! + \**********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar fixRegExpWellKnownSymbolLogic = __webpack_require__(/*! ../internals/fix-regexp-well-known-symbol-logic */ \"./node_modules/core-js/internals/fix-regexp-well-known-symbol-logic.js\");\nvar anObject = __webpack_require__(/*! ../internals/an-object */ \"./node_modules/core-js/internals/an-object.js\");\nvar requireObjectCoercible = __webpack_require__(/*! ../internals/require-object-coercible */ \"./node_modules/core-js/internals/require-object-coercible.js\");\nvar sameValue = __webpack_require__(/*! ../internals/same-value */ \"./node_modules/core-js/internals/same-value.js\");\nvar regExpExec = __webpack_require__(/*! ../internals/regexp-exec-abstract */ \"./node_modules/core-js/internals/regexp-exec-abstract.js\");\n\n// @@search logic\nfixRegExpWellKnownSymbolLogic('search', 1, function (SEARCH, nativeSearch, maybeCallNative) {\n return [\n // `String.prototype.search` method\n // https://tc39.github.io/ecma262/#sec-string.prototype.search\n function search(regexp) {\n var O = requireObjectCoercible(this);\n var searcher = regexp == undefined ? undefined : regexp[SEARCH];\n return searcher !== undefined ? searcher.call(regexp, O) : new RegExp(regexp)[SEARCH](String(O));\n },\n // `RegExp.prototype[@@search]` method\n // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@search\n function (regexp) {\n var res = maybeCallNative(nativeSearch, regexp, this);\n if (res.done) return res.value;\n\n var rx = anObject(regexp);\n var S = String(this);\n\n var previousLastIndex = rx.lastIndex;\n if (!sameValue(previousLastIndex, 0)) rx.lastIndex = 0;\n var result = regExpExec(rx, S);\n if (!sameValue(rx.lastIndex, previousLastIndex)) rx.lastIndex = previousLastIndex;\n return result === null ? -1 : result.index;\n }\n ];\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5zZWFyY2guanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXMuc3RyaW5nLnNlYXJjaC5qcz84NDFjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcbnZhciBmaXhSZWdFeHBXZWxsS25vd25TeW1ib2xMb2dpYyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9maXgtcmVnZXhwLXdlbGwta25vd24tc3ltYm9sLWxvZ2ljJyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvYW4tb2JqZWN0Jyk7XG52YXIgcmVxdWlyZU9iamVjdENvZXJjaWJsZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9yZXF1aXJlLW9iamVjdC1jb2VyY2libGUnKTtcbnZhciBzYW1lVmFsdWUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvc2FtZS12YWx1ZScpO1xudmFyIHJlZ0V4cEV4ZWMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvcmVnZXhwLWV4ZWMtYWJzdHJhY3QnKTtcblxuLy8gQEBzZWFyY2ggbG9naWNcbmZpeFJlZ0V4cFdlbGxLbm93blN5bWJvbExvZ2ljKCdzZWFyY2gnLCAxLCBmdW5jdGlvbiAoU0VBUkNILCBuYXRpdmVTZWFyY2gsIG1heWJlQ2FsbE5hdGl2ZSkge1xuICByZXR1cm4gW1xuICAgIC8vIGBTdHJpbmcucHJvdG90eXBlLnNlYXJjaGAgbWV0aG9kXG4gICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtc3RyaW5nLnByb3RvdHlwZS5zZWFyY2hcbiAgICBmdW5jdGlvbiBzZWFyY2gocmVnZXhwKSB7XG4gICAgICB2YXIgTyA9IHJlcXVpcmVPYmplY3RDb2VyY2libGUodGhpcyk7XG4gICAgICB2YXIgc2VhcmNoZXIgPSByZWdleHAgPT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogcmVnZXhwW1NFQVJDSF07XG4gICAgICByZXR1cm4gc2VhcmNoZXIgIT09IHVuZGVmaW5lZCA/IHNlYXJjaGVyLmNhbGwocmVnZXhwLCBPKSA6IG5ldyBSZWdFeHAocmVnZXhwKVtTRUFSQ0hdKFN0cmluZyhPKSk7XG4gICAgfSxcbiAgICAvLyBgUmVnRXhwLnByb3RvdHlwZVtAQHNlYXJjaF1gIG1ldGhvZFxuICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXJlZ2V4cC5wcm90b3R5cGUtQEBzZWFyY2hcbiAgICBmdW5jdGlvbiAocmVnZXhwKSB7XG4gICAgICB2YXIgcmVzID0gbWF5YmVDYWxsTmF0aXZlKG5hdGl2ZVNlYXJjaCwgcmVnZXhwLCB0aGlzKTtcbiAgICAgIGlmIChyZXMuZG9uZSkgcmV0dXJuIHJlcy52YWx1ZTtcblxuICAgICAgdmFyIHJ4ID0gYW5PYmplY3QocmVnZXhwKTtcbiAgICAgIHZhciBTID0gU3RyaW5nKHRoaXMpO1xuXG4gICAgICB2YXIgcHJldmlvdXNMYXN0SW5kZXggPSByeC5sYXN0SW5kZXg7XG4gICAgICBpZiAoIXNhbWVWYWx1ZShwcmV2aW91c0xhc3RJbmRleCwgMCkpIHJ4Lmxhc3RJbmRleCA9IDA7XG4gICAgICB2YXIgcmVzdWx0ID0gcmVnRXhwRXhlYyhyeCwgUyk7XG4gICAgICBpZiAoIXNhbWVWYWx1ZShyeC5sYXN0SW5kZXgsIHByZXZpb3VzTGFzdEluZGV4KSkgcngubGFzdEluZGV4ID0gcHJldmlvdXNMYXN0SW5kZXg7XG4gICAgICByZXR1cm4gcmVzdWx0ID09PSBudWxsID8gLTEgOiByZXN1bHQuaW5kZXg7XG4gICAgfVxuICBdO1xufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.search.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.small.js": +/*!*********************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.small.js ***! + \*********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar createHTML = __webpack_require__(/*! ../internals/create-html */ \"./node_modules/core-js/internals/create-html.js\");\nvar forcedStringHTMLMethod = __webpack_require__(/*! ../internals/forced-string-html-method */ \"./node_modules/core-js/internals/forced-string-html-method.js\");\n\n// `String.prototype.small` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.small\n$({ target: 'String', proto: true, forced: forcedStringHTMLMethod('small') }, {\n small: function small() {\n return createHTML(this, 'small', '', '');\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5zbWFsbC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lcy5zdHJpbmcuc21hbGwuanM/Yzk2YSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG52YXIgJCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9leHBvcnQnKTtcbnZhciBjcmVhdGVIVE1MID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2NyZWF0ZS1odG1sJyk7XG52YXIgZm9yY2VkU3RyaW5nSFRNTE1ldGhvZCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9mb3JjZWQtc3RyaW5nLWh0bWwtbWV0aG9kJyk7XG5cbi8vIGBTdHJpbmcucHJvdG90eXBlLnNtYWxsYCBtZXRob2Rcbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXN0cmluZy5wcm90b3R5cGUuc21hbGxcbiQoeyB0YXJnZXQ6ICdTdHJpbmcnLCBwcm90bzogdHJ1ZSwgZm9yY2VkOiBmb3JjZWRTdHJpbmdIVE1MTWV0aG9kKCdzbWFsbCcpIH0sIHtcbiAgc21hbGw6IGZ1bmN0aW9uIHNtYWxsKCkge1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdzbWFsbCcsICcnLCAnJyk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.small.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.split.js": +/*!*********************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.split.js ***! + \*********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar fixRegExpWellKnownSymbolLogic = __webpack_require__(/*! ../internals/fix-regexp-well-known-symbol-logic */ \"./node_modules/core-js/internals/fix-regexp-well-known-symbol-logic.js\");\nvar isRegExp = __webpack_require__(/*! ../internals/is-regexp */ \"./node_modules/core-js/internals/is-regexp.js\");\nvar anObject = __webpack_require__(/*! ../internals/an-object */ \"./node_modules/core-js/internals/an-object.js\");\nvar requireObjectCoercible = __webpack_require__(/*! ../internals/require-object-coercible */ \"./node_modules/core-js/internals/require-object-coercible.js\");\nvar speciesConstructor = __webpack_require__(/*! ../internals/species-constructor */ \"./node_modules/core-js/internals/species-constructor.js\");\nvar advanceStringIndex = __webpack_require__(/*! ../internals/advance-string-index */ \"./node_modules/core-js/internals/advance-string-index.js\");\nvar toLength = __webpack_require__(/*! ../internals/to-length */ \"./node_modules/core-js/internals/to-length.js\");\nvar callRegExpExec = __webpack_require__(/*! ../internals/regexp-exec-abstract */ \"./node_modules/core-js/internals/regexp-exec-abstract.js\");\nvar regexpExec = __webpack_require__(/*! ../internals/regexp-exec */ \"./node_modules/core-js/internals/regexp-exec.js\");\nvar fails = __webpack_require__(/*! ../internals/fails */ \"./node_modules/core-js/internals/fails.js\");\n\nvar arrayPush = [].push;\nvar min = Math.min;\nvar MAX_UINT32 = 0xFFFFFFFF;\n\n// babel-minify transpiles RegExp('x', 'y') -> /x/y and it causes SyntaxError\nvar SUPPORTS_Y = !fails(function () { return !RegExp(MAX_UINT32, 'y'); });\n\n// @@split logic\nfixRegExpWellKnownSymbolLogic('split', 2, function (SPLIT, nativeSplit, maybeCallNative) {\n var internalSplit;\n if (\n 'abbc'.split(/(b)*/)[1] == 'c' ||\n 'test'.split(/(?:)/, -1).length != 4 ||\n 'ab'.split(/(?:ab)*/).length != 2 ||\n '.'.split(/(.?)(.?)/).length != 4 ||\n '.'.split(/()()/).length > 1 ||\n ''.split(/.?/).length\n ) {\n // based on es5-shim implementation, need to rework it\n internalSplit = function (separator, limit) {\n var string = String(requireObjectCoercible(this));\n var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;\n if (lim === 0) return [];\n if (separator === undefined) return [string];\n // If `separator` is not a regex, use native split\n if (!isRegExp(separator)) {\n return nativeSplit.call(string, separator, lim);\n }\n var output = [];\n var flags = (separator.ignoreCase ? 'i' : '') +\n (separator.multiline ? 'm' : '') +\n (separator.unicode ? 'u' : '') +\n (separator.sticky ? 'y' : '');\n var lastLastIndex = 0;\n // Make `global` and avoid `lastIndex` issues by working with a copy\n var separatorCopy = new RegExp(separator.source, flags + 'g');\n var match, lastIndex, lastLength;\n while (match = regexpExec.call(separatorCopy, string)) {\n lastIndex = separatorCopy.lastIndex;\n if (lastIndex > lastLastIndex) {\n output.push(string.slice(lastLastIndex, match.index));\n if (match.length > 1 && match.index < string.length) arrayPush.apply(output, match.slice(1));\n lastLength = match[0].length;\n lastLastIndex = lastIndex;\n if (output.length >= lim) break;\n }\n if (separatorCopy.lastIndex === match.index) separatorCopy.lastIndex++; // Avoid an infinite loop\n }\n if (lastLastIndex === string.length) {\n if (lastLength || !separatorCopy.test('')) output.push('');\n } else output.push(string.slice(lastLastIndex));\n return output.length > lim ? output.slice(0, lim) : output;\n };\n // Chakra, V8\n } else if ('0'.split(undefined, 0).length) {\n internalSplit = function (separator, limit) {\n return separator === undefined && limit === 0 ? [] : nativeSplit.call(this, separator, limit);\n };\n } else internalSplit = nativeSplit;\n\n return [\n // `String.prototype.split` method\n // https://tc39.github.io/ecma262/#sec-string.prototype.split\n function split(separator, limit) {\n var O = requireObjectCoercible(this);\n var splitter = separator == undefined ? undefined : separator[SPLIT];\n return splitter !== undefined\n ? splitter.call(separator, O, limit)\n : internalSplit.call(String(O), separator, limit);\n },\n // `RegExp.prototype[@@split]` method\n // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@split\n //\n // NOTE: This cannot be properly polyfilled in engines that don't support\n // the 'y' flag.\n function (regexp, limit) {\n var res = maybeCallNative(internalSplit, regexp, this, limit, internalSplit !== nativeSplit);\n if (res.done) return res.value;\n\n var rx = anObject(regexp);\n var S = String(this);\n var C = speciesConstructor(rx, RegExp);\n\n var unicodeMatching = rx.unicode;\n var flags = (rx.ignoreCase ? 'i' : '') +\n (rx.multiline ? 'm' : '') +\n (rx.unicode ? 'u' : '') +\n (SUPPORTS_Y ? 'y' : 'g');\n\n // ^(? + rx + ) is needed, in combination with some S slicing, to\n // simulate the 'y' flag.\n var splitter = new C(SUPPORTS_Y ? rx : '^(?:' + rx.source + ')', flags);\n var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;\n if (lim === 0) return [];\n if (S.length === 0) return callRegExpExec(splitter, S) === null ? [S] : [];\n var p = 0;\n var q = 0;\n var A = [];\n while (q < S.length) {\n splitter.lastIndex = SUPPORTS_Y ? q : 0;\n var z = callRegExpExec(splitter, SUPPORTS_Y ? S : S.slice(q));\n var e;\n if (\n z === null ||\n (e = min(toLength(splitter.lastIndex + (SUPPORTS_Y ? 0 : q)), S.length)) === p\n ) {\n q = advanceStringIndex(S, q, unicodeMatching);\n } else {\n A.push(S.slice(p, q));\n if (A.length === lim) return A;\n for (var i = 1; i <= z.length - 1; i++) {\n A.push(z[i]);\n if (A.length === lim) return A;\n }\n q = p = e;\n }\n }\n A.push(S.slice(p));\n return A;\n }\n ];\n}, !SUPPORTS_Y);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5zcGxpdC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lcy5zdHJpbmcuc3BsaXQuanM/MTI3NiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG52YXIgZml4UmVnRXhwV2VsbEtub3duU3ltYm9sTG9naWMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZml4LXJlZ2V4cC13ZWxsLWtub3duLXN5bWJvbC1sb2dpYycpO1xudmFyIGlzUmVnRXhwID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2lzLXJlZ2V4cCcpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2FuLW9iamVjdCcpO1xudmFyIHJlcXVpcmVPYmplY3RDb2VyY2libGUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvcmVxdWlyZS1vYmplY3QtY29lcmNpYmxlJyk7XG52YXIgc3BlY2llc0NvbnN0cnVjdG9yID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3NwZWNpZXMtY29uc3RydWN0b3InKTtcbnZhciBhZHZhbmNlU3RyaW5nSW5kZXggPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvYWR2YW5jZS1zdHJpbmctaW5kZXgnKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy90by1sZW5ndGgnKTtcbnZhciBjYWxsUmVnRXhwRXhlYyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9yZWdleHAtZXhlYy1hYnN0cmFjdCcpO1xudmFyIHJlZ2V4cEV4ZWMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvcmVnZXhwLWV4ZWMnKTtcbnZhciBmYWlscyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9mYWlscycpO1xuXG52YXIgYXJyYXlQdXNoID0gW10ucHVzaDtcbnZhciBtaW4gPSBNYXRoLm1pbjtcbnZhciBNQVhfVUlOVDMyID0gMHhGRkZGRkZGRjtcblxuLy8gYmFiZWwtbWluaWZ5IHRyYW5zcGlsZXMgUmVnRXhwKCd4JywgJ3knKSAtPiAveC95IGFuZCBpdCBjYXVzZXMgU3ludGF4RXJyb3JcbnZhciBTVVBQT1JUU19ZID0gIWZhaWxzKGZ1bmN0aW9uICgpIHsgcmV0dXJuICFSZWdFeHAoTUFYX1VJTlQzMiwgJ3knKTsgfSk7XG5cbi8vIEBAc3BsaXQgbG9naWNcbmZpeFJlZ0V4cFdlbGxLbm93blN5bWJvbExvZ2ljKCdzcGxpdCcsIDIsIGZ1bmN0aW9uIChTUExJVCwgbmF0aXZlU3BsaXQsIG1heWJlQ2FsbE5hdGl2ZSkge1xuICB2YXIgaW50ZXJuYWxTcGxpdDtcbiAgaWYgKFxuICAgICdhYmJjJy5zcGxpdCgvKGIpKi8pWzFdID09ICdjJyB8fFxuICAgICd0ZXN0Jy5zcGxpdCgvKD86KS8sIC0xKS5sZW5ndGggIT0gNCB8fFxuICAgICdhYicuc3BsaXQoLyg/OmFiKSovKS5sZW5ndGggIT0gMiB8fFxuICAgICcuJy5zcGxpdCgvKC4/KSguPykvKS5sZW5ndGggIT0gNCB8fFxuICAgICcuJy5zcGxpdCgvKCkoKS8pLmxlbmd0aCA+IDEgfHxcbiAgICAnJy5zcGxpdCgvLj8vKS5sZW5ndGhcbiAgKSB7XG4gICAgLy8gYmFzZWQgb24gZXM1LXNoaW0gaW1wbGVtZW50YXRpb24sIG5lZWQgdG8gcmV3b3JrIGl0XG4gICAgaW50ZXJuYWxTcGxpdCA9IGZ1bmN0aW9uIChzZXBhcmF0b3IsIGxpbWl0KSB7XG4gICAgICB2YXIgc3RyaW5nID0gU3RyaW5nKHJlcXVpcmVPYmplY3RDb2VyY2libGUodGhpcykpO1xuICAgICAgdmFyIGxpbSA9IGxpbWl0ID09PSB1bmRlZmluZWQgPyBNQVhfVUlOVDMyIDogbGltaXQgPj4+IDA7XG4gICAgICBpZiAobGltID09PSAwKSByZXR1cm4gW107XG4gICAgICBpZiAoc2VwYXJhdG9yID09PSB1bmRlZmluZWQpIHJldHVybiBbc3RyaW5nXTtcbiAgICAgIC8vIElmIGBzZXBhcmF0b3JgIGlzIG5vdCBhIHJlZ2V4LCB1c2UgbmF0aXZlIHNwbGl0XG4gICAgICBpZiAoIWlzUmVnRXhwKHNlcGFyYXRvcikpIHtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZVNwbGl0LmNhbGwoc3RyaW5nLCBzZXBhcmF0b3IsIGxpbSk7XG4gICAgICB9XG4gICAgICB2YXIgb3V0cHV0ID0gW107XG4gICAgICB2YXIgZmxhZ3MgPSAoc2VwYXJhdG9yLmlnbm9yZUNhc2UgPyAnaScgOiAnJykgK1xuICAgICAgICAgICAgICAgICAgKHNlcGFyYXRvci5tdWx0aWxpbmUgPyAnbScgOiAnJykgK1xuICAgICAgICAgICAgICAgICAgKHNlcGFyYXRvci51bmljb2RlID8gJ3UnIDogJycpICtcbiAgICAgICAgICAgICAgICAgIChzZXBhcmF0b3Iuc3RpY2t5ID8gJ3knIDogJycpO1xuICAgICAgdmFyIGxhc3RMYXN0SW5kZXggPSAwO1xuICAgICAgLy8gTWFrZSBgZ2xvYmFsYCBhbmQgYXZvaWQgYGxhc3RJbmRleGAgaXNzdWVzIGJ5IHdvcmtpbmcgd2l0aCBhIGNvcHlcbiAgICAgIHZhciBzZXBhcmF0b3JDb3B5ID0gbmV3IFJlZ0V4cChzZXBhcmF0b3Iuc291cmNlLCBmbGFncyArICdnJyk7XG4gICAgICB2YXIgbWF0Y2gsIGxhc3RJbmRleCwgbGFzdExlbmd0aDtcbiAgICAgIHdoaWxlIChtYXRjaCA9IHJlZ2V4cEV4ZWMuY2FsbChzZXBhcmF0b3JDb3B5LCBzdHJpbmcpKSB7XG4gICAgICAgIGxhc3RJbmRleCA9IHNlcGFyYXRvckNvcHkubGFzdEluZGV4O1xuICAgICAgICBpZiAobGFzdEluZGV4ID4gbGFzdExhc3RJbmRleCkge1xuICAgICAgICAgIG91dHB1dC5wdXNoKHN0cmluZy5zbGljZShsYXN0TGFzdEluZGV4LCBtYXRjaC5pbmRleCkpO1xuICAgICAgICAgIGlmIChtYXRjaC5sZW5ndGggPiAxICYmIG1hdGNoLmluZGV4IDwgc3RyaW5nLmxlbmd0aCkgYXJyYXlQdXNoLmFwcGx5KG91dHB1dCwgbWF0Y2guc2xpY2UoMSkpO1xuICAgICAgICAgIGxhc3RMZW5ndGggPSBtYXRjaFswXS5sZW5ndGg7XG4gICAgICAgICAgbGFzdExhc3RJbmRleCA9IGxhc3RJbmRleDtcbiAgICAgICAgICBpZiAob3V0cHV0Lmxlbmd0aCA+PSBsaW0pIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzZXBhcmF0b3JDb3B5Lmxhc3RJbmRleCA9PT0gbWF0Y2guaW5kZXgpIHNlcGFyYXRvckNvcHkubGFzdEluZGV4Kys7IC8vIEF2b2lkIGFuIGluZmluaXRlIGxvb3BcbiAgICAgIH1cbiAgICAgIGlmIChsYXN0TGFzdEluZGV4ID09PSBzdHJpbmcubGVuZ3RoKSB7XG4gICAgICAgIGlmIChsYXN0TGVuZ3RoIHx8ICFzZXBhcmF0b3JDb3B5LnRlc3QoJycpKSBvdXRwdXQucHVzaCgnJyk7XG4gICAgICB9IGVsc2Ugb3V0cHV0LnB1c2goc3RyaW5nLnNsaWNlKGxhc3RMYXN0SW5kZXgpKTtcbiAgICAgIHJldHVybiBvdXRwdXQubGVuZ3RoID4gbGltID8gb3V0cHV0LnNsaWNlKDAsIGxpbSkgOiBvdXRwdXQ7XG4gICAgfTtcbiAgLy8gQ2hha3JhLCBWOFxuICB9IGVsc2UgaWYgKCcwJy5zcGxpdCh1bmRlZmluZWQsIDApLmxlbmd0aCkge1xuICAgIGludGVybmFsU3BsaXQgPSBmdW5jdGlvbiAoc2VwYXJhdG9yLCBsaW1pdCkge1xuICAgICAgcmV0dXJuIHNlcGFyYXRvciA9PT0gdW5kZWZpbmVkICYmIGxpbWl0ID09PSAwID8gW10gOiBuYXRpdmVTcGxpdC5jYWxsKHRoaXMsIHNlcGFyYXRvciwgbGltaXQpO1xuICAgIH07XG4gIH0gZWxzZSBpbnRlcm5hbFNwbGl0ID0gbmF0aXZlU3BsaXQ7XG5cbiAgcmV0dXJuIFtcbiAgICAvLyBgU3RyaW5nLnByb3RvdHlwZS5zcGxpdGAgbWV0aG9kXG4gICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtc3RyaW5nLnByb3RvdHlwZS5zcGxpdFxuICAgIGZ1bmN0aW9uIHNwbGl0KHNlcGFyYXRvciwgbGltaXQpIHtcbiAgICAgIHZhciBPID0gcmVxdWlyZU9iamVjdENvZXJjaWJsZSh0aGlzKTtcbiAgICAgIHZhciBzcGxpdHRlciA9IHNlcGFyYXRvciA9PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBzZXBhcmF0b3JbU1BMSVRdO1xuICAgICAgcmV0dXJuIHNwbGl0dGVyICE9PSB1bmRlZmluZWRcbiAgICAgICAgPyBzcGxpdHRlci5jYWxsKHNlcGFyYXRvciwgTywgbGltaXQpXG4gICAgICAgIDogaW50ZXJuYWxTcGxpdC5jYWxsKFN0cmluZyhPKSwgc2VwYXJhdG9yLCBsaW1pdCk7XG4gICAgfSxcbiAgICAvLyBgUmVnRXhwLnByb3RvdHlwZVtAQHNwbGl0XWAgbWV0aG9kXG4gICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtcmVnZXhwLnByb3RvdHlwZS1AQHNwbGl0XG4gICAgLy9cbiAgICAvLyBOT1RFOiBUaGlzIGNhbm5vdCBiZSBwcm9wZXJseSBwb2x5ZmlsbGVkIGluIGVuZ2luZXMgdGhhdCBkb24ndCBzdXBwb3J0XG4gICAgLy8gdGhlICd5JyBmbGFnLlxuICAgIGZ1bmN0aW9uIChyZWdleHAsIGxpbWl0KSB7XG4gICAgICB2YXIgcmVzID0gbWF5YmVDYWxsTmF0aXZlKGludGVybmFsU3BsaXQsIHJlZ2V4cCwgdGhpcywgbGltaXQsIGludGVybmFsU3BsaXQgIT09IG5hdGl2ZVNwbGl0KTtcbiAgICAgIGlmIChyZXMuZG9uZSkgcmV0dXJuIHJlcy52YWx1ZTtcblxuICAgICAgdmFyIHJ4ID0gYW5PYmplY3QocmVnZXhwKTtcbiAgICAgIHZhciBTID0gU3RyaW5nKHRoaXMpO1xuICAgICAgdmFyIEMgPSBzcGVjaWVzQ29uc3RydWN0b3IocngsIFJlZ0V4cCk7XG5cbiAgICAgIHZhciB1bmljb2RlTWF0Y2hpbmcgPSByeC51bmljb2RlO1xuICAgICAgdmFyIGZsYWdzID0gKHJ4Lmlnbm9yZUNhc2UgPyAnaScgOiAnJykgK1xuICAgICAgICAgICAgICAgICAgKHJ4Lm11bHRpbGluZSA/ICdtJyA6ICcnKSArXG4gICAgICAgICAgICAgICAgICAocngudW5pY29kZSA/ICd1JyA6ICcnKSArXG4gICAgICAgICAgICAgICAgICAoU1VQUE9SVFNfWSA/ICd5JyA6ICdnJyk7XG5cbiAgICAgIC8vIF4oPyArIHJ4ICsgKSBpcyBuZWVkZWQsIGluIGNvbWJpbmF0aW9uIHdpdGggc29tZSBTIHNsaWNpbmcsIHRvXG4gICAgICAvLyBzaW11bGF0ZSB0aGUgJ3knIGZsYWcuXG4gICAgICB2YXIgc3BsaXR0ZXIgPSBuZXcgQyhTVVBQT1JUU19ZID8gcnggOiAnXig/OicgKyByeC5zb3VyY2UgKyAnKScsIGZsYWdzKTtcbiAgICAgIHZhciBsaW0gPSBsaW1pdCA9PT0gdW5kZWZpbmVkID8gTUFYX1VJTlQzMiA6IGxpbWl0ID4+PiAwO1xuICAgICAgaWYgKGxpbSA9PT0gMCkgcmV0dXJuIFtdO1xuICAgICAgaWYgKFMubGVuZ3RoID09PSAwKSByZXR1cm4gY2FsbFJlZ0V4cEV4ZWMoc3BsaXR0ZXIsIFMpID09PSBudWxsID8gW1NdIDogW107XG4gICAgICB2YXIgcCA9IDA7XG4gICAgICB2YXIgcSA9IDA7XG4gICAgICB2YXIgQSA9IFtdO1xuICAgICAgd2hpbGUgKHEgPCBTLmxlbmd0aCkge1xuICAgICAgICBzcGxpdHRlci5sYXN0SW5kZXggPSBTVVBQT1JUU19ZID8gcSA6IDA7XG4gICAgICAgIHZhciB6ID0gY2FsbFJlZ0V4cEV4ZWMoc3BsaXR0ZXIsIFNVUFBPUlRTX1kgPyBTIDogUy5zbGljZShxKSk7XG4gICAgICAgIHZhciBlO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgeiA9PT0gbnVsbCB8fFxuICAgICAgICAgIChlID0gbWluKHRvTGVuZ3RoKHNwbGl0dGVyLmxhc3RJbmRleCArIChTVVBQT1JUU19ZID8gMCA6IHEpKSwgUy5sZW5ndGgpKSA9PT0gcFxuICAgICAgICApIHtcbiAgICAgICAgICBxID0gYWR2YW5jZVN0cmluZ0luZGV4KFMsIHEsIHVuaWNvZGVNYXRjaGluZyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgQS5wdXNoKFMuc2xpY2UocCwgcSkpO1xuICAgICAgICAgIGlmIChBLmxlbmd0aCA9PT0gbGltKSByZXR1cm4gQTtcbiAgICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8PSB6Lmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICAgICAgQS5wdXNoKHpbaV0pO1xuICAgICAgICAgICAgaWYgKEEubGVuZ3RoID09PSBsaW0pIHJldHVybiBBO1xuICAgICAgICAgIH1cbiAgICAgICAgICBxID0gcCA9IGU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIEEucHVzaChTLnNsaWNlKHApKTtcbiAgICAgIHJldHVybiBBO1xuICAgIH1cbiAgXTtcbn0sICFTVVBQT1JUU19ZKTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.split.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.starts-with.js": +/*!***************************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.starts-with.js ***! + \***************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar toLength = __webpack_require__(/*! ../internals/to-length */ \"./node_modules/core-js/internals/to-length.js\");\nvar validateArguments = __webpack_require__(/*! ../internals/validate-string-method-arguments */ \"./node_modules/core-js/internals/validate-string-method-arguments.js\");\nvar correctIsRegExpLogic = __webpack_require__(/*! ../internals/correct-is-regexp-logic */ \"./node_modules/core-js/internals/correct-is-regexp-logic.js\");\n\nvar STARTS_WITH = 'startsWith';\nvar nativeStartsWith = ''[STARTS_WITH];\n\n// `String.prototype.startsWith` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.startswith\n$({ target: 'String', proto: true, forced: !correctIsRegExpLogic(STARTS_WITH) }, {\n startsWith: function startsWith(searchString /* , position = 0 */) {\n var that = validateArguments(this, searchString, STARTS_WITH);\n var index = toLength(Math.min(arguments.length > 1 ? arguments[1] : undefined, that.length));\n var search = String(searchString);\n return nativeStartsWith\n ? nativeStartsWith.call(that, search, index)\n : that.slice(index, index + search.length) === search;\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5zdGFydHMtd2l0aC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lcy5zdHJpbmcuc3RhcnRzLXdpdGguanM/MmNhMCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG52YXIgJCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9leHBvcnQnKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy90by1sZW5ndGgnKTtcbnZhciB2YWxpZGF0ZUFyZ3VtZW50cyA9IHJlcXVpcmUoJy4uL2ludGVybmFscy92YWxpZGF0ZS1zdHJpbmctbWV0aG9kLWFyZ3VtZW50cycpO1xudmFyIGNvcnJlY3RJc1JlZ0V4cExvZ2ljID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2NvcnJlY3QtaXMtcmVnZXhwLWxvZ2ljJyk7XG5cbnZhciBTVEFSVFNfV0lUSCA9ICdzdGFydHNXaXRoJztcbnZhciBuYXRpdmVTdGFydHNXaXRoID0gJydbU1RBUlRTX1dJVEhdO1xuXG4vLyBgU3RyaW5nLnByb3RvdHlwZS5zdGFydHNXaXRoYCBtZXRob2Rcbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXN0cmluZy5wcm90b3R5cGUuc3RhcnRzd2l0aFxuJCh7IHRhcmdldDogJ1N0cmluZycsIHByb3RvOiB0cnVlLCBmb3JjZWQ6ICFjb3JyZWN0SXNSZWdFeHBMb2dpYyhTVEFSVFNfV0lUSCkgfSwge1xuICBzdGFydHNXaXRoOiBmdW5jdGlvbiBzdGFydHNXaXRoKHNlYXJjaFN0cmluZyAvKiAsIHBvc2l0aW9uID0gMCAqLykge1xuICAgIHZhciB0aGF0ID0gdmFsaWRhdGVBcmd1bWVudHModGhpcywgc2VhcmNoU3RyaW5nLCBTVEFSVFNfV0lUSCk7XG4gICAgdmFyIGluZGV4ID0gdG9MZW5ndGgoTWF0aC5taW4oYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQsIHRoYXQubGVuZ3RoKSk7XG4gICAgdmFyIHNlYXJjaCA9IFN0cmluZyhzZWFyY2hTdHJpbmcpO1xuICAgIHJldHVybiBuYXRpdmVTdGFydHNXaXRoXG4gICAgICA/IG5hdGl2ZVN0YXJ0c1dpdGguY2FsbCh0aGF0LCBzZWFyY2gsIGluZGV4KVxuICAgICAgOiB0aGF0LnNsaWNlKGluZGV4LCBpbmRleCArIHNlYXJjaC5sZW5ndGgpID09PSBzZWFyY2g7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.starts-with.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.strike.js": +/*!**********************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.strike.js ***! + \**********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar createHTML = __webpack_require__(/*! ../internals/create-html */ \"./node_modules/core-js/internals/create-html.js\");\nvar forcedStringHTMLMethod = __webpack_require__(/*! ../internals/forced-string-html-method */ \"./node_modules/core-js/internals/forced-string-html-method.js\");\n\n// `String.prototype.strike` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.strike\n$({ target: 'String', proto: true, forced: forcedStringHTMLMethod('strike') }, {\n strike: function strike() {\n return createHTML(this, 'strike', '', '');\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5zdHJpa2UuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXMuc3RyaW5nLnN0cmlrZS5qcz8yMzE1Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcbnZhciAkID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2V4cG9ydCcpO1xudmFyIGNyZWF0ZUhUTUwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvY3JlYXRlLWh0bWwnKTtcbnZhciBmb3JjZWRTdHJpbmdIVE1MTWV0aG9kID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2ZvcmNlZC1zdHJpbmctaHRtbC1tZXRob2QnKTtcblxuLy8gYFN0cmluZy5wcm90b3R5cGUuc3RyaWtlYCBtZXRob2Rcbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXN0cmluZy5wcm90b3R5cGUuc3RyaWtlXG4kKHsgdGFyZ2V0OiAnU3RyaW5nJywgcHJvdG86IHRydWUsIGZvcmNlZDogZm9yY2VkU3RyaW5nSFRNTE1ldGhvZCgnc3RyaWtlJykgfSwge1xuICBzdHJpa2U6IGZ1bmN0aW9uIHN0cmlrZSgpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnc3RyaWtlJywgJycsICcnKTtcbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.strike.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.sub.js": +/*!*******************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.sub.js ***! + \*******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar createHTML = __webpack_require__(/*! ../internals/create-html */ \"./node_modules/core-js/internals/create-html.js\");\nvar forcedStringHTMLMethod = __webpack_require__(/*! ../internals/forced-string-html-method */ \"./node_modules/core-js/internals/forced-string-html-method.js\");\n\n// `String.prototype.sub` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.sub\n$({ target: 'String', proto: true, forced: forcedStringHTMLMethod('sub') }, {\n sub: function sub() {\n return createHTML(this, 'sub', '', '');\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5zdWIuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXMuc3RyaW5nLnN1Yi5qcz80YzUzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcbnZhciAkID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2V4cG9ydCcpO1xudmFyIGNyZWF0ZUhUTUwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvY3JlYXRlLWh0bWwnKTtcbnZhciBmb3JjZWRTdHJpbmdIVE1MTWV0aG9kID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2ZvcmNlZC1zdHJpbmctaHRtbC1tZXRob2QnKTtcblxuLy8gYFN0cmluZy5wcm90b3R5cGUuc3ViYCBtZXRob2Rcbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXN0cmluZy5wcm90b3R5cGUuc3ViXG4kKHsgdGFyZ2V0OiAnU3RyaW5nJywgcHJvdG86IHRydWUsIGZvcmNlZDogZm9yY2VkU3RyaW5nSFRNTE1ldGhvZCgnc3ViJykgfSwge1xuICBzdWI6IGZ1bmN0aW9uIHN1YigpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnc3ViJywgJycsICcnKTtcbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.sub.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.sup.js": +/*!*******************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.sup.js ***! + \*******************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar createHTML = __webpack_require__(/*! ../internals/create-html */ \"./node_modules/core-js/internals/create-html.js\");\nvar forcedStringHTMLMethod = __webpack_require__(/*! ../internals/forced-string-html-method */ \"./node_modules/core-js/internals/forced-string-html-method.js\");\n\n// `String.prototype.sup` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.sup\n$({ target: 'String', proto: true, forced: forcedStringHTMLMethod('sup') }, {\n sup: function sup() {\n return createHTML(this, 'sup', '', '');\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5zdXAuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXMuc3RyaW5nLnN1cC5qcz82NjRmIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcbnZhciAkID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2V4cG9ydCcpO1xudmFyIGNyZWF0ZUhUTUwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvY3JlYXRlLWh0bWwnKTtcbnZhciBmb3JjZWRTdHJpbmdIVE1MTWV0aG9kID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2ZvcmNlZC1zdHJpbmctaHRtbC1tZXRob2QnKTtcblxuLy8gYFN0cmluZy5wcm90b3R5cGUuc3VwYCBtZXRob2Rcbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXN0cmluZy5wcm90b3R5cGUuc3VwXG4kKHsgdGFyZ2V0OiAnU3RyaW5nJywgcHJvdG86IHRydWUsIGZvcmNlZDogZm9yY2VkU3RyaW5nSFRNTE1ldGhvZCgnc3VwJykgfSwge1xuICBzdXA6IGZ1bmN0aW9uIHN1cCgpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnc3VwJywgJycsICcnKTtcbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.sup.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.trim-end.js": +/*!************************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.trim-end.js ***! + \************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar internalStringTrim = __webpack_require__(/*! ../internals/string-trim */ \"./node_modules/core-js/internals/string-trim.js\");\nvar forcedStringTrimMethod = __webpack_require__(/*! ../internals/forced-string-trim-method */ \"./node_modules/core-js/internals/forced-string-trim-method.js\");\n\nvar FORCED = forcedStringTrimMethod('trimEnd');\n\nvar trimEnd = FORCED ? function trimEnd() {\n return internalStringTrim(this, 2);\n} : ''.trimEnd;\n\n// `String.prototype.{ trimEnd, trimRight }` methods\n// https://github.com/tc39/ecmascript-string-left-right-trim\n$({ target: 'String', proto: true, forced: FORCED }, {\n trimEnd: trimEnd,\n trimRight: trimEnd\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy50cmltLWVuZC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lcy5zdHJpbmcudHJpbS1lbmQuanM/MWUyNSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG52YXIgJCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9leHBvcnQnKTtcbnZhciBpbnRlcm5hbFN0cmluZ1RyaW0gPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvc3RyaW5nLXRyaW0nKTtcbnZhciBmb3JjZWRTdHJpbmdUcmltTWV0aG9kID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2ZvcmNlZC1zdHJpbmctdHJpbS1tZXRob2QnKTtcblxudmFyIEZPUkNFRCA9IGZvcmNlZFN0cmluZ1RyaW1NZXRob2QoJ3RyaW1FbmQnKTtcblxudmFyIHRyaW1FbmQgPSBGT1JDRUQgPyBmdW5jdGlvbiB0cmltRW5kKCkge1xuICByZXR1cm4gaW50ZXJuYWxTdHJpbmdUcmltKHRoaXMsIDIpO1xufSA6ICcnLnRyaW1FbmQ7XG5cbi8vIGBTdHJpbmcucHJvdG90eXBlLnsgdHJpbUVuZCwgdHJpbVJpZ2h0IH1gIG1ldGhvZHNcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS90YzM5L2VjbWFzY3JpcHQtc3RyaW5nLWxlZnQtcmlnaHQtdHJpbVxuJCh7IHRhcmdldDogJ1N0cmluZycsIHByb3RvOiB0cnVlLCBmb3JjZWQ6IEZPUkNFRCB9LCB7XG4gIHRyaW1FbmQ6IHRyaW1FbmQsXG4gIHRyaW1SaWdodDogdHJpbUVuZFxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.trim-end.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.trim-start.js": +/*!**************************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.trim-start.js ***! + \**************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar internalStringTrim = __webpack_require__(/*! ../internals/string-trim */ \"./node_modules/core-js/internals/string-trim.js\");\nvar forcedStringTrimMethod = __webpack_require__(/*! ../internals/forced-string-trim-method */ \"./node_modules/core-js/internals/forced-string-trim-method.js\");\n\nvar FORCED = forcedStringTrimMethod('trimStart');\n\nvar trimStart = FORCED ? function trimStart() {\n return internalStringTrim(this, 1);\n} : ''.trimStart;\n\n// `String.prototype.{ trimStart, trimLeft }` methods\n// https://github.com/tc39/ecmascript-string-left-right-trim\n$({ target: 'String', proto: true, forced: FORCED }, {\n trimStart: trimStart,\n trimLeft: trimStart\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy50cmltLXN0YXJ0LmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy50cmltLXN0YXJ0LmpzP2VlZTciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xudmFyICQgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZXhwb3J0Jyk7XG52YXIgaW50ZXJuYWxTdHJpbmdUcmltID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3N0cmluZy10cmltJyk7XG52YXIgZm9yY2VkU3RyaW5nVHJpbU1ldGhvZCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9mb3JjZWQtc3RyaW5nLXRyaW0tbWV0aG9kJyk7XG5cbnZhciBGT1JDRUQgPSBmb3JjZWRTdHJpbmdUcmltTWV0aG9kKCd0cmltU3RhcnQnKTtcblxudmFyIHRyaW1TdGFydCA9IEZPUkNFRCA/IGZ1bmN0aW9uIHRyaW1TdGFydCgpIHtcbiAgcmV0dXJuIGludGVybmFsU3RyaW5nVHJpbSh0aGlzLCAxKTtcbn0gOiAnJy50cmltU3RhcnQ7XG5cbi8vIGBTdHJpbmcucHJvdG90eXBlLnsgdHJpbVN0YXJ0LCB0cmltTGVmdCB9YCBtZXRob2RzXG4vLyBodHRwczovL2dpdGh1Yi5jb20vdGMzOS9lY21hc2NyaXB0LXN0cmluZy1sZWZ0LXJpZ2h0LXRyaW1cbiQoeyB0YXJnZXQ6ICdTdHJpbmcnLCBwcm90bzogdHJ1ZSwgZm9yY2VkOiBGT1JDRUQgfSwge1xuICB0cmltU3RhcnQ6IHRyaW1TdGFydCxcbiAgdHJpbUxlZnQ6IHRyaW1TdGFydFxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.trim-start.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/es.string.trim.js": +/*!********************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.trim.js ***! + \********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\nvar $ = __webpack_require__(/*! ../internals/export */ \"./node_modules/core-js/internals/export.js\");\nvar internalStringTrim = __webpack_require__(/*! ../internals/string-trim */ \"./node_modules/core-js/internals/string-trim.js\");\nvar forcedStringTrimMethod = __webpack_require__(/*! ../internals/forced-string-trim-method */ \"./node_modules/core-js/internals/forced-string-trim-method.js\");\n\nvar FORCED = forcedStringTrimMethod('trim');\n\n// `String.prototype.trim` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.trim\n$({ target: 'String', proto: true, forced: FORCED }, {\n trim: function trim() {\n return internalStringTrim(this, 3);\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy50cmltLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy50cmltLmpzPzQ5OGEiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xudmFyICQgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZXhwb3J0Jyk7XG52YXIgaW50ZXJuYWxTdHJpbmdUcmltID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3N0cmluZy10cmltJyk7XG52YXIgZm9yY2VkU3RyaW5nVHJpbU1ldGhvZCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9mb3JjZWQtc3RyaW5nLXRyaW0tbWV0aG9kJyk7XG5cbnZhciBGT1JDRUQgPSBmb3JjZWRTdHJpbmdUcmltTWV0aG9kKCd0cmltJyk7XG5cbi8vIGBTdHJpbmcucHJvdG90eXBlLnRyaW1gIG1ldGhvZFxuLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtc3RyaW5nLnByb3RvdHlwZS50cmltXG4kKHsgdGFyZ2V0OiAnU3RyaW5nJywgcHJvdG86IHRydWUsIGZvcmNlZDogRk9SQ0VEIH0sIHtcbiAgdHJpbTogZnVuY3Rpb24gdHJpbSgpIHtcbiAgICByZXR1cm4gaW50ZXJuYWxTdHJpbmdUcmltKHRoaXMsIDMpO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/es.string.trim.js\n"); + +/***/ }), + +/***/ "./node_modules/core-js/modules/web.dom-collections.iterator.js": +/*!**********************************************************************!*\ + !*** ./node_modules/core-js/modules/web.dom-collections.iterator.js ***! + \**********************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var global = __webpack_require__(/*! ../internals/global */ \"./node_modules/core-js/internals/global.js\");\nvar DOMIterables = __webpack_require__(/*! ../internals/dom-iterables */ \"./node_modules/core-js/internals/dom-iterables.js\");\nvar ArrayIteratorMethods = __webpack_require__(/*! ../modules/es.array.iterator */ \"./node_modules/core-js/modules/es.array.iterator.js\");\nvar hide = __webpack_require__(/*! ../internals/hide */ \"./node_modules/core-js/internals/hide.js\");\nvar wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ \"./node_modules/core-js/internals/well-known-symbol.js\");\n\nvar ITERATOR = wellKnownSymbol('iterator');\nvar TO_STRING_TAG = wellKnownSymbol('toStringTag');\nvar ArrayValues = ArrayIteratorMethods.values;\n\nfor (var COLLECTION_NAME in DOMIterables) {\n var Collection = global[COLLECTION_NAME];\n var CollectionPrototype = Collection && Collection.prototype;\n if (CollectionPrototype) {\n // some Chrome versions have non-configurable methods on DOMTokenList\n if (CollectionPrototype[ITERATOR] !== ArrayValues) try {\n hide(CollectionPrototype, ITERATOR, ArrayValues);\n } catch (error) {\n CollectionPrototype[ITERATOR] = ArrayValues;\n }\n if (!CollectionPrototype[TO_STRING_TAG]) hide(CollectionPrototype, TO_STRING_TAG, COLLECTION_NAME);\n if (DOMIterables[COLLECTION_NAME]) for (var METHOD_NAME in ArrayIteratorMethods) {\n // some Chrome versions have non-configurable methods on DOMTokenList\n if (CollectionPrototype[METHOD_NAME] !== ArrayIteratorMethods[METHOD_NAME]) try {\n hide(CollectionPrototype, METHOD_NAME, ArrayIteratorMethods[METHOD_NAME]);\n } catch (error) {\n CollectionPrototype[METHOD_NAME] = ArrayIteratorMethods[METHOD_NAME];\n }\n }\n }\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL3dlYi5kb20tY29sbGVjdGlvbnMuaXRlcmF0b3IuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9KUy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvd2ViLmRvbS1jb2xsZWN0aW9ucy5pdGVyYXRvci5qcz9kZGIwIl0sInNvdXJjZXNDb250ZW50IjpbInZhciBnbG9iYWwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZ2xvYmFsJyk7XG52YXIgRE9NSXRlcmFibGVzID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2RvbS1pdGVyYWJsZXMnKTtcbnZhciBBcnJheUl0ZXJhdG9yTWV0aG9kcyA9IHJlcXVpcmUoJy4uL21vZHVsZXMvZXMuYXJyYXkuaXRlcmF0b3InKTtcbnZhciBoaWRlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2hpZGUnKTtcbnZhciB3ZWxsS25vd25TeW1ib2wgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvd2VsbC1rbm93bi1zeW1ib2wnKTtcblxudmFyIElURVJBVE9SID0gd2VsbEtub3duU3ltYm9sKCdpdGVyYXRvcicpO1xudmFyIFRPX1NUUklOR19UQUcgPSB3ZWxsS25vd25TeW1ib2woJ3RvU3RyaW5nVGFnJyk7XG52YXIgQXJyYXlWYWx1ZXMgPSBBcnJheUl0ZXJhdG9yTWV0aG9kcy52YWx1ZXM7XG5cbmZvciAodmFyIENPTExFQ1RJT05fTkFNRSBpbiBET01JdGVyYWJsZXMpIHtcbiAgdmFyIENvbGxlY3Rpb24gPSBnbG9iYWxbQ09MTEVDVElPTl9OQU1FXTtcbiAgdmFyIENvbGxlY3Rpb25Qcm90b3R5cGUgPSBDb2xsZWN0aW9uICYmIENvbGxlY3Rpb24ucHJvdG90eXBlO1xuICBpZiAoQ29sbGVjdGlvblByb3RvdHlwZSkge1xuICAgIC8vIHNvbWUgQ2hyb21lIHZlcnNpb25zIGhhdmUgbm9uLWNvbmZpZ3VyYWJsZSBtZXRob2RzIG9uIERPTVRva2VuTGlzdFxuICAgIGlmIChDb2xsZWN0aW9uUHJvdG90eXBlW0lURVJBVE9SXSAhPT0gQXJyYXlWYWx1ZXMpIHRyeSB7XG4gICAgICBoaWRlKENvbGxlY3Rpb25Qcm90b3R5cGUsIElURVJBVE9SLCBBcnJheVZhbHVlcyk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIENvbGxlY3Rpb25Qcm90b3R5cGVbSVRFUkFUT1JdID0gQXJyYXlWYWx1ZXM7XG4gICAgfVxuICAgIGlmICghQ29sbGVjdGlvblByb3RvdHlwZVtUT19TVFJJTkdfVEFHXSkgaGlkZShDb2xsZWN0aW9uUHJvdG90eXBlLCBUT19TVFJJTkdfVEFHLCBDT0xMRUNUSU9OX05BTUUpO1xuICAgIGlmIChET01JdGVyYWJsZXNbQ09MTEVDVElPTl9OQU1FXSkgZm9yICh2YXIgTUVUSE9EX05BTUUgaW4gQXJyYXlJdGVyYXRvck1ldGhvZHMpIHtcbiAgICAgIC8vIHNvbWUgQ2hyb21lIHZlcnNpb25zIGhhdmUgbm9uLWNvbmZpZ3VyYWJsZSBtZXRob2RzIG9uIERPTVRva2VuTGlzdFxuICAgICAgaWYgKENvbGxlY3Rpb25Qcm90b3R5cGVbTUVUSE9EX05BTUVdICE9PSBBcnJheUl0ZXJhdG9yTWV0aG9kc1tNRVRIT0RfTkFNRV0pIHRyeSB7XG4gICAgICAgIGhpZGUoQ29sbGVjdGlvblByb3RvdHlwZSwgTUVUSE9EX05BTUUsIEFycmF5SXRlcmF0b3JNZXRob2RzW01FVEhPRF9OQU1FXSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBDb2xsZWN0aW9uUHJvdG90eXBlW01FVEhPRF9OQU1FXSA9IEFycmF5SXRlcmF0b3JNZXRob2RzW01FVEhPRF9OQU1FXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-js/modules/web.dom-collections.iterator.js\n"); + +/***/ }), + +/***/ "./node_modules/core-util-is/lib/util.js": +/*!***********************************************!*\ + !*** ./node_modules/core-util-is/lib/util.js ***! + \***********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("/* WEBPACK VAR INJECTION */(function(Buffer) {// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\n\nfunction isArray(arg) {\n if (Array.isArray) {\n return Array.isArray(arg);\n }\n return objectToString(arg) === '[object Array]';\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n return objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n return objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n return (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n return arg === null ||\n typeof arg === 'boolean' ||\n typeof arg === 'number' ||\n typeof arg === 'string' ||\n typeof arg === 'symbol' || // ES6 symbol\n typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = Buffer.isBuffer;\n\nfunction objectToString(o) {\n return Object.prototype.toString.call(o);\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../buffer/index.js */ \"./node_modules/buffer/index.js\").Buffer))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29yZS11dGlsLWlzL2xpYi91dGlsLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSlMvLi9ub2RlX21vZHVsZXMvY29yZS11dGlsLWlzL2xpYi91dGlsLmpzPzNhN2MiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIE5PVEU6IFRoZXNlIHR5cGUgY2hlY2tpbmcgZnVuY3Rpb25zIGludGVudGlvbmFsbHkgZG9uJ3QgdXNlIGBpbnN0YW5jZW9mYFxuLy8gYmVjYXVzZSBpdCBpcyBmcmFnaWxlIGFuZCBjYW4gYmUgZWFzaWx5IGZha2VkIHdpdGggYE9iamVjdC5jcmVhdGUoKWAuXG5cbmZ1bmN0aW9uIGlzQXJyYXkoYXJnKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KSB7XG4gICAgcmV0dXJuIEFycmF5LmlzQXJyYXkoYXJnKTtcbiAgfVxuICByZXR1cm4gb2JqZWN0VG9TdHJpbmcoYXJnKSA9PT0gJ1tvYmplY3QgQXJyYXldJztcbn1cbmV4cG9ydHMuaXNBcnJheSA9IGlzQXJyYXk7XG5cbmZ1bmN0aW9uIGlzQm9vbGVhbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJztcbn1cbmV4cG9ydHMuaXNCb29sZWFuID0gaXNCb29sZWFuO1xuXG5mdW5jdGlvbiBpc051bGwoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGw7XG59XG5leHBvcnRzLmlzTnVsbCA9IGlzTnVsbDtcblxuZnVuY3Rpb24gaXNOdWxsT3JVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsT3JVbmRlZmluZWQgPSBpc051bGxPclVuZGVmaW5lZDtcblxuZnVuY3Rpb24gaXNOdW1iZXIoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnbnVtYmVyJztcbn1cbmV4cG9ydHMuaXNOdW1iZXIgPSBpc051bWJlcjtcblxuZnVuY3Rpb24gaXNTdHJpbmcoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3RyaW5nJztcbn1cbmV4cG9ydHMuaXNTdHJpbmcgPSBpc1N0cmluZztcblxuZnVuY3Rpb24gaXNTeW1ib2woYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3ltYm9sJztcbn1cbmV4cG9ydHMuaXNTeW1ib2wgPSBpc1N5bWJvbDtcblxuZnVuY3Rpb24gaXNVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IHZvaWQgMDtcbn1cbmV4cG9ydHMuaXNVbmRlZmluZWQgPSBpc1VuZGVmaW5lZDtcblxuZnVuY3Rpb24gaXNSZWdFeHAocmUpIHtcbiAgcmV0dXJuIG9iamVjdFRvU3RyaW5nKHJlKSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG59XG5leHBvcnRzLmlzUmVnRXhwID0gaXNSZWdFeHA7XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xufVxuZXhwb3J0cy5pc09iamVjdCA9IGlzT2JqZWN0O1xuXG5mdW5jdGlvbiBpc0RhdGUoZCkge1xuICByZXR1cm4gb2JqZWN0VG9TdHJpbmcoZCkgPT09ICdbb2JqZWN0IERhdGVdJztcbn1cbmV4cG9ydHMuaXNEYXRlID0gaXNEYXRlO1xuXG5mdW5jdGlvbiBpc0Vycm9yKGUpIHtcbiAgcmV0dXJuIChvYmplY3RUb1N0cmluZyhlKSA9PT0gJ1tvYmplY3QgRXJyb3JdJyB8fCBlIGluc3RhbmNlb2YgRXJyb3IpO1xufVxuZXhwb3J0cy5pc0Vycm9yID0gaXNFcnJvcjtcblxuZnVuY3Rpb24gaXNGdW5jdGlvbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdmdW5jdGlvbic7XG59XG5leHBvcnRzLmlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uO1xuXG5mdW5jdGlvbiBpc1ByaW1pdGl2ZShhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbCB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnbnVtYmVyJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3N0cmluZycgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnIHx8ICAvLyBFUzYgc3ltYm9sXG4gICAgICAgICB0eXBlb2YgYXJnID09PSAndW5kZWZpbmVkJztcbn1cbmV4cG9ydHMuaXNQcmltaXRpdmUgPSBpc1ByaW1pdGl2ZTtcblxuZXhwb3J0cy5pc0J1ZmZlciA9IEJ1ZmZlci5pc0J1ZmZlcjtcblxuZnVuY3Rpb24gb2JqZWN0VG9TdHJpbmcobykge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pO1xufVxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/core-util-is/lib/util.js\n"); + +/***/ }), + +/***/ "./node_modules/events/events.js": +/*!***************************************!*\ + !*** ./node_modules/events/events.js ***! + \***************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\n\nvar R = typeof Reflect === 'object' ? Reflect : null\nvar ReflectApply = R && typeof R.apply === 'function'\n ? R.apply\n : function ReflectApply(target, receiver, args) {\n return Function.prototype.apply.call(target, receiver, args);\n }\n\nvar ReflectOwnKeys\nif (R && typeof R.ownKeys === 'function') {\n ReflectOwnKeys = R.ownKeys\n} else if (Object.getOwnPropertySymbols) {\n ReflectOwnKeys = function ReflectOwnKeys(target) {\n return Object.getOwnPropertyNames(target)\n .concat(Object.getOwnPropertySymbols(target));\n };\n} else {\n ReflectOwnKeys = function ReflectOwnKeys(target) {\n return Object.getOwnPropertyNames(target);\n };\n}\n\nfunction ProcessEmitWarning(warning) {\n if (console && console.warn) console.warn(warning);\n}\n\nvar NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {\n return value !== value;\n}\n\nfunction EventEmitter() {\n EventEmitter.init.call(this);\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._eventsCount = 0;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nvar defaultMaxListeners = 10;\n\nObject.defineProperty(EventEmitter, 'defaultMaxListeners', {\n enumerable: true,\n get: function() {\n return defaultMaxListeners;\n },\n set: function(arg) {\n if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {\n throw new RangeError('The value of \"defaultMaxListeners\" is out of range. It must be a non-negative number. Received ' + arg + '.');\n }\n defaultMaxListeners = arg;\n }\n});\n\nEventEmitter.init = function() {\n\n if (this._events === undefined ||\n this._events === Object.getPrototypeOf(this)._events) {\n this._events = Object.create(null);\n this._eventsCount = 0;\n }\n\n this._maxListeners = this._maxListeners || undefined;\n};\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {\n if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {\n throw new RangeError('The value of \"n\" is out of range. It must be a non-negative number. Received ' + n + '.');\n }\n this._maxListeners = n;\n return this;\n};\n\nfunction $getMaxListeners(that) {\n if (that._maxListeners === undefined)\n return EventEmitter.defaultMaxListeners;\n return that._maxListeners;\n}\n\nEventEmitter.prototype.getMaxListeners = function getMaxListeners() {\n return $getMaxListeners(this);\n};\n\nEventEmitter.prototype.emit = function emit(type) {\n var args = [];\n for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);\n var doError = (type === 'error');\n\n var events = this._events;\n if (events !== undefined)\n doError = (doError && events.error === undefined);\n else if (!doError)\n return false;\n\n // If there is no 'error' event listener then throw.\n if (doError) {\n var er;\n if (args.length > 0)\n er = args[0];\n if (er instanceof Error) {\n // Note: The comments on the `throw` lines are intentional, they show\n // up in Node's output if this results in an unhandled exception.\n throw er; // Unhandled 'error' event\n }\n // At least give some kind of context to the user\n var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));\n err.context = er;\n throw err; // Unhandled 'error' event\n }\n\n var handler = events[type];\n\n if (handler === undefined)\n return false;\n\n if (typeof handler === 'function') {\n ReflectApply(handler, this, args);\n } else {\n var len = handler.length;\n var listeners = arrayClone(handler, len);\n for (var i = 0; i < len; ++i)\n ReflectApply(listeners[i], this, args);\n }\n\n return true;\n};\n\nfunction _addListener(target, type, listener, prepend) {\n var m;\n var events;\n var existing;\n\n if (typeof listener !== 'function') {\n throw new TypeError('The \"listener\" argument must be of type Function. Received type ' + typeof listener);\n }\n\n events = target._events;\n if (events === undefined) {\n events = target._events = Object.create(null);\n target._eventsCount = 0;\n } else {\n // To avoid recursion in the case that type === \"newListener\"! Before\n // adding it to the listeners, first emit \"newListener\".\n if (events.newListener !== undefined) {\n target.emit('newListener', type,\n listener.listener ? listener.listener : listener);\n\n // Re-assign `events` because a newListener handler could have caused the\n // this._events to be assigned to a new object\n events = target._events;\n }\n existing = events[type];\n }\n\n if (existing === undefined) {\n // Optimize the case of one listener. Don't need the extra array object.\n existing = events[type] = listener;\n ++target._eventsCount;\n } else {\n if (typeof existing === 'function') {\n // Adding the second element, need to change to array.\n existing = events[type] =\n prepend ? [listener, existing] : [existing, listener];\n // If we've already got an array, just append.\n } else if (prepend) {\n existing.unshift(listener);\n } else {\n existing.push(listener);\n }\n\n // Check for listener leak\n m = $getMaxListeners(target);\n if (m > 0 && existing.length > m && !existing.warned) {\n existing.warned = true;\n // No error code for this since it is a Warning\n // eslint-disable-next-line no-restricted-syntax\n var w = new Error('Possible EventEmitter memory leak detected. ' +\n existing.length + ' ' + String(type) + ' listeners ' +\n 'added. Use emitter.setMaxListeners() to ' +\n 'increase limit');\n w.name = 'MaxListenersExceededWarning';\n w.emitter = target;\n w.type = type;\n w.count = existing.length;\n ProcessEmitWarning(w);\n }\n }\n\n return target;\n}\n\nEventEmitter.prototype.addListener = function addListener(type, listener) {\n return _addListener(this, type, listener, false);\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.prependListener =\n function prependListener(type, listener) {\n return _addListener(this, type, listener, true);\n };\n\nfunction onceWrapper() {\n var args = [];\n for (var i = 0; i < arguments.length; i++) args.push(arguments[i]);\n if (!this.fired) {\n this.target.removeListener(this.type, this.wrapFn);\n this.fired = true;\n ReflectApply(this.listener, this.target, args);\n }\n}\n\nfunction _onceWrap(target, type, listener) {\n var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };\n var wrapped = onceWrapper.bind(state);\n wrapped.listener = listener;\n state.wrapFn = wrapped;\n return wrapped;\n}\n\nEventEmitter.prototype.once = function once(type, listener) {\n if (typeof listener !== 'function') {\n throw new TypeError('The \"listener\" argument must be of type Function. Received type ' + typeof listener);\n }\n this.on(type, _onceWrap(this, type, listener));\n return this;\n};\n\nEventEmitter.prototype.prependOnceListener =\n function prependOnceListener(type, listener) {\n if (typeof listener !== 'function') {\n throw new TypeError('The \"listener\" argument must be of type Function. Received type ' + typeof listener);\n }\n this.prependListener(type, _onceWrap(this, type, listener));\n return this;\n };\n\n// Emits a 'removeListener' event if and only if the listener was removed.\nEventEmitter.prototype.removeListener =\n function removeListener(type, listener) {\n var list, events, position, i, originalListener;\n\n if (typeof listener !== 'function') {\n throw new TypeError('The \"listener\" argument must be of type Function. Received type ' + typeof listener);\n }\n\n events = this._events;\n if (events === undefined)\n return this;\n\n list = events[type];\n if (list === undefined)\n return this;\n\n if (list === listener || list.listener === listener) {\n if (--this._eventsCount === 0)\n this._events = Object.create(null);\n else {\n delete events[type];\n if (events.removeListener)\n this.emit('removeListener', type, list.listener || listener);\n }\n } else if (typeof list !== 'function') {\n position = -1;\n\n for (i = list.length - 1; i >= 0; i--) {\n if (list[i] === listener || list[i].listener === listener) {\n originalListener = list[i].listener;\n position = i;\n break;\n }\n }\n\n if (position < 0)\n return this;\n\n if (position === 0)\n list.shift();\n else {\n spliceOne(list, position);\n }\n\n if (list.length === 1)\n events[type] = list[0];\n\n if (events.removeListener !== undefined)\n this.emit('removeListener', type, originalListener || listener);\n }\n\n return this;\n };\n\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\n\nEventEmitter.prototype.removeAllListeners =\n function removeAllListeners(type) {\n var listeners, events, i;\n\n events = this._events;\n if (events === undefined)\n return this;\n\n // not listening for removeListener, no need to emit\n if (events.removeListener === undefined) {\n if (arguments.length === 0) {\n this._events = Object.create(null);\n this._eventsCount = 0;\n } else if (events[type] !== undefined) {\n if (--this._eventsCount === 0)\n this._events = Object.create(null);\n else\n delete events[type];\n }\n return this;\n }\n\n // emit removeListener for all listeners on all events\n if (arguments.length === 0) {\n var keys = Object.keys(events);\n var key;\n for (i = 0; i < keys.length; ++i) {\n key = keys[i];\n if (key === 'removeListener') continue;\n this.removeAllListeners(key);\n }\n this.removeAllListeners('removeListener');\n this._events = Object.create(null);\n this._eventsCount = 0;\n return this;\n }\n\n listeners = events[type];\n\n if (typeof listeners === 'function') {\n this.removeListener(type, listeners);\n } else if (listeners !== undefined) {\n // LIFO order\n for (i = listeners.length - 1; i >= 0; i--) {\n this.removeListener(type, listeners[i]);\n }\n }\n\n return this;\n };\n\nfunction _listeners(target, type, unwrap) {\n var events = target._events;\n\n if (events === undefined)\n return [];\n\n var evlistener = events[type];\n if (evlistener === undefined)\n return [];\n\n if (typeof evlistener === 'function')\n return unwrap ? [evlistener.listener || evlistener] : [evlistener];\n\n return unwrap ?\n unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);\n}\n\nEventEmitter.prototype.listeners = function listeners(type) {\n return _listeners(this, type, true);\n};\n\nEventEmitter.prototype.rawListeners = function rawListeners(type) {\n return _listeners(this, type, false);\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n if (typeof emitter.listenerCount === 'function') {\n return emitter.listenerCount(type);\n } else {\n return listenerCount.call(emitter, type);\n }\n};\n\nEventEmitter.prototype.listenerCount = listenerCount;\nfunction listenerCount(type) {\n var events = this._events;\n\n if (events !== undefined) {\n var evlistener = events[type];\n\n if (typeof evlistener === 'function') {\n return 1;\n } else if (evlistener !== undefined) {\n return evlistener.length;\n }\n }\n\n return 0;\n}\n\nEventEmitter.prototype.eventNames = function eventNames() {\n return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];\n};\n\nfunction arrayClone(arr, n) {\n var copy = new Array(n);\n for (var i = 0; i < n; ++i)\n copy[i] = arr[i];\n return copy;\n}\n\nfunction spliceOne(list, index) {\n for (; index + 1 < list.length; index++)\n list[index] = list[index + 1];\n list.pop();\n}\n\nfunction unwrapListeners(arr) {\n var ret = new Array(arr.length);\n for (var i = 0; i < ret.length; ++i) {\n ret[i] = arr[i].listener || arr[i];\n }\n return ret;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2V2ZW50cy9ldmVudHMuanM/ZmFhMSJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUiA9IHR5cGVvZiBSZWZsZWN0ID09PSAnb2JqZWN0JyA/IFJlZmxlY3QgOiBudWxsXG52YXIgUmVmbGVjdEFwcGx5ID0gUiAmJiB0eXBlb2YgUi5hcHBseSA9PT0gJ2Z1bmN0aW9uJ1xuICA/IFIuYXBwbHlcbiAgOiBmdW5jdGlvbiBSZWZsZWN0QXBwbHkodGFyZ2V0LCByZWNlaXZlciwgYXJncykge1xuICAgIHJldHVybiBGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHkuY2FsbCh0YXJnZXQsIHJlY2VpdmVyLCBhcmdzKTtcbiAgfVxuXG52YXIgUmVmbGVjdE93bktleXNcbmlmIChSICYmIHR5cGVvZiBSLm93bktleXMgPT09ICdmdW5jdGlvbicpIHtcbiAgUmVmbGVjdE93bktleXMgPSBSLm93bktleXNcbn0gZWxzZSBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scykge1xuICBSZWZsZWN0T3duS2V5cyA9IGZ1bmN0aW9uIFJlZmxlY3RPd25LZXlzKHRhcmdldCkge1xuICAgIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0YXJnZXQpXG4gICAgICAuY29uY2F0KE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHModGFyZ2V0KSk7XG4gIH07XG59IGVsc2Uge1xuICBSZWZsZWN0T3duS2V5cyA9IGZ1bmN0aW9uIFJlZmxlY3RPd25LZXlzKHRhcmdldCkge1xuICAgIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0YXJnZXQpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBQcm9jZXNzRW1pdFdhcm5pbmcod2FybmluZykge1xuICBpZiAoY29uc29sZSAmJiBjb25zb2xlLndhcm4pIGNvbnNvbGUud2Fybih3YXJuaW5nKTtcbn1cblxudmFyIE51bWJlcklzTmFOID0gTnVtYmVyLmlzTmFOIHx8IGZ1bmN0aW9uIE51bWJlcklzTmFOKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSAhPT0gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgRXZlbnRFbWl0dGVyLmluaXQuY2FsbCh0aGlzKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xuXG4vLyBCYWNrd2FyZHMtY29tcGF0IHdpdGggbm9kZSAwLjEwLnhcbkV2ZW50RW1pdHRlci5FdmVudEVtaXR0ZXIgPSBFdmVudEVtaXR0ZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX2V2ZW50cyA9IHVuZGVmaW5lZDtcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX2V2ZW50c0NvdW50ID0gMDtcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX21heExpc3RlbmVycyA9IHVuZGVmaW5lZDtcblxuLy8gQnkgZGVmYXVsdCBFdmVudEVtaXR0ZXJzIHdpbGwgcHJpbnQgYSB3YXJuaW5nIGlmIG1vcmUgdGhhbiAxMCBsaXN0ZW5lcnMgYXJlXG4vLyBhZGRlZCB0byBpdC4gVGhpcyBpcyBhIHVzZWZ1bCBkZWZhdWx0IHdoaWNoIGhlbHBzIGZpbmRpbmcgbWVtb3J5IGxlYWtzLlxudmFyIGRlZmF1bHRNYXhMaXN0ZW5lcnMgPSAxMDtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEV2ZW50RW1pdHRlciwgJ2RlZmF1bHRNYXhMaXN0ZW5lcnMnLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gIH0sXG4gIHNldDogZnVuY3Rpb24oYXJnKSB7XG4gICAgaWYgKHR5cGVvZiBhcmcgIT09ICdudW1iZXInIHx8IGFyZyA8IDAgfHwgTnVtYmVySXNOYU4oYXJnKSkge1xuICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RoZSB2YWx1ZSBvZiBcImRlZmF1bHRNYXhMaXN0ZW5lcnNcIiBpcyBvdXQgb2YgcmFuZ2UuIEl0IG11c3QgYmUgYSBub24tbmVnYXRpdmUgbnVtYmVyLiBSZWNlaXZlZCAnICsgYXJnICsgJy4nKTtcbiAgICB9XG4gICAgZGVmYXVsdE1heExpc3RlbmVycyA9IGFyZztcbiAgfVxufSk7XG5cbkV2ZW50RW1pdHRlci5pbml0ID0gZnVuY3Rpb24oKSB7XG5cbiAgaWYgKHRoaXMuX2V2ZW50cyA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICB0aGlzLl9ldmVudHMgPT09IE9iamVjdC5nZXRQcm90b3R5cGVPZih0aGlzKS5fZXZlbnRzKSB7XG4gICAgdGhpcy5fZXZlbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICB0aGlzLl9ldmVudHNDb3VudCA9IDA7XG4gIH1cblxuICB0aGlzLl9tYXhMaXN0ZW5lcnMgPSB0aGlzLl9tYXhMaXN0ZW5lcnMgfHwgdW5kZWZpbmVkO1xufTtcblxuLy8gT2J2aW91c2x5IG5vdCBhbGwgRW1pdHRlcnMgc2hvdWxkIGJlIGxpbWl0ZWQgdG8gMTAuIFRoaXMgZnVuY3Rpb24gYWxsb3dzXG4vLyB0aGF0IHRvIGJlIGluY3JlYXNlZC4gU2V0IHRvIHplcm8gZm9yIHVubGltaXRlZC5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuc2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24gc2V0TWF4TGlzdGVuZXJzKG4pIHtcbiAgaWYgKHR5cGVvZiBuICE9PSAnbnVtYmVyJyB8fCBuIDwgMCB8fCBOdW1iZXJJc05hTihuKSkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdUaGUgdmFsdWUgb2YgXCJuXCIgaXMgb3V0IG9mIHJhbmdlLiBJdCBtdXN0IGJlIGEgbm9uLW5lZ2F0aXZlIG51bWJlci4gUmVjZWl2ZWQgJyArIG4gKyAnLicpO1xuICB9XG4gIHRoaXMuX21heExpc3RlbmVycyA9IG47XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gJGdldE1heExpc3RlbmVycyh0aGF0KSB7XG4gIGlmICh0aGF0Ll9tYXhMaXN0ZW5lcnMgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gIHJldHVybiB0aGF0Ll9tYXhMaXN0ZW5lcnM7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZ2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24gZ2V0TWF4TGlzdGVuZXJzKCkge1xuICByZXR1cm4gJGdldE1heExpc3RlbmVycyh0aGlzKTtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIGVtaXQodHlwZSkge1xuICB2YXIgYXJncyA9IFtdO1xuICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgYXJncy5wdXNoKGFyZ3VtZW50c1tpXSk7XG4gIHZhciBkb0Vycm9yID0gKHR5cGUgPT09ICdlcnJvcicpO1xuXG4gIHZhciBldmVudHMgPSB0aGlzLl9ldmVudHM7XG4gIGlmIChldmVudHMgIT09IHVuZGVmaW5lZClcbiAgICBkb0Vycm9yID0gKGRvRXJyb3IgJiYgZXZlbnRzLmVycm9yID09PSB1bmRlZmluZWQpO1xuICBlbHNlIGlmICghZG9FcnJvcilcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgLy8gSWYgdGhlcmUgaXMgbm8gJ2Vycm9yJyBldmVudCBsaXN0ZW5lciB0aGVuIHRocm93LlxuICBpZiAoZG9FcnJvcikge1xuICAgIHZhciBlcjtcbiAgICBpZiAoYXJncy5sZW5ndGggPiAwKVxuICAgICAgZXIgPSBhcmdzWzBdO1xuICAgIGlmIChlciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAvLyBOb3RlOiBUaGUgY29tbWVudHMgb24gdGhlIGB0aHJvd2AgbGluZXMgYXJlIGludGVudGlvbmFsLCB0aGV5IHNob3dcbiAgICAgIC8vIHVwIGluIE5vZGUncyBvdXRwdXQgaWYgdGhpcyByZXN1bHRzIGluIGFuIHVuaGFuZGxlZCBleGNlcHRpb24uXG4gICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkICdlcnJvcicgZXZlbnRcbiAgICB9XG4gICAgLy8gQXQgbGVhc3QgZ2l2ZSBzb21lIGtpbmQgb2YgY29udGV4dCB0byB0aGUgdXNlclxuICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ1VuaGFuZGxlZCBlcnJvci4nICsgKGVyID8gJyAoJyArIGVyLm1lc3NhZ2UgKyAnKScgOiAnJykpO1xuICAgIGVyci5jb250ZXh0ID0gZXI7XG4gICAgdGhyb3cgZXJyOyAvLyBVbmhhbmRsZWQgJ2Vycm9yJyBldmVudFxuICB9XG5cbiAgdmFyIGhhbmRsZXIgPSBldmVudHNbdHlwZV07XG5cbiAgaWYgKGhhbmRsZXIgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKHR5cGVvZiBoYW5kbGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgUmVmbGVjdEFwcGx5KGhhbmRsZXIsIHRoaXMsIGFyZ3MpO1xuICB9IGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBSZWZsZWN0QXBwbHkobGlzdGVuZXJzW2ldLCB0aGlzLCBhcmdzKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuZnVuY3Rpb24gX2FkZExpc3RlbmVyKHRhcmdldCwgdHlwZSwgbGlzdGVuZXIsIHByZXBlbmQpIHtcbiAgdmFyIG07XG4gIHZhciBldmVudHM7XG4gIHZhciBleGlzdGluZztcblxuICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwibGlzdGVuZXJcIiBhcmd1bWVudCBtdXN0IGJlIG9mIHR5cGUgRnVuY3Rpb24uIFJlY2VpdmVkIHR5cGUgJyArIHR5cGVvZiBsaXN0ZW5lcik7XG4gIH1cblxuICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcbiAgaWYgKGV2ZW50cyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHRhcmdldC5fZXZlbnRzQ291bnQgPSAwO1xuICB9IGVsc2Uge1xuICAgIC8vIFRvIGF2b2lkIHJlY3Vyc2lvbiBpbiB0aGUgY2FzZSB0aGF0IHR5cGUgPT09IFwibmV3TGlzdGVuZXJcIiEgQmVmb3JlXG4gICAgLy8gYWRkaW5nIGl0IHRvIHRoZSBsaXN0ZW5lcnMsIGZpcnN0IGVtaXQgXCJuZXdMaXN0ZW5lclwiLlxuICAgIGlmIChldmVudHMubmV3TGlzdGVuZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGFyZ2V0LmVtaXQoJ25ld0xpc3RlbmVyJywgdHlwZSxcbiAgICAgICAgICAgICAgICAgIGxpc3RlbmVyLmxpc3RlbmVyID8gbGlzdGVuZXIubGlzdGVuZXIgOiBsaXN0ZW5lcik7XG5cbiAgICAgIC8vIFJlLWFzc2lnbiBgZXZlbnRzYCBiZWNhdXNlIGEgbmV3TGlzdGVuZXIgaGFuZGxlciBjb3VsZCBoYXZlIGNhdXNlZCB0aGVcbiAgICAgIC8vIHRoaXMuX2V2ZW50cyB0byBiZSBhc3NpZ25lZCB0byBhIG5ldyBvYmplY3RcbiAgICAgIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuICAgIH1cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXTtcbiAgfVxuXG4gIGlmIChleGlzdGluZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gT3B0aW1pemUgdGhlIGNhc2Ugb2Ygb25lIGxpc3RlbmVyLiBEb24ndCBuZWVkIHRoZSBleHRyYSBhcnJheSBvYmplY3QuXG4gICAgZXhpc3RpbmcgPSBldmVudHNbdHlwZV0gPSBsaXN0ZW5lcjtcbiAgICArK3RhcmdldC5fZXZlbnRzQ291bnQ7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHR5cGVvZiBleGlzdGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgLy8gQWRkaW5nIHRoZSBzZWNvbmQgZWxlbWVudCwgbmVlZCB0byBjaGFuZ2UgdG8gYXJyYXkuXG4gICAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9XG4gICAgICAgIHByZXBlbmQgPyBbbGlzdGVuZXIsIGV4aXN0aW5nXSA6IFtleGlzdGluZywgbGlzdGVuZXJdO1xuICAgICAgLy8gSWYgd2UndmUgYWxyZWFkeSBnb3QgYW4gYXJyYXksIGp1c3QgYXBwZW5kLlxuICAgIH0gZWxzZSBpZiAocHJlcGVuZCkge1xuICAgICAgZXhpc3RpbmcudW5zaGlmdChsaXN0ZW5lcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGV4aXN0aW5nLnB1c2gobGlzdGVuZXIpO1xuICAgIH1cblxuICAgIC8vIENoZWNrIGZvciBsaXN0ZW5lciBsZWFrXG4gICAgbSA9ICRnZXRNYXhMaXN0ZW5lcnModGFyZ2V0KTtcbiAgICBpZiAobSA+IDAgJiYgZXhpc3RpbmcubGVuZ3RoID4gbSAmJiAhZXhpc3Rpbmcud2FybmVkKSB7XG4gICAgICBleGlzdGluZy53YXJuZWQgPSB0cnVlO1xuICAgICAgLy8gTm8gZXJyb3IgY29kZSBmb3IgdGhpcyBzaW5jZSBpdCBpcyBhIFdhcm5pbmdcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheFxuICAgICAgdmFyIHcgPSBuZXcgRXJyb3IoJ1Bvc3NpYmxlIEV2ZW50RW1pdHRlciBtZW1vcnkgbGVhayBkZXRlY3RlZC4gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nLmxlbmd0aCArICcgJyArIFN0cmluZyh0eXBlKSArICcgbGlzdGVuZXJzICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAnYWRkZWQuIFVzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAnaW5jcmVhc2UgbGltaXQnKTtcbiAgICAgIHcubmFtZSA9ICdNYXhMaXN0ZW5lcnNFeGNlZWRlZFdhcm5pbmcnO1xuICAgICAgdy5lbWl0dGVyID0gdGFyZ2V0O1xuICAgICAgdy50eXBlID0gdHlwZTtcbiAgICAgIHcuY291bnQgPSBleGlzdGluZy5sZW5ndGg7XG4gICAgICBQcm9jZXNzRW1pdFdhcm5pbmcodyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnByZXBlbmRMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICByZXR1cm4gX2FkZExpc3RlbmVyKHRoaXMsIHR5cGUsIGxpc3RlbmVyLCB0cnVlKTtcbiAgICB9O1xuXG5mdW5jdGlvbiBvbmNlV3JhcHBlcigpIHtcbiAgdmFyIGFyZ3MgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIGFyZ3MucHVzaChhcmd1bWVudHNbaV0pO1xuICBpZiAoIXRoaXMuZmlyZWQpIHtcbiAgICB0aGlzLnRhcmdldC5yZW1vdmVMaXN0ZW5lcih0aGlzLnR5cGUsIHRoaXMud3JhcEZuKTtcbiAgICB0aGlzLmZpcmVkID0gdHJ1ZTtcbiAgICBSZWZsZWN0QXBwbHkodGhpcy5saXN0ZW5lciwgdGhpcy50YXJnZXQsIGFyZ3MpO1xuICB9XG59XG5cbmZ1bmN0aW9uIF9vbmNlV3JhcCh0YXJnZXQsIHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBzdGF0ZSA9IHsgZmlyZWQ6IGZhbHNlLCB3cmFwRm46IHVuZGVmaW5lZCwgdGFyZ2V0OiB0YXJnZXQsIHR5cGU6IHR5cGUsIGxpc3RlbmVyOiBsaXN0ZW5lciB9O1xuICB2YXIgd3JhcHBlZCA9IG9uY2VXcmFwcGVyLmJpbmQoc3RhdGUpO1xuICB3cmFwcGVkLmxpc3RlbmVyID0gbGlzdGVuZXI7XG4gIHN0YXRlLndyYXBGbiA9IHdyYXBwZWQ7XG4gIHJldHVybiB3cmFwcGVkO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiBvbmNlKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgb2YgdHlwZSBGdW5jdGlvbi4gUmVjZWl2ZWQgdHlwZSAnICsgdHlwZW9mIGxpc3RlbmVyKTtcbiAgfVxuICB0aGlzLm9uKHR5cGUsIF9vbmNlV3JhcCh0aGlzLCB0eXBlLCBsaXN0ZW5lcikpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZE9uY2VMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZE9uY2VMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgb2YgdHlwZSBGdW5jdGlvbi4gUmVjZWl2ZWQgdHlwZSAnICsgdHlwZW9mIGxpc3RlbmVyKTtcbiAgICAgIH1cbiAgICAgIHRoaXMucHJlcGVuZExpc3RlbmVyKHR5cGUsIF9vbmNlV3JhcCh0aGlzLCB0eXBlLCBsaXN0ZW5lcikpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuLy8gRW1pdHMgYSAncmVtb3ZlTGlzdGVuZXInIGV2ZW50IGlmIGFuZCBvbmx5IGlmIHRoZSBsaXN0ZW5lciB3YXMgcmVtb3ZlZC5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXIgPVxuICAgIGZ1bmN0aW9uIHJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICB2YXIgbGlzdCwgZXZlbnRzLCBwb3NpdGlvbiwgaSwgb3JpZ2luYWxMaXN0ZW5lcjtcblxuICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgb2YgdHlwZSBGdW5jdGlvbi4gUmVjZWl2ZWQgdHlwZSAnICsgdHlwZW9mIGxpc3RlbmVyKTtcbiAgICAgIH1cblxuICAgICAgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuICAgICAgaWYgKGV2ZW50cyA9PT0gdW5kZWZpbmVkKVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgbGlzdCA9IGV2ZW50c1t0eXBlXTtcbiAgICAgIGlmIChsaXN0ID09PSB1bmRlZmluZWQpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICBpZiAobGlzdCA9PT0gbGlzdGVuZXIgfHwgbGlzdC5saXN0ZW5lciA9PT0gbGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKC0tdGhpcy5fZXZlbnRzQ291bnQgPT09IDApXG4gICAgICAgICAgdGhpcy5fZXZlbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgZGVsZXRlIGV2ZW50c1t0eXBlXTtcbiAgICAgICAgICBpZiAoZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3QubGlzdGVuZXIgfHwgbGlzdGVuZXIpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBsaXN0ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHBvc2l0aW9uID0gLTE7XG5cbiAgICAgICAgZm9yIChpID0gbGlzdC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgIGlmIChsaXN0W2ldID09PSBsaXN0ZW5lciB8fCBsaXN0W2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICAgICAgb3JpZ2luYWxMaXN0ZW5lciA9IGxpc3RbaV0ubGlzdGVuZXI7XG4gICAgICAgICAgICBwb3NpdGlvbiA9IGk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocG9zaXRpb24gPCAwKVxuICAgICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAgIGlmIChwb3NpdGlvbiA9PT0gMClcbiAgICAgICAgICBsaXN0LnNoaWZ0KCk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHNwbGljZU9uZShsaXN0LCBwb3NpdGlvbik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobGlzdC5sZW5ndGggPT09IDEpXG4gICAgICAgICAgZXZlbnRzW3R5cGVdID0gbGlzdFswXTtcblxuICAgICAgICBpZiAoZXZlbnRzLnJlbW92ZUxpc3RlbmVyICE9PSB1bmRlZmluZWQpXG4gICAgICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIG9yaWdpbmFsTGlzdGVuZXIgfHwgbGlzdGVuZXIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9mZiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlQWxsTGlzdGVuZXJzID1cbiAgICBmdW5jdGlvbiByZW1vdmVBbGxMaXN0ZW5lcnModHlwZSkge1xuICAgICAgdmFyIGxpc3RlbmVycywgZXZlbnRzLCBpO1xuXG4gICAgICBldmVudHMgPSB0aGlzLl9ldmVudHM7XG4gICAgICBpZiAoZXZlbnRzID09PSB1bmRlZmluZWQpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAvLyBub3QgbGlzdGVuaW5nIGZvciByZW1vdmVMaXN0ZW5lciwgbm8gbmVlZCB0byBlbWl0XG4gICAgICBpZiAoZXZlbnRzLnJlbW92ZUxpc3RlbmVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudHNbdHlwZV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGlmICgtLXRoaXMuX2V2ZW50c0NvdW50ID09PSAwKVxuICAgICAgICAgICAgdGhpcy5fZXZlbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICBkZWxldGUgZXZlbnRzW3R5cGVdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuXG4gICAgICAvLyBlbWl0IHJlbW92ZUxpc3RlbmVyIGZvciBhbGwgbGlzdGVuZXJzIG9uIGFsbCBldmVudHNcbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMoZXZlbnRzKTtcbiAgICAgICAgdmFyIGtleTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBrZXkgPSBrZXlzW2ldO1xuICAgICAgICAgIGlmIChrZXkgPT09ICdyZW1vdmVMaXN0ZW5lcicpIGNvbnRpbnVlO1xuICAgICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKGtleSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoJ3JlbW92ZUxpc3RlbmVyJyk7XG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIGxpc3RlbmVycyA9IGV2ZW50c1t0eXBlXTtcblxuICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lcnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnMpO1xuICAgICAgfSBlbHNlIGlmIChsaXN0ZW5lcnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAvLyBMSUZPIG9yZGVyXG4gICAgICAgIGZvciAoaSA9IGxpc3RlbmVycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG5mdW5jdGlvbiBfbGlzdGVuZXJzKHRhcmdldCwgdHlwZSwgdW53cmFwKSB7XG4gIHZhciBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcblxuICBpZiAoZXZlbnRzID09PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIFtdO1xuXG4gIHZhciBldmxpc3RlbmVyID0gZXZlbnRzW3R5cGVdO1xuICBpZiAoZXZsaXN0ZW5lciA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBbXTtcblxuICBpZiAodHlwZW9mIGV2bGlzdGVuZXIgPT09ICdmdW5jdGlvbicpXG4gICAgcmV0dXJuIHVud3JhcCA/IFtldmxpc3RlbmVyLmxpc3RlbmVyIHx8IGV2bGlzdGVuZXJdIDogW2V2bGlzdGVuZXJdO1xuXG4gIHJldHVybiB1bndyYXAgP1xuICAgIHVud3JhcExpc3RlbmVycyhldmxpc3RlbmVyKSA6IGFycmF5Q2xvbmUoZXZsaXN0ZW5lciwgZXZsaXN0ZW5lci5sZW5ndGgpO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uIGxpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIHRydWUpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yYXdMaXN0ZW5lcnMgPSBmdW5jdGlvbiByYXdMaXN0ZW5lcnModHlwZSkge1xuICByZXR1cm4gX2xpc3RlbmVycyh0aGlzLCB0eXBlLCBmYWxzZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIubGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uKGVtaXR0ZXIsIHR5cGUpIHtcbiAgaWYgKHR5cGVvZiBlbWl0dGVyLmxpc3RlbmVyQ291bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gZW1pdHRlci5saXN0ZW5lckNvdW50KHR5cGUpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBsaXN0ZW5lckNvdW50LmNhbGwoZW1pdHRlciwgdHlwZSk7XG4gIH1cbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJDb3VudCA9IGxpc3RlbmVyQ291bnQ7XG5mdW5jdGlvbiBsaXN0ZW5lckNvdW50KHR5cGUpIHtcbiAgdmFyIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcblxuICBpZiAoZXZlbnRzICE9PSB1bmRlZmluZWQpIHtcbiAgICB2YXIgZXZsaXN0ZW5lciA9IGV2ZW50c1t0eXBlXTtcblxuICAgIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfSBlbHNlIGlmIChldmxpc3RlbmVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBldmxpc3RlbmVyLmxlbmd0aDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gMDtcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5ldmVudE5hbWVzID0gZnVuY3Rpb24gZXZlbnROYW1lcygpIHtcbiAgcmV0dXJuIHRoaXMuX2V2ZW50c0NvdW50ID4gMCA/IFJlZmxlY3RPd25LZXlzKHRoaXMuX2V2ZW50cykgOiBbXTtcbn07XG5cbmZ1bmN0aW9uIGFycmF5Q2xvbmUoYXJyLCBuKSB7XG4gIHZhciBjb3B5ID0gbmV3IEFycmF5KG4pO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG47ICsraSlcbiAgICBjb3B5W2ldID0gYXJyW2ldO1xuICByZXR1cm4gY29weTtcbn1cblxuZnVuY3Rpb24gc3BsaWNlT25lKGxpc3QsIGluZGV4KSB7XG4gIGZvciAoOyBpbmRleCArIDEgPCBsaXN0Lmxlbmd0aDsgaW5kZXgrKylcbiAgICBsaXN0W2luZGV4XSA9IGxpc3RbaW5kZXggKyAxXTtcbiAgbGlzdC5wb3AoKTtcbn1cblxuZnVuY3Rpb24gdW53cmFwTGlzdGVuZXJzKGFycikge1xuICB2YXIgcmV0ID0gbmV3IEFycmF5KGFyci5sZW5ndGgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHJldC5sZW5ndGg7ICsraSkge1xuICAgIHJldFtpXSA9IGFycltpXS5saXN0ZW5lciB8fCBhcnJbaV07XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/events/events.js\n"); + +/***/ }), + +/***/ "./node_modules/https-browserify/index.js": +/*!************************************************!*\ + !*** ./node_modules/https-browserify/index.js ***! + \************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var http = __webpack_require__(/*! http */ \"./node_modules/stream-http/index.js\")\nvar url = __webpack_require__(/*! url */ \"./node_modules/url/url.js\")\n\nvar https = module.exports\n\nfor (var key in http) {\n if (http.hasOwnProperty(key)) https[key] = http[key]\n}\n\nhttps.request = function (params, cb) {\n params = validateParams(params)\n return http.request.call(this, params, cb)\n}\n\nhttps.get = function (params, cb) {\n params = validateParams(params)\n return http.get.call(this, params, cb)\n}\n\nfunction validateParams (params) {\n if (typeof params === 'string') {\n params = url.parse(params)\n }\n if (!params.protocol) {\n params.protocol = 'https:'\n }\n if (params.protocol !== 'https:') {\n throw new Error('Protocol \"' + params.protocol + '\" not supported. Expected \"https:\"')\n }\n return params\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvaHR0cHMtYnJvd3NlcmlmeS9pbmRleC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2h0dHBzLWJyb3dzZXJpZnkvaW5kZXguanM/MjRmOCJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgaHR0cCA9IHJlcXVpcmUoJ2h0dHAnKVxudmFyIHVybCA9IHJlcXVpcmUoJ3VybCcpXG5cbnZhciBodHRwcyA9IG1vZHVsZS5leHBvcnRzXG5cbmZvciAodmFyIGtleSBpbiBodHRwKSB7XG4gIGlmIChodHRwLmhhc093blByb3BlcnR5KGtleSkpIGh0dHBzW2tleV0gPSBodHRwW2tleV1cbn1cblxuaHR0cHMucmVxdWVzdCA9IGZ1bmN0aW9uIChwYXJhbXMsIGNiKSB7XG4gIHBhcmFtcyA9IHZhbGlkYXRlUGFyYW1zKHBhcmFtcylcbiAgcmV0dXJuIGh0dHAucmVxdWVzdC5jYWxsKHRoaXMsIHBhcmFtcywgY2IpXG59XG5cbmh0dHBzLmdldCA9IGZ1bmN0aW9uIChwYXJhbXMsIGNiKSB7XG4gIHBhcmFtcyA9IHZhbGlkYXRlUGFyYW1zKHBhcmFtcylcbiAgcmV0dXJuIGh0dHAuZ2V0LmNhbGwodGhpcywgcGFyYW1zLCBjYilcbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVQYXJhbXMgKHBhcmFtcykge1xuICBpZiAodHlwZW9mIHBhcmFtcyA9PT0gJ3N0cmluZycpIHtcbiAgICBwYXJhbXMgPSB1cmwucGFyc2UocGFyYW1zKVxuICB9XG4gIGlmICghcGFyYW1zLnByb3RvY29sKSB7XG4gICAgcGFyYW1zLnByb3RvY29sID0gJ2h0dHBzOidcbiAgfVxuICBpZiAocGFyYW1zLnByb3RvY29sICE9PSAnaHR0cHM6Jykge1xuICAgIHRocm93IG5ldyBFcnJvcignUHJvdG9jb2wgXCInICsgcGFyYW1zLnByb3RvY29sICsgJ1wiIG5vdCBzdXBwb3J0ZWQuIEV4cGVjdGVkIFwiaHR0cHM6XCInKVxuICB9XG4gIHJldHVybiBwYXJhbXNcbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/https-browserify/index.js\n"); + +/***/ }), + +/***/ "./node_modules/ieee754/index.js": +/*!***************************************!*\ + !*** ./node_modules/ieee754/index.js ***! + \***************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("exports.read = function (buffer, offset, isLE, mLen, nBytes) {\n var e, m\n var eLen = (nBytes * 8) - mLen - 1\n var eMax = (1 << eLen) - 1\n var eBias = eMax >> 1\n var nBits = -7\n var i = isLE ? (nBytes - 1) : 0\n var d = isLE ? -1 : 1\n var s = buffer[offset + i]\n\n i += d\n\n e = s & ((1 << (-nBits)) - 1)\n s >>= (-nBits)\n nBits += eLen\n for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n m = e & ((1 << (-nBits)) - 1)\n e >>= (-nBits)\n nBits += mLen\n for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n if (e === 0) {\n e = 1 - eBias\n } else if (e === eMax) {\n return m ? NaN : ((s ? -1 : 1) * Infinity)\n } else {\n m = m + Math.pow(2, mLen)\n e = e - eBias\n }\n return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n var e, m, c\n var eLen = (nBytes * 8) - mLen - 1\n var eMax = (1 << eLen) - 1\n var eBias = eMax >> 1\n var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n var i = isLE ? 0 : (nBytes - 1)\n var d = isLE ? 1 : -1\n var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n value = Math.abs(value)\n\n if (isNaN(value) || value === Infinity) {\n m = isNaN(value) ? 1 : 0\n e = eMax\n } else {\n e = Math.floor(Math.log(value) / Math.LN2)\n if (value * (c = Math.pow(2, -e)) < 1) {\n e--\n c *= 2\n }\n if (e + eBias >= 1) {\n value += rt / c\n } else {\n value += rt * Math.pow(2, 1 - eBias)\n }\n if (value * c >= 2) {\n e++\n c /= 2\n }\n\n if (e + eBias >= eMax) {\n m = 0\n e = eMax\n } else if (e + eBias >= 1) {\n m = ((value * c) - 1) * Math.pow(2, mLen)\n e = e + eBias\n } else {\n m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n e = 0\n }\n }\n\n for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n e = (e << mLen) | m\n eLen += mLen\n for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n buffer[offset + i - d] |= s * 128\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2llZWU3NTQvaW5kZXguanM/OTE1MiJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnRzLnJlYWQgPSBmdW5jdGlvbiAoYnVmZmVyLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbVxuICB2YXIgZUxlbiA9IChuQnl0ZXMgKiA4KSAtIG1MZW4gLSAxXG4gIHZhciBlTWF4ID0gKDEgPDwgZUxlbikgLSAxXG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMVxuICB2YXIgbkJpdHMgPSAtN1xuICB2YXIgaSA9IGlzTEUgPyAobkJ5dGVzIC0gMSkgOiAwXG4gIHZhciBkID0gaXNMRSA/IC0xIDogMVxuICB2YXIgcyA9IGJ1ZmZlcltvZmZzZXQgKyBpXVxuXG4gIGkgKz0gZFxuXG4gIGUgPSBzICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpXG4gIHMgPj49ICgtbkJpdHMpXG4gIG5CaXRzICs9IGVMZW5cbiAgZm9yICg7IG5CaXRzID4gMDsgZSA9IChlICogMjU2KSArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIG0gPSBlICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpXG4gIGUgPj49ICgtbkJpdHMpXG4gIG5CaXRzICs9IG1MZW5cbiAgZm9yICg7IG5CaXRzID4gMDsgbSA9IChtICogMjU2KSArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIGlmIChlID09PSAwKSB7XG4gICAgZSA9IDEgLSBlQmlhc1xuICB9IGVsc2UgaWYgKGUgPT09IGVNYXgpIHtcbiAgICByZXR1cm4gbSA/IE5hTiA6ICgocyA/IC0xIDogMSkgKiBJbmZpbml0eSlcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIE1hdGgucG93KDIsIG1MZW4pXG4gICAgZSA9IGUgLSBlQmlhc1xuICB9XG4gIHJldHVybiAocyA/IC0xIDogMSkgKiBtICogTWF0aC5wb3coMiwgZSAtIG1MZW4pXG59XG5cbmV4cG9ydHMud3JpdGUgPSBmdW5jdGlvbiAoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG0sIGNcbiAgdmFyIGVMZW4gPSAobkJ5dGVzICogOCkgLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIHJ0ID0gKG1MZW4gPT09IDIzID8gTWF0aC5wb3coMiwgLTI0KSAtIE1hdGgucG93KDIsIC03NykgOiAwKVxuICB2YXIgaSA9IGlzTEUgPyAwIDogKG5CeXRlcyAtIDEpXG4gIHZhciBkID0gaXNMRSA/IDEgOiAtMVxuICB2YXIgcyA9IHZhbHVlIDwgMCB8fCAodmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCkgPyAxIDogMFxuXG4gIHZhbHVlID0gTWF0aC5hYnModmFsdWUpXG5cbiAgaWYgKGlzTmFOKHZhbHVlKSB8fCB2YWx1ZSA9PT0gSW5maW5pdHkpIHtcbiAgICBtID0gaXNOYU4odmFsdWUpID8gMSA6IDBcbiAgICBlID0gZU1heFxuICB9IGVsc2Uge1xuICAgIGUgPSBNYXRoLmZsb29yKE1hdGgubG9nKHZhbHVlKSAvIE1hdGguTE4yKVxuICAgIGlmICh2YWx1ZSAqIChjID0gTWF0aC5wb3coMiwgLWUpKSA8IDEpIHtcbiAgICAgIGUtLVxuICAgICAgYyAqPSAyXG4gICAgfVxuICAgIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgdmFsdWUgKz0gcnQgLyBjXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlICs9IHJ0ICogTWF0aC5wb3coMiwgMSAtIGVCaWFzKVxuICAgIH1cbiAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcbiAgICAgIGUrK1xuICAgICAgYyAvPSAyXG4gICAgfVxuXG4gICAgaWYgKGUgKyBlQmlhcyA+PSBlTWF4KSB7XG4gICAgICBtID0gMFxuICAgICAgZSA9IGVNYXhcbiAgICB9IGVsc2UgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICBtID0gKCh2YWx1ZSAqIGMpIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKVxuICAgICAgZSA9IGUgKyBlQmlhc1xuICAgIH0gZWxzZSB7XG4gICAgICBtID0gdmFsdWUgKiBNYXRoLnBvdygyLCBlQmlhcyAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSAwXG4gICAgfVxuICB9XG5cbiAgZm9yICg7IG1MZW4gPj0gODsgYnVmZmVyW29mZnNldCArIGldID0gbSAmIDB4ZmYsIGkgKz0gZCwgbSAvPSAyNTYsIG1MZW4gLT0gOCkge31cblxuICBlID0gKGUgPDwgbUxlbikgfCBtXG4gIGVMZW4gKz0gbUxlblxuICBmb3IgKDsgZUxlbiA+IDA7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IGUgJiAweGZmLCBpICs9IGQsIGUgLz0gMjU2LCBlTGVuIC09IDgpIHt9XG5cbiAgYnVmZmVyW29mZnNldCArIGkgLSBkXSB8PSBzICogMTI4XG59XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/ieee754/index.js\n"); + +/***/ }), + +/***/ "./node_modules/inherits/inherits_browser.js": +/*!***************************************************!*\ + !*** ./node_modules/inherits/inherits_browser.js ***! + \***************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("if (typeof Object.create === 'function') {\n // implementation from standard node.js 'util' module\n module.exports = function inherits(ctor, superCtor) {\n ctor.super_ = superCtor\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n };\n} else {\n // old school shim for old browsers\n module.exports = function inherits(ctor, superCtor) {\n ctor.super_ = superCtor\n var TempCtor = function () {}\n TempCtor.prototype = superCtor.prototype\n ctor.prototype = new TempCtor()\n ctor.prototype.constructor = ctor\n }\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvaW5oZXJpdHMvaW5oZXJpdHNfYnJvd3Nlci5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2luaGVyaXRzL2luaGVyaXRzX2Jyb3dzZXIuanM/M2ZiNSJdLCJzb3VyY2VzQ29udGVudCI6WyJpZiAodHlwZW9mIE9iamVjdC5jcmVhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgLy8gaW1wbGVtZW50YXRpb24gZnJvbSBzdGFuZGFyZCBub2RlLmpzICd1dGlsJyBtb2R1bGVcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICB2YWx1ZTogY3RvcixcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICB2YXIgVGVtcEN0b3IgPSBmdW5jdGlvbiAoKSB7fVxuICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgY3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjdG9yXG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/inherits/inherits_browser.js\n"); + +/***/ }), + +/***/ "./node_modules/isarray/index.js": +/*!***************************************!*\ + !*** ./node_modules/isarray/index.js ***! + \***************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("var toString = {}.toString;\n\nmodule.exports = Array.isArray || function (arr) {\n return toString.call(arr) == '[object Array]';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvaXNhcnJheS9pbmRleC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0pTLy4vbm9kZV9tb2R1bGVzL2lzYXJyYXkvaW5kZXguanM/ZTNkYiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgdG9TdHJpbmcgPSB7fS50b1N0cmluZztcblxubW9kdWxlLmV4cG9ydHMgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uIChhcnIpIHtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwoYXJyKSA9PSAnW29iamVjdCBBcnJheV0nO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/isarray/index.js\n"); + +/***/ }), + +/***/ "./node_modules/jquery/dist/jquery.js": +/*!********************************************!*\ + !*** ./node_modules/jquery/dist/jquery.js ***! + \********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!\n * jQuery JavaScript Library v3.4.1\n * https://jquery.com/\n *\n * Includes Sizzle.js\n * https://sizzlejs.com/\n *\n * Copyright JS Foundation and other contributors\n * Released under the MIT license\n * https://jquery.org/license\n *\n * Date: 2019-05-01T21:04Z\n */\n( function( global, factory ) {\n\n\t\"use strict\";\n\n\tif ( true && typeof module.exports === \"object\" ) {\n\n\t\t// For CommonJS and CommonJS-like environments where a proper `window`\n\t\t// is present, execute the factory and get jQuery.\n\t\t// For environments that do not have a `window` with a `document`\n\t\t// (such as Node.js), expose a factory as module.exports.\n\t\t// This accentuates the need for the creation of a real `window`.\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info.\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n} )( typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1\n// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode\n// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common\n// enough that all such attempts are guarded in a try block.\n\"use strict\";\n\nvar arr = [];\n\nvar document = window.document;\n\nvar getProto = Object.getPrototypeOf;\n\nvar slice = arr.slice;\n\nvar concat = arr.concat;\n\nvar push = arr.push;\n\nvar indexOf = arr.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar fnToString = hasOwn.toString;\n\nvar ObjectFunctionString = fnToString.call( Object );\n\nvar support = {};\n\nvar isFunction = function isFunction( obj ) {\n\n // Support: Chrome <=57, Firefox <=52\n // In some browsers, typeof returns \"function\" for HTML elements\n // (i.e., `typeof document.createElement( \"object\" ) === \"function\"`).\n // We don't want to classify *any* DOM node as a function.\n return typeof obj === \"function\" && typeof obj.nodeType !== \"number\";\n };\n\n\nvar isWindow = function isWindow( obj ) {\n\t\treturn obj != null && obj === obj.window;\n\t};\n\n\n\n\n\tvar preservedScriptAttributes = {\n\t\ttype: true,\n\t\tsrc: true,\n\t\tnonce: true,\n\t\tnoModule: true\n\t};\n\n\tfunction DOMEval( code, node, doc ) {\n\t\tdoc = doc || document;\n\n\t\tvar i, val,\n\t\t\tscript = doc.createElement( \"script\" );\n\n\t\tscript.text = code;\n\t\tif ( node ) {\n\t\t\tfor ( i in preservedScriptAttributes ) {\n\n\t\t\t\t// Support: Firefox 64+, Edge 18+\n\t\t\t\t// Some browsers don't support the \"nonce\" property on scripts.\n\t\t\t\t// On the other hand, just using `getAttribute` is not enough as\n\t\t\t\t// the `nonce` attribute is reset to an empty string whenever it\n\t\t\t\t// becomes browsing-context connected.\n\t\t\t\t// See https://github.com/whatwg/html/issues/2369\n\t\t\t\t// See https://html.spec.whatwg.org/#nonce-attributes\n\t\t\t\t// The `node.getAttribute` check was added for the sake of\n\t\t\t\t// `jQuery.globalEval` so that it can fake a nonce-containing node\n\t\t\t\t// via an object.\n\t\t\t\tval = node[ i ] || node.getAttribute && node.getAttribute( i );\n\t\t\t\tif ( val ) {\n\t\t\t\t\tscript.setAttribute( i, val );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdoc.head.appendChild( script ).parentNode.removeChild( script );\n\t}\n\n\nfunction toType( obj ) {\n\tif ( obj == null ) {\n\t\treturn obj + \"\";\n\t}\n\n\t// Support: Android <=2.3 only (functionish RegExp)\n\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\tclass2type[ toString.call( obj ) ] || \"object\" :\n\t\ttypeof obj;\n}\n/* global Symbol */\n// Defining this global in .eslintrc.json would create a danger of using the global\n// unguarded in another place, it seems safer to define global only for this module\n\n\n\nvar\n\tversion = \"3.4.1\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t},\n\n\t// Support: Android <=4.0 only\n\t// Make sure we trim BOM and NBSP\n\trtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g;\n\njQuery.fn = jQuery.prototype = {\n\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\n\t\t// Return all the elements in a clean array\n\t\tif ( num == null ) {\n\t\t\treturn slice.call( this );\n\t\t}\n\n\t\t// Return just the one element from the set\n\t\treturn num < 0 ? this[ num + this.length ] : this[ num ];\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\teach: function( callback ) {\n\t\treturn jQuery.each( this, callback );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map( this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t} ) );\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor();\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: arr.sort,\n\tsplice: arr.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[ 0 ] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// Skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !isFunction( target ) ) {\n\t\ttarget = {};\n\t}\n\n\t// Extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\n\t\t// Only deal with non-null/undefined values\n\t\tif ( ( options = arguments[ i ] ) != null ) {\n\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent Object.prototype pollution\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( name === \"__proto__\" || target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject( copy ) ||\n\t\t\t\t\t( copyIsArray = Array.isArray( copy ) ) ) ) {\n\t\t\t\t\tsrc = target[ name ];\n\n\t\t\t\t\t// Ensure proper type for the source value\n\t\t\t\t\tif ( copyIsArray && !Array.isArray( src ) ) {\n\t\t\t\t\t\tclone = [];\n\t\t\t\t\t} else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {\n\t\t\t\t\t\tclone = {};\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src;\n\t\t\t\t\t}\n\t\t\t\t\tcopyIsArray = false;\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend( {\n\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\tisPlainObject: function( obj ) {\n\t\tvar proto, Ctor;\n\n\t\t// Detect obvious negatives\n\t\t// Use toString instead of jQuery.type to catch host objects\n\t\tif ( !obj || toString.call( obj ) !== \"[object Object]\" ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tproto = getProto( obj );\n\n\t\t// Objects with no prototype (e.g., `Object.create( null )`) are plain\n\t\tif ( !proto ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Objects with prototype are plain iff they were constructed by a global Object function\n\t\tCtor = hasOwn.call( proto, \"constructor\" ) && proto.constructor;\n\t\treturn typeof Ctor === \"function\" && fnToString.call( Ctor ) === ObjectFunctionString;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\t// Evaluates a script in a global context\n\tglobalEval: function( code, options ) {\n\t\tDOMEval( code, { nonce: options && options.nonce } );\n\t},\n\n\teach: function( obj, callback ) {\n\t\tvar length, i = 0;\n\n\t\tif ( isArrayLike( obj ) ) {\n\t\t\tlength = obj.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor ( i in obj ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// Support: Android <=4.0 only\n\ttrim: function( text ) {\n\t\treturn text == null ?\n\t\t\t\"\" :\n\t\t\t( text + \"\" ).replace( rtrim, \"\" );\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArrayLike( Object( arr ) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\treturn arr == null ? -1 : indexOf.call( arr, elem, i );\n\t},\n\n\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t// push.apply(_, arraylike) throws on ancient WebKit\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\tfor ( ; j < len; j++ ) {\n\t\t\tfirst[ i++ ] = second[ j ];\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar length, value,\n\t\t\ti = 0,\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArrayLike( elems ) ) {\n\t\t\tlength = elems.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n} );\n\nif ( typeof Symbol === \"function\" ) {\n\tjQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];\n}\n\n// Populate the class2type map\njQuery.each( \"Boolean Number String Function Array Date RegExp Object Error Symbol\".split( \" \" ),\nfunction( i, name ) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n} );\n\nfunction isArrayLike( obj ) {\n\n\t// Support: real iOS 8.2 only (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = !!obj && \"length\" in obj && obj.length,\n\t\ttype = toType( obj );\n\n\tif ( isFunction( obj ) || isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.3.4\n * https://sizzlejs.com/\n *\n * Copyright JS Foundation and other contributors\n * Released under the MIT license\n * https://js.foundation/\n *\n * Date: 2019-04-08\n */\n(function( window ) {\n\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tnonnativeSelectorCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// Instance methods\n\thasOwn = ({}).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpush_native = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\t// Use a stripped-down indexOf as it's faster than native\n\t// https://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\n\t// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n\tidentifier = \"(?:\\\\\\\\.|[\\\\w-]|[^\\0-\\\\xa0])+\",\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + identifier + \")(?:\" + whitespace +\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\t\t// \"Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" + whitespace +\n\t\t\"*\\\\]\",\n\n\tpseudos = \":(\" + identifier + \")(?:\\\\((\" +\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\trdescend = new RegExp( whitespace + \"|>\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + identifier + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + identifier + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + identifier + \"|[*])\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n\t\t\twhitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trhtml = /HTML$/i,\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\n\t// CSS escapes\n\t// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n\tfunescape = function( _, escaped, escapedWhitespace ) {\n\t\tvar high = \"0x\" + escaped - 0x10000;\n\t\t// NaN means non-codepoint\n\t\t// Support: Firefox<24\n\t\t// Workaround erroneous numeric interpretation of +\"0x\"\n\t\treturn high !== high || escapedWhitespace ?\n\t\t\tescaped :\n\t\t\thigh < 0 ?\n\t\t\t\t// BMP codepoint\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\t// Supplemental Plane codepoint (surrogate pair)\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// CSS string/identifier serialization\n\t// https://drafts.csswg.org/cssom/#common-serializing-idioms\n\trcssescape = /([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,\n\tfcssescape = function( ch, asCodePoint ) {\n\t\tif ( asCodePoint ) {\n\n\t\t\t// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER\n\t\t\tif ( ch === \"\\0\" ) {\n\t\t\t\treturn \"\\uFFFD\";\n\t\t\t}\n\n\t\t\t// Control characters and (dependent upon position) numbers get escaped as code points\n\t\t\treturn ch.slice( 0, -1 ) + \"\\\\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + \" \";\n\t\t}\n\n\t\t// Other potentially-special ASCII characters get backslash-escaped\n\t\treturn \"\\\\\" + ch;\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t},\n\n\tinDisabledFieldset = addCombinator(\n\t\tfunction( elem ) {\n\t\t\treturn elem.disabled === true && elem.nodeName.toLowerCase() === \"fieldset\";\n\t\t},\n\t\t{ dir: \"parentNode\", next: \"legend\" }\n\t);\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t(arr = slice.call( preferredDoc.childNodes )),\n\t\tpreferredDoc.childNodes\n\t);\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpush_native.apply( target, slice.call(els) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( (target[j++] = els[i++]) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar m, i, elem, nid, match, groups, newSelector,\n\t\tnewContext = context && context.ownerDocument,\n\n\t\t// nodeType defaults to 9, since context defaults to document\n\t\tnodeType = context ? context.nodeType : 9;\n\n\tresults = results || [];\n\n\t// Return early from calls with invalid selector or context\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\t// Try to shortcut find operations (as opposed to filters) in HTML documents\n\tif ( !seed ) {\n\n\t\tif ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n\t\t\tsetDocument( context );\n\t\t}\n\t\tcontext = context || document;\n\n\t\tif ( documentIsHTML ) {\n\n\t\t\t// If the selector is sufficiently simple, try using a \"get*By*\" DOM method\n\t\t\t// (excepting DocumentFragment context, where the methods don't exist)\n\t\t\tif ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {\n\n\t\t\t\t// ID selector\n\t\t\t\tif ( (m = match[1]) ) {\n\n\t\t\t\t\t// Document context\n\t\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\t\tif ( (elem = context.getElementById( m )) ) {\n\n\t\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t// Element context\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\tif ( newContext && (elem = newContext.getElementById( m )) &&\n\t\t\t\t\t\t\tcontains( context, elem ) &&\n\t\t\t\t\t\t\telem.id === m ) {\n\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t// Type selector\n\t\t\t\t} else if ( match[2] ) {\n\t\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\t\treturn results;\n\n\t\t\t\t// Class selector\n\t\t\t\t} else if ( (m = match[3]) && support.getElementsByClassName &&\n\t\t\t\t\tcontext.getElementsByClassName ) {\n\n\t\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\t\treturn results;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Take advantage of querySelectorAll\n\t\t\tif ( support.qsa &&\n\t\t\t\t!nonnativeSelectorCache[ selector + \" \" ] &&\n\t\t\t\t(!rbuggyQSA || !rbuggyQSA.test( selector )) &&\n\n\t\t\t\t// Support: IE 8 only\n\t\t\t\t// Exclude object elements\n\t\t\t\t(nodeType !== 1 || context.nodeName.toLowerCase() !== \"object\") ) {\n\n\t\t\t\tnewSelector = selector;\n\t\t\t\tnewContext = context;\n\n\t\t\t\t// qSA considers elements outside a scoping root when evaluating child or\n\t\t\t\t// descendant combinators, which is not what we want.\n\t\t\t\t// In such cases, we work around the behavior by prefixing every selector in the\n\t\t\t\t// list with an ID selector referencing the scope context.\n\t\t\t\t// Thanks to Andrew Dupont for this technique.\n\t\t\t\tif ( nodeType === 1 && rdescend.test( selector ) ) {\n\n\t\t\t\t\t// Capture the context ID, setting it first if necessary\n\t\t\t\t\tif ( (nid = context.getAttribute( \"id\" )) ) {\n\t\t\t\t\t\tnid = nid.replace( rcssescape, fcssescape );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontext.setAttribute( \"id\", (nid = expando) );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prefix every selector in the list\n\t\t\t\t\tgroups = tokenize( selector );\n\t\t\t\t\ti = groups.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tgroups[i] = \"#\" + nid + \" \" + toSelector( groups[i] );\n\t\t\t\t\t}\n\t\t\t\t\tnewSelector = groups.join( \",\" );\n\n\t\t\t\t\t// Expand context for sibling selectors\n\t\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext;\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch ( qsaError ) {\n\t\t\t\t\tnonnativeSelectorCache( selector, true );\n\t\t\t\t} finally {\n\t\t\t\t\tif ( nid === expando ) {\n\t\t\t\t\t\tcontext.removeAttribute( \"id\" );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {function(string, object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn (cache[ key + \" \" ] = value);\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created element and returns a boolean result\n */\nfunction assert( fn ) {\n\tvar el = document.createElement(\"fieldset\");\n\n\ttry {\n\t\treturn !!fn( el );\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\t// Remove from its parent by default\n\t\tif ( el.parentNode ) {\n\t\t\tel.parentNode.removeChild( el );\n\t\t}\n\t\t// release memory in IE\n\t\tel = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split(\"|\"),\n\t\ti = arr.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[i] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\ta.sourceIndex - b.sourceIndex;\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( (cur = cur.nextSibling) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for :enabled/:disabled\n * @param {Boolean} disabled true for :disabled; false for :enabled\n */\nfunction createDisabledPseudo( disabled ) {\n\n\t// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable\n\treturn function( elem ) {\n\n\t\t// Only certain elements can match :enabled or :disabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled\n\t\tif ( \"form\" in elem ) {\n\n\t\t\t// Check for inherited disabledness on relevant non-disabled elements:\n\t\t\t// * listed form-associated elements in a disabled fieldset\n\t\t\t// https://html.spec.whatwg.org/multipage/forms.html#category-listed\n\t\t\t// https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled\n\t\t\t// * option elements in a disabled optgroup\n\t\t\t// https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled\n\t\t\t// All such elements have a \"form\" property.\n\t\t\tif ( elem.parentNode && elem.disabled === false ) {\n\n\t\t\t\t// Option elements defer to a parent optgroup if present\n\t\t\t\tif ( \"label\" in elem ) {\n\t\t\t\t\tif ( \"label\" in elem.parentNode ) {\n\t\t\t\t\t\treturn elem.parentNode.disabled === disabled;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn elem.disabled === disabled;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Support: IE 6 - 11\n\t\t\t\t// Use the isDisabled shortcut property to check for disabled fieldset ancestors\n\t\t\t\treturn elem.isDisabled === disabled ||\n\n\t\t\t\t\t// Where there is no isDisabled, check manually\n\t\t\t\t\t/* jshint -W018 */\n\t\t\t\t\telem.isDisabled !== !disabled &&\n\t\t\t\t\t\tinDisabledFieldset( elem ) === disabled;\n\t\t\t}\n\n\t\t\treturn elem.disabled === disabled;\n\n\t\t// Try to winnow out elements that can't be disabled before trusting the disabled property.\n\t\t// Some victims get caught in our net (label, legend, menu, track), but it shouldn't\n\t\t// even exist on them, let alone have a boolean value.\n\t\t} else if ( \"label\" in elem ) {\n\t\t\treturn elem.disabled === disabled;\n\t\t}\n\n\t\t// Remaining elements are neither :enabled nor :disabled\n\t\treturn false;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\tvar namespace = elem.namespaceURI,\n\t\tdocElem = (elem.ownerDocument || elem).documentElement;\n\n\t// Support: IE <=8\n\t// Assume HTML when documentElement doesn't yet exist, such as inside loading iframes\n\t// https://bugs.jquery.com/ticket/4833\n\treturn !rhtml.test( namespace || docElem && docElem.nodeName || \"HTML\" );\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, subWindow,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// Return early if doc is invalid or already selected\n\tif ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Update global variables\n\tdocument = doc;\n\tdocElem = document.documentElement;\n\tdocumentIsHTML = !isXML( document );\n\n\t// Support: IE 9-11, Edge\n\t// Accessing iframe documents after unload throws \"permission denied\" errors (jQuery #13936)\n\tif ( preferredDoc !== document &&\n\t\t(subWindow = document.defaultView) && subWindow.top !== subWindow ) {\n\n\t\t// Support: IE 11, Edge\n\t\tif ( subWindow.addEventListener ) {\n\t\t\tsubWindow.addEventListener( \"unload\", unloadHandler, false );\n\n\t\t// Support: IE 9 - 10 only\n\t\t} else if ( subWindow.attachEvent ) {\n\t\t\tsubWindow.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert(function( el ) {\n\t\tel.className = \"i\";\n\t\treturn !el.getAttribute(\"className\");\n\t});\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert(function( el ) {\n\t\tel.appendChild( document.createComment(\"\") );\n\t\treturn !el.getElementsByTagName(\"*\").length;\n\t});\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( document.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programmatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert(function( el ) {\n\t\tdocElem.appendChild( el ).id = expando;\n\t\treturn !document.getElementsByName || !document.getElementsByName( expando ).length;\n\t});\n\n\t// ID filter and find\n\tif ( support.getById ) {\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"id\") === attrId;\n\t\t\t};\n\t\t};\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar elem = context.getElementById( id );\n\t\t\t\treturn elem ? [ elem ] : [];\n\t\t\t}\n\t\t};\n\t} else {\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" &&\n\t\t\t\t\telem.getAttributeNode(\"id\");\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\n\t\t// Support: IE 6 - 7 only\n\t\t// getElementById is not reliable as a find shortcut\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar node, i, elems,\n\t\t\t\t\telem = context.getElementById( id );\n\n\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t// Verify the id attribute\n\t\t\t\t\tnode = elem.getAttributeNode(\"id\");\n\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t}\n\n\t\t\t\t\t// Fall back on getElementsByName\n\t\t\t\t\telems = context.getElementsByName( id );\n\t\t\t\t\ti = 0;\n\t\t\t\t\twhile ( (elem = elems[i++]) ) {\n\t\t\t\t\t\tnode = elem.getAttributeNode(\"id\");\n\t\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn [];\n\t\t\t}\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[\"TAG\"] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( (elem = results[i++]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( typeof context.getElementsByClassName !== \"undefined\" && documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See https://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( (support.qsa = rnative.test( document.querySelectorAll )) ) {\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert(function( el ) {\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// https://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( el ).innerHTML = \"\" +\n\t\t\t\t\"\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( el.querySelectorAll(\"[msallowcapture^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !el.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+\n\t\t\tif ( !el.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push(\"~=\");\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !el.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibling-combinator selector` fails\n\t\t\tif ( !el.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push(\".#.+[+~]\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( el ) {\n\t\t\tel.innerHTML = \"\" +\n\t\t\t\t\"\";\n\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = document.createElement(\"input\");\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tel.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( el.querySelectorAll(\"[name=d]\").length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( el.querySelectorAll(\":enabled\").length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Support: IE9-11+\n\t\t\t// IE's :disabled selector does not pick up the children of disabled fieldsets\n\t\t\tdocElem.appendChild( el ).disabled = true;\n\t\t\tif ( el.querySelectorAll(\":disabled\").length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tel.querySelectorAll(\"*,:x\");\n\t\t\trbuggyQSA.push(\",.*:\");\n\t\t});\n\t}\n\n\tif ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector) )) ) {\n\n\t\tassert(function( el ) {\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( el, \"*\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( el, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t});\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully self-exclusive\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t));\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( (b = b.parentNode) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\tcompare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\tif ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\t\t\treturn a === document ? -1 :\n\t\t\t\tb === document ? 1 :\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[i] === bp[i] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[i], bp[i] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\tap[i] === preferredDoc ? -1 :\n\t\t\tbp[i] === preferredDoc ? 1 :\n\t\t\t0;\n\t};\n\n\treturn document;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t!nonnativeSelectorCache[ expr + \" \" ] &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t// fragment in IE 9\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tnonnativeSelectorCache( expr, true );\n\t\t}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\t// Set document vars if needed\n\tif ( ( context.ownerDocument || context ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t(val = elem.getAttributeNode(name)) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.escape = function( sel ) {\n\treturn (sel + \"\").replace( rcssescape, fcssescape );\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( (elem = results[i++]) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( (node = elem[i++]) ) {\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[3] = ( match[3] || match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1].slice( 0, 3 ) === \"nth\" ) {\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[3] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n\t\t\t\tmatch[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\n\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[3] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[6] && match[2];\n\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[3] ) {\n\t\t\t\tmatch[2] = match[4] || match[5] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\tmatch[2] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() { return true; } :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== \"undefined\" && elem.getAttribute(\"class\") || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tvar cache, uniqueCache, outerCache, node, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType,\n\t\t\t\t\t\tdiff = false;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( (node = node[ dir ]) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) {\n\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\n\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\tnode = parent;\n\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\tdiff = nodeIndex && cache[ 2 ];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\t\tdiff = nodeIndex;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// xml :nth-child(...)\n\t\t\t\t\t\t\t// or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t\tif ( diff === false ) {\n\t\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t\tif ( ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) &&\n\t\t\t\t\t\t\t\t\t\t++diff ) {\n\n\t\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[0] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test(lang || \"\") ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( (elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": createDisabledPseudo( false ),\n\t\t\"disabled\": createDisabledPseudo( true ),\n\n\t\t\"checked\": function( elem ) {\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t// but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ?\n\t\t\t\targument + length :\n\t\t\t\targument > length ?\n\t\t\t\t\tlength :\n\t\t\t\t\targument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( (tokens = []) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push({\n\t\t\t\tvalue: matched,\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[0].replace( rtrim, \" \" )\n\t\t\t});\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push({\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t});\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[i].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tskip = combinator.next,\n\t\tkey = skip || dir,\n\t\tcheckNonElements = base && key === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, uniqueCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || (elem[ expando ] = {});\n\n\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\tuniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});\n\n\t\t\t\t\t\tif ( skip && skip === elem.nodeName.toLowerCase() ) {\n\t\t\t\t\t\t\telem = elem[ dir ] || elem;\n\t\t\t\t\t\t} else if ( (oldCache = uniqueCache[ key ]) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn (newCache[ 2 ] = oldCache[ 2 ]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\tuniqueCache[ key ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\t\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\t\ttokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", outermost ),\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context === document || context || outermost;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: ) matching elements by id\n\t\t\tfor ( ; i !== len && (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\tif ( !context && elem.ownerDocument !== document ) {\n\t\t\t\t\t\tsetDocument( elem );\n\t\t\t\t\t\txml = !documentIsHTML;\n\t\t\t\t\t}\n\t\t\t\t\twhile ( (matcher = elementMatchers[j++]) ) {\n\t\t\t\t\t\tif ( matcher( elem, context || document, xml) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// `i` is now the count of elements visited above, and adding it to `matchedCount`\n\t\t\t// makes the latter nonnegative.\n\t\t\tmatchedCount += i;\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\t// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`\n\t\t\t// equals `i`), unless we didn't visit _any_ elements in the above loop because we have\n\t\t\t// no element matchers and no seed.\n\t\t\t// Incrementing an initially-string \"0\" `i` allows `i` to remain a string only in that\n\t\t\t// case, which will result in a \"00\" `matchedCount` that differs from `i` but is also\n\t\t\t// numerically zero.\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (matcher = setMatchers[j++]) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n * selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n * selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( (selector = compiled.selector || selector) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is only one selector in the list and no seed\n\t// (the latter of which guarantees us context)\n\tif ( match.length === 1 ) {\n\n\t\t// Reduce context if the leading compound selector is an ID\n\t\ttokens = match[0] = match[0].slice( 0 );\n\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\tcontext.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {\n\n\t\t\tcontext = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[i];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( (seed = find(\n\t\t\t\t\ttoken.matches[0].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context\n\t\t\t\t)) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\t!context || rsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert(function( el ) {\n\t// Should return 1, but returns 4 (following)\n\treturn el.compareDocumentPosition( document.createElement(\"fieldset\") ) & 1;\n});\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert(function( el ) {\n\tel.innerHTML = \"\";\n\treturn el.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert(function( el ) {\n\tel.innerHTML = \"\";\n\tel.firstChild.setAttribute( \"value\", \"\" );\n\treturn el.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n\taddHandle( \"value\", function( elem, name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert(function( el ) {\n\treturn el.getAttribute(\"disabled\") == null;\n}) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t\t(val = elem.getAttributeNode( name )) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\tnull;\n\t\t}\n\t});\n}\n\nreturn Sizzle;\n\n})( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\n\n// Deprecated\njQuery.expr[ \":\" ] = jQuery.expr.pseudos;\njQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\njQuery.escapeSelector = Sizzle.escape;\n\n\n\n\nvar dir = function( elem, dir, until ) {\n\tvar matched = [],\n\t\ttruncate = until !== undefined;\n\n\twhile ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {\n\t\tif ( elem.nodeType === 1 ) {\n\t\t\tif ( truncate && jQuery( elem ).is( until ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmatched.push( elem );\n\t\t}\n\t}\n\treturn matched;\n};\n\n\nvar siblings = function( n, elem ) {\n\tvar matched = [];\n\n\tfor ( ; n; n = n.nextSibling ) {\n\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\tmatched.push( n );\n\t\t}\n\t}\n\n\treturn matched;\n};\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\n\n\nfunction nodeName( elem, name ) {\n\n return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\n};\nvar rsingleTag = ( /^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i );\n\n\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t} );\n\t}\n\n\t// Single element\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t} );\n\t}\n\n\t// Arraylike of elements (jQuery, arguments, Array)\n\tif ( typeof qualifier !== \"string\" ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( indexOf.call( qualifier, elem ) > -1 ) !== not;\n\t\t} );\n\t}\n\n\t// Filtered directly for both simple and complex selectors\n\treturn jQuery.filter( qualifier, elements, not );\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\tif ( elems.length === 1 && elem.nodeType === 1 ) {\n\t\treturn jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];\n\t}\n\n\treturn jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\treturn elem.nodeType === 1;\n\t} ) );\n};\n\njQuery.fn.extend( {\n\tfind: function( selector ) {\n\t\tvar i, ret,\n\t\t\tlen = this.length,\n\t\t\tself = this;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter( function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} ) );\n\t\t}\n\n\t\tret = this.pushStack( [] );\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\treturn len > 1 ? jQuery.uniqueSort( ret ) : ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], false ) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], true ) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n} );\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\t// Shortcut simple #id case for speed\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,\n\n\tinit = jQuery.fn.init = function( selector, context, root ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Method init() accepts an alternate rootjQuery\n\t\t// so migrate can support jQuery.sub (gh-2101)\n\t\troot = root || rootjQuery;\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector[ 0 ] === \"<\" &&\n\t\t\t\tselector[ selector.length - 1 ] === \">\" &&\n\t\t\t\tselector.length >= 3 ) {\n\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && ( match[ 1 ] || !context ) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[ 1 ] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[ 0 ] : context;\n\n\t\t\t\t\t// Option to run scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[ 1 ],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[ 2 ] );\n\n\t\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t\t// Inject the element directly into the jQuery object\n\t\t\t\t\t\tthis[ 0 ] = elem;\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || root ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis[ 0 ] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( isFunction( selector ) ) {\n\t\t\treturn root.ready !== undefined ?\n\t\t\t\troot.ready( selector ) :\n\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\n\t// Methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend( {\n\thas: function( target ) {\n\t\tvar targets = jQuery( target, this ),\n\t\t\tl = targets.length;\n\n\t\treturn this.filter( function() {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[ i ] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\ttargets = typeof selectors !== \"string\" && jQuery( selectors );\n\n\t\t// Positional selectors never match, since there's no _selection_ context\n\t\tif ( !rneedsContext.test( selectors ) ) {\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tfor ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {\n\n\t\t\t\t\t// Always skip document fragments\n\t\t\t\t\tif ( cur.nodeType < 11 && ( targets ?\n\t\t\t\t\t\ttargets.index( cur ) > -1 :\n\n\t\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\t\tjQuery.find.matchesSelector( cur, selectors ) ) ) {\n\n\t\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within the set\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// Index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn indexOf.call( jQuery( elem ), this[ 0 ] );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn indexOf.call( this,\n\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[ 0 ] : elem\n\t\t);\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.uniqueSort(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t}\n} );\n\nfunction sibling( cur, dir ) {\n\twhile ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}\n\treturn cur;\n}\n\njQuery.each( {\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn siblings( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn siblings( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\tif ( typeof elem.contentDocument !== \"undefined\" ) {\n\t\t\treturn elem.contentDocument;\n\t\t}\n\n\t\t// Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only\n\t\t// Treat the template element as a regular one in browsers that\n\t\t// don't support it.\n\t\tif ( nodeName( elem, \"template\" ) ) {\n\t\t\telem = elem.content || elem;\n\t\t}\n\n\t\treturn jQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar matched = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tmatched = jQuery.filter( selector, matched );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tjQuery.uniqueSort( matched );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tmatched.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched );\n\t};\n} );\nvar rnothtmlwhite = ( /[^\\x20\\t\\r\\n\\f]+/g );\n\n\n\n// Convert String-formatted options into Object-formatted ones\nfunction createOptions( options ) {\n\tvar object = {};\n\tjQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t} );\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\tcreateOptions( options ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\n\t\t// Last fire value for non-forgettable lists\n\t\tmemory,\n\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\n\t\t// Flag to prevent firing\n\t\tlocked,\n\n\t\t// Actual callback list\n\t\tlist = [],\n\n\t\t// Queue of execution data for repeatable lists\n\t\tqueue = [],\n\n\t\t// Index of currently firing callback (modified by add/remove as needed)\n\t\tfiringIndex = -1,\n\n\t\t// Fire callbacks\n\t\tfire = function() {\n\n\t\t\t// Enforce single-firing\n\t\t\tlocked = locked || options.once;\n\n\t\t\t// Execute callbacks for all pending executions,\n\t\t\t// respecting firingIndex overrides and runtime changes\n\t\t\tfired = firing = true;\n\t\t\tfor ( ; queue.length; firingIndex = -1 ) {\n\t\t\t\tmemory = queue.shift();\n\t\t\t\twhile ( ++firingIndex < list.length ) {\n\n\t\t\t\t\t// Run callback and check for early termination\n\t\t\t\t\tif ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&\n\t\t\t\t\t\toptions.stopOnFalse ) {\n\n\t\t\t\t\t\t// Jump to end and forget the data so .add doesn't re-fire\n\t\t\t\t\t\tfiringIndex = list.length;\n\t\t\t\t\t\tmemory = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Forget the data if we're done with it\n\t\t\tif ( !options.memory ) {\n\t\t\t\tmemory = false;\n\t\t\t}\n\n\t\t\tfiring = false;\n\n\t\t\t// Clean up if we're done firing for good\n\t\t\tif ( locked ) {\n\n\t\t\t\t// Keep an empty list if we have data for future add calls\n\t\t\t\tif ( memory ) {\n\t\t\t\t\tlist = [];\n\n\t\t\t\t// Otherwise, this object is spent\n\t\t\t\t} else {\n\t\t\t\t\tlist = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t// Actual Callbacks object\n\t\tself = {\n\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\n\t\t\t\t\t// If we have memory from a past run, we should fire after adding\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfiringIndex = list.length - 1;\n\t\t\t\t\t\tqueue.push( memory );\n\t\t\t\t\t}\n\n\t\t\t\t\t( function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tif ( isFunction( arg ) ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && toType( arg ) !== \"string\" ) {\n\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t} )( arguments );\n\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\tvar index;\n\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\tlist.splice( index, 1 );\n\n\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ?\n\t\t\t\t\tjQuery.inArray( fn, list ) > -1 :\n\t\t\t\t\tlist.length > 0;\n\t\t\t},\n\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Disable .fire and .add\n\t\t\t// Abort any current/pending executions\n\t\t\t// Clear all callbacks and values\n\t\t\tdisable: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tlist = memory = \"\";\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\n\t\t\t// Disable .fire\n\t\t\t// Also disable .add unless we have memory (since it would have no effect)\n\t\t\t// Abort any pending executions\n\t\t\tlock: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tif ( !memory && !firing ) {\n\t\t\t\t\tlist = memory = \"\";\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tlocked: function() {\n\t\t\t\treturn !!locked;\n\t\t\t},\n\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( !locked ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tqueue.push( args );\n\t\t\t\t\tif ( !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\nfunction Identity( v ) {\n\treturn v;\n}\nfunction Thrower( ex ) {\n\tthrow ex;\n}\n\nfunction adoptValue( value, resolve, reject, noValue ) {\n\tvar method;\n\n\ttry {\n\n\t\t// Check for promise aspect first to privilege synchronous behavior\n\t\tif ( value && isFunction( ( method = value.promise ) ) ) {\n\t\t\tmethod.call( value ).done( resolve ).fail( reject );\n\n\t\t// Other thenables\n\t\t} else if ( value && isFunction( ( method = value.then ) ) ) {\n\t\t\tmethod.call( value, resolve, reject );\n\n\t\t// Other non-thenables\n\t\t} else {\n\n\t\t\t// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:\n\t\t\t// * false: [ value ].slice( 0 ) => resolve( value )\n\t\t\t// * true: [ value ].slice( 1 ) => resolve()\n\t\t\tresolve.apply( undefined, [ value ].slice( noValue ) );\n\t\t}\n\n\t// For Promises/A+, convert exceptions into rejections\n\t// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in\n\t// Deferred#then to conditionally suppress rejection.\n\t} catch ( value ) {\n\n\t\t// Support: Android 4.0 only\n\t\t// Strict mode functions invoked without .call/.apply get global-object context\n\t\treject.apply( undefined, [ value ] );\n\t}\n}\n\njQuery.extend( {\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\n\t\t\t\t// action, add listener, callbacks,\n\t\t\t\t// ... .then handlers, argument index, [final state]\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks( \"memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"memory\" ), 2 ],\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 0, \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 1, \"rejected\" ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\t\"catch\": function( fn ) {\n\t\t\t\t\treturn promise.then( null, fn );\n\t\t\t\t},\n\n\t\t\t\t// Keep pipe for back-compat\n\t\t\t\tpipe: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\n\t\t\t\t\t\t\t// Map tuples (progress, done, fail) to arguments (done, fail, progress)\n\t\t\t\t\t\t\tvar fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];\n\n\t\t\t\t\t\t\t// deferred.progress(function() { bind to newDefer or newDefer.notify })\n\t\t\t\t\t\t\t// deferred.done(function() { bind to newDefer or newDefer.resolve })\n\t\t\t\t\t\t\t// deferred.fail(function() { bind to newDefer or newDefer.reject })\n\t\t\t\t\t\t\tdeferred[ tuple[ 1 ] ]( function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify )\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ](\n\t\t\t\t\t\t\t\t\t\tthis,\n\t\t\t\t\t\t\t\t\t\tfn ? [ returned ] : arguments\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} );\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\t\t\t\tthen: function( onFulfilled, onRejected, onProgress ) {\n\t\t\t\t\tvar maxDepth = 0;\n\t\t\t\t\tfunction resolve( depth, deferred, handler, special ) {\n\t\t\t\t\t\treturn function() {\n\t\t\t\t\t\t\tvar that = this,\n\t\t\t\t\t\t\t\targs = arguments,\n\t\t\t\t\t\t\t\tmightThrow = function() {\n\t\t\t\t\t\t\t\t\tvar returned, then;\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.3\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-59\n\t\t\t\t\t\t\t\t\t// Ignore double-resolution attempts\n\t\t\t\t\t\t\t\t\tif ( depth < maxDepth ) {\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturned = handler.apply( that, args );\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.1\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-48\n\t\t\t\t\t\t\t\t\tif ( returned === deferred.promise() ) {\n\t\t\t\t\t\t\t\t\t\tthrow new TypeError( \"Thenable self-resolution\" );\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ sections 2.3.3.1, 3.5\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-54\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-75\n\t\t\t\t\t\t\t\t\t// Retrieve `then` only once\n\t\t\t\t\t\t\t\t\tthen = returned &&\n\n\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.4\n\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-64\n\t\t\t\t\t\t\t\t\t\t// Only check objects and functions for thenability\n\t\t\t\t\t\t\t\t\t\t( typeof returned === \"object\" ||\n\t\t\t\t\t\t\t\t\t\t\ttypeof returned === \"function\" ) &&\n\t\t\t\t\t\t\t\t\t\treturned.then;\n\n\t\t\t\t\t\t\t\t\t// Handle a returned thenable\n\t\t\t\t\t\t\t\t\tif ( isFunction( then ) ) {\n\n\t\t\t\t\t\t\t\t\t\t// Special processors (notify) just wait for resolution\n\t\t\t\t\t\t\t\t\t\tif ( special ) {\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special )\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t// Normal processors (resolve) also hook into progress\n\t\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t\t// ...and disregard older resolution values\n\t\t\t\t\t\t\t\t\t\t\tmaxDepth++;\n\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdeferred.notifyWith )\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Handle all other returned values\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\tif ( handler !== Identity ) {\n\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\targs = [ returned ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t// Process the value(s)\n\t\t\t\t\t\t\t\t\t\t// Default process is resolve\n\t\t\t\t\t\t\t\t\t\t( special || deferred.resolveWith )( that, args );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\n\t\t\t\t\t\t\t\t// Only normal processors (resolve) catch and reject exceptions\n\t\t\t\t\t\t\t\tprocess = special ?\n\t\t\t\t\t\t\t\t\tmightThrow :\n\t\t\t\t\t\t\t\t\tfunction() {\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tmightThrow();\n\t\t\t\t\t\t\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t\t\t\t\t\t\tif ( jQuery.Deferred.exceptionHook ) {\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery.Deferred.exceptionHook( e,\n\t\t\t\t\t\t\t\t\t\t\t\t\tprocess.stackTrace );\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.4.1\n\t\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-61\n\t\t\t\t\t\t\t\t\t\t\t// Ignore post-resolution exceptions\n\t\t\t\t\t\t\t\t\t\t\tif ( depth + 1 >= maxDepth ) {\n\n\t\t\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\t\t\tif ( handler !== Thrower ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\t\t\targs = [ e ];\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\tdeferred.rejectWith( that, args );\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.1\n\t\t\t\t\t\t\t// https://promisesaplus.com/#point-57\n\t\t\t\t\t\t\t// Re-resolve promises immediately to dodge false rejection from\n\t\t\t\t\t\t\t// subsequent errors\n\t\t\t\t\t\t\tif ( depth ) {\n\t\t\t\t\t\t\t\tprocess();\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// Call an optional hook to record the stack, in case of exception\n\t\t\t\t\t\t\t\t// since it's otherwise lost when execution goes async\n\t\t\t\t\t\t\t\tif ( jQuery.Deferred.getStackHook ) {\n\t\t\t\t\t\t\t\t\tprocess.stackTrace = jQuery.Deferred.getStackHook();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\twindow.setTimeout( process );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\n\t\t\t\t\t\t// progress_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 0 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onProgress ) ?\n\t\t\t\t\t\t\t\t\tonProgress :\n\t\t\t\t\t\t\t\t\tIdentity,\n\t\t\t\t\t\t\t\tnewDefer.notifyWith\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// fulfilled_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 1 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onFulfilled ) ?\n\t\t\t\t\t\t\t\t\tonFulfilled :\n\t\t\t\t\t\t\t\t\tIdentity\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// rejected_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 2 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onRejected ) ?\n\t\t\t\t\t\t\t\t\tonRejected :\n\t\t\t\t\t\t\t\t\tThrower\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 5 ];\n\n\t\t\t// promise.progress = list.add\n\t\t\t// promise.done = list.add\n\t\t\t// promise.fail = list.add\n\t\t\tpromise[ tuple[ 1 ] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(\n\t\t\t\t\tfunction() {\n\n\t\t\t\t\t\t// state = \"resolved\" (i.e., fulfilled)\n\t\t\t\t\t\t// state = \"rejected\"\n\t\t\t\t\t\tstate = stateString;\n\t\t\t\t\t},\n\n\t\t\t\t\t// rejected_callbacks.disable\n\t\t\t\t\t// fulfilled_callbacks.disable\n\t\t\t\t\ttuples[ 3 - i ][ 2 ].disable,\n\n\t\t\t\t\t// rejected_handlers.disable\n\t\t\t\t\t// fulfilled_handlers.disable\n\t\t\t\t\ttuples[ 3 - i ][ 3 ].disable,\n\n\t\t\t\t\t// progress_callbacks.lock\n\t\t\t\t\ttuples[ 0 ][ 2 ].lock,\n\n\t\t\t\t\t// progress_handlers.lock\n\t\t\t\t\ttuples[ 0 ][ 3 ].lock\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// progress_handlers.fire\n\t\t\t// fulfilled_handlers.fire\n\t\t\t// rejected_handlers.fire\n\t\t\tlist.add( tuple[ 3 ].fire );\n\n\t\t\t// deferred.notify = function() { deferred.notifyWith(...) }\n\t\t\t// deferred.resolve = function() { deferred.resolveWith(...) }\n\t\t\t// deferred.reject = function() { deferred.rejectWith(...) }\n\t\t\tdeferred[ tuple[ 0 ] ] = function() {\n\t\t\t\tdeferred[ tuple[ 0 ] + \"With\" ]( this === deferred ? undefined : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\n\t\t\t// deferred.notifyWith = list.fireWith\n\t\t\t// deferred.resolveWith = list.fireWith\n\t\t\t// deferred.rejectWith = list.fireWith\n\t\t\tdeferred[ tuple[ 0 ] + \"With\" ] = list.fireWith;\n\t\t} );\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( singleValue ) {\n\t\tvar\n\n\t\t\t// count of uncompleted subordinates\n\t\t\tremaining = arguments.length,\n\n\t\t\t// count of unprocessed arguments\n\t\t\ti = remaining,\n\n\t\t\t// subordinate fulfillment data\n\t\t\tresolveContexts = Array( i ),\n\t\t\tresolveValues = slice.call( arguments ),\n\n\t\t\t// the master Deferred\n\t\t\tmaster = jQuery.Deferred(),\n\n\t\t\t// subordinate callback factory\n\t\t\tupdateFunc = function( i ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tresolveContexts[ i ] = this;\n\t\t\t\t\tresolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( !( --remaining ) ) {\n\t\t\t\t\t\tmaster.resolveWith( resolveContexts, resolveValues );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t};\n\n\t\t// Single- and empty arguments are adopted like Promise.resolve\n\t\tif ( remaining <= 1 ) {\n\t\t\tadoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,\n\t\t\t\t!remaining );\n\n\t\t\t// Use .then() to unwrap secondary thenables (cf. gh-3000)\n\t\t\tif ( master.state() === \"pending\" ||\n\t\t\t\tisFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {\n\n\t\t\t\treturn master.then();\n\t\t\t}\n\t\t}\n\n\t\t// Multiple arguments are aggregated like Promise.all array elements\n\t\twhile ( i-- ) {\n\t\t\tadoptValue( resolveValues[ i ], updateFunc( i ), master.reject );\n\t\t}\n\n\t\treturn master.promise();\n\t}\n} );\n\n\n// These usually indicate a programmer mistake during development,\n// warn about them ASAP rather than swallowing them by default.\nvar rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;\n\njQuery.Deferred.exceptionHook = function( error, stack ) {\n\n\t// Support: IE 8 - 9 only\n\t// Console exists when dev tools are open, which can happen at any time\n\tif ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {\n\t\twindow.console.warn( \"jQuery.Deferred exception: \" + error.message, error.stack, stack );\n\t}\n};\n\n\n\n\njQuery.readyException = function( error ) {\n\twindow.setTimeout( function() {\n\t\tthrow error;\n\t} );\n};\n\n\n\n\n// The deferred used on DOM ready\nvar readyList = jQuery.Deferred();\n\njQuery.fn.ready = function( fn ) {\n\n\treadyList\n\t\t.then( fn )\n\n\t\t// Wrap jQuery.readyException in a function so that the lookup\n\t\t// happens at the time of error handling instead of callback\n\t\t// registration.\n\t\t.catch( function( error ) {\n\t\t\tjQuery.readyException( error );\n\t\t} );\n\n\treturn this;\n};\n\njQuery.extend( {\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\t}\n} );\n\njQuery.ready.then = readyList.then;\n\n// The ready event handler and self cleanup method\nfunction completed() {\n\tdocument.removeEventListener( \"DOMContentLoaded\", completed );\n\twindow.removeEventListener( \"load\", completed );\n\tjQuery.ready();\n}\n\n// Catch cases where $(document).ready() is called\n// after the browser event has already occurred.\n// Support: IE <=9 - 10 only\n// Older IE sometimes signals \"interactive\" too soon\nif ( document.readyState === \"complete\" ||\n\t( document.readyState !== \"loading\" && !document.documentElement.doScroll ) ) {\n\n\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\twindow.setTimeout( jQuery.ready );\n\n} else {\n\n\t// Use the handy event callback\n\tdocument.addEventListener( \"DOMContentLoaded\", completed );\n\n\t// A fallback to window.onload, that will always work\n\twindow.addEventListener( \"load\", completed );\n}\n\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlen = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( toType( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\taccess( elems, fn, i, key[ i ], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\tfn(\n\t\t\t\t\telems[ i ], key, raw ?\n\t\t\t\t\tvalue :\n\t\t\t\t\tvalue.call( elems[ i ], i, fn( elems[ i ], key ) )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( chainable ) {\n\t\treturn elems;\n\t}\n\n\t// Gets\n\tif ( bulk ) {\n\t\treturn fn.call( elems );\n\t}\n\n\treturn len ? fn( elems[ 0 ], key ) : emptyGet;\n};\n\n\n// Matches dashed string for camelizing\nvar rmsPrefix = /^-ms-/,\n\trdashAlpha = /-([a-z])/g;\n\n// Used by camelCase as callback to replace()\nfunction fcamelCase( all, letter ) {\n\treturn letter.toUpperCase();\n}\n\n// Convert dashed to camelCase; used by the css and data modules\n// Support: IE <=9 - 11, Edge 12 - 15\n// Microsoft forgot to hump their vendor prefix (#9572)\nfunction camelCase( string ) {\n\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n}\nvar acceptData = function( owner ) {\n\n\t// Accepts only:\n\t// - Node\n\t// - Node.ELEMENT_NODE\n\t// - Node.DOCUMENT_NODE\n\t// - Object\n\t// - Any\n\treturn owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );\n};\n\n\n\n\nfunction Data() {\n\tthis.expando = jQuery.expando + Data.uid++;\n}\n\nData.uid = 1;\n\nData.prototype = {\n\n\tcache: function( owner ) {\n\n\t\t// Check if the owner object already has a cache\n\t\tvar value = owner[ this.expando ];\n\n\t\t// If not, create one\n\t\tif ( !value ) {\n\t\t\tvalue = {};\n\n\t\t\t// We can accept data for non-element nodes in modern browsers,\n\t\t\t// but we should not, see #8335.\n\t\t\t// Always return an empty object.\n\t\t\tif ( acceptData( owner ) ) {\n\n\t\t\t\t// If it is a node unlikely to be stringify-ed or looped over\n\t\t\t\t// use plain assignment\n\t\t\t\tif ( owner.nodeType ) {\n\t\t\t\t\towner[ this.expando ] = value;\n\n\t\t\t\t// Otherwise secure it in a non-enumerable property\n\t\t\t\t// configurable must be true to allow the property to be\n\t\t\t\t// deleted when data is removed\n\t\t\t\t} else {\n\t\t\t\t\tObject.defineProperty( owner, this.expando, {\n\t\t\t\t\t\tvalue: value,\n\t\t\t\t\t\tconfigurable: true\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn value;\n\t},\n\tset: function( owner, data, value ) {\n\t\tvar prop,\n\t\t\tcache = this.cache( owner );\n\n\t\t// Handle: [ owner, key, value ] args\n\t\t// Always use camelCase key (gh-2257)\n\t\tif ( typeof data === \"string\" ) {\n\t\t\tcache[ camelCase( data ) ] = value;\n\n\t\t// Handle: [ owner, { properties } ] args\n\t\t} else {\n\n\t\t\t// Copy the properties one-by-one to the cache object\n\t\t\tfor ( prop in data ) {\n\t\t\t\tcache[ camelCase( prop ) ] = data[ prop ];\n\t\t\t}\n\t\t}\n\t\treturn cache;\n\t},\n\tget: function( owner, key ) {\n\t\treturn key === undefined ?\n\t\t\tthis.cache( owner ) :\n\n\t\t\t// Always use camelCase key (gh-2257)\n\t\t\towner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];\n\t},\n\taccess: function( owner, key, value ) {\n\n\t\t// In cases where either:\n\t\t//\n\t\t// 1. No key was specified\n\t\t// 2. A string key was specified, but no value provided\n\t\t//\n\t\t// Take the \"read\" path and allow the get method to determine\n\t\t// which value to return, respectively either:\n\t\t//\n\t\t// 1. The entire cache object\n\t\t// 2. The data stored at the key\n\t\t//\n\t\tif ( key === undefined ||\n\t\t\t\t( ( key && typeof key === \"string\" ) && value === undefined ) ) {\n\n\t\t\treturn this.get( owner, key );\n\t\t}\n\n\t\t// When the key is not a string, or both a key and value\n\t\t// are specified, set or extend (existing objects) with either:\n\t\t//\n\t\t// 1. An object of properties\n\t\t// 2. A key and value\n\t\t//\n\t\tthis.set( owner, key, value );\n\n\t\t// Since the \"set\" path can have two possible entry points\n\t\t// return the expected data based on which path was taken[*]\n\t\treturn value !== undefined ? value : key;\n\t},\n\tremove: function( owner, key ) {\n\t\tvar i,\n\t\t\tcache = owner[ this.expando ];\n\n\t\tif ( cache === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key !== undefined ) {\n\n\t\t\t// Support array or space separated string of keys\n\t\t\tif ( Array.isArray( key ) ) {\n\n\t\t\t\t// If key is an array of keys...\n\t\t\t\t// We always set camelCase keys, so remove that.\n\t\t\t\tkey = key.map( camelCase );\n\t\t\t} else {\n\t\t\t\tkey = camelCase( key );\n\n\t\t\t\t// If a key with the spaces exists, use it.\n\t\t\t\t// Otherwise, create an array by matching non-whitespace\n\t\t\t\tkey = key in cache ?\n\t\t\t\t\t[ key ] :\n\t\t\t\t\t( key.match( rnothtmlwhite ) || [] );\n\t\t\t}\n\n\t\t\ti = key.length;\n\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete cache[ key[ i ] ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if there's no more data\n\t\tif ( key === undefined || jQuery.isEmptyObject( cache ) ) {\n\n\t\t\t// Support: Chrome <=35 - 45\n\t\t\t// Webkit & Blink performance suffers when deleting properties\n\t\t\t// from DOM nodes, so set to undefined instead\n\t\t\t// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)\n\t\t\tif ( owner.nodeType ) {\n\t\t\t\towner[ this.expando ] = undefined;\n\t\t\t} else {\n\t\t\t\tdelete owner[ this.expando ];\n\t\t\t}\n\t\t}\n\t},\n\thasData: function( owner ) {\n\t\tvar cache = owner[ this.expando ];\n\t\treturn cache !== undefined && !jQuery.isEmptyObject( cache );\n\t}\n};\nvar dataPriv = new Data();\n\nvar dataUser = new Data();\n\n\n\n//\tImplementation Summary\n//\n//\t1. Enforce API surface and semantic compatibility with 1.9.x branch\n//\t2. Improve the module's maintainability by reducing the storage\n//\t\tpaths to a single mechanism.\n//\t3. Use the same single mechanism to support \"private\" and \"user\" data.\n//\t4. _Never_ expose \"private\" data to user code (TODO: Drop _data, _removeData)\n//\t5. Avoid exposing implementation details on user objects (eg. expando properties)\n//\t6. Provide a clear path for implementation upgrade to WeakMap in 2014\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /[A-Z]/g;\n\nfunction getData( data ) {\n\tif ( data === \"true\" ) {\n\t\treturn true;\n\t}\n\n\tif ( data === \"false\" ) {\n\t\treturn false;\n\t}\n\n\tif ( data === \"null\" ) {\n\t\treturn null;\n\t}\n\n\t// Only convert to a number if it doesn't change the string\n\tif ( data === +data + \"\" ) {\n\t\treturn +data;\n\t}\n\n\tif ( rbrace.test( data ) ) {\n\t\treturn JSON.parse( data );\n\t}\n\n\treturn data;\n}\n\nfunction dataAttr( elem, key, data ) {\n\tvar name;\n\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\t\tname = \"data-\" + key.replace( rmultiDash, \"-$&\" ).toLowerCase();\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = getData( data );\n\t\t\t} catch ( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tdataUser.set( elem, key, data );\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\treturn data;\n}\n\njQuery.extend( {\n\thasData: function( elem ) {\n\t\treturn dataUser.hasData( elem ) || dataPriv.hasData( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn dataUser.access( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\tdataUser.remove( elem, name );\n\t},\n\n\t// TODO: Now that all calls to _data and _removeData have been replaced\n\t// with direct calls to dataPriv methods, these can be deprecated.\n\t_data: function( elem, name, data ) {\n\t\treturn dataPriv.access( elem, name, data );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\tdataPriv.remove( elem, name );\n\t}\n} );\n\njQuery.fn.extend( {\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[ 0 ],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = dataUser.get( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !dataPriv.get( elem, \"hasDataAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE 11 only\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = camelCase( name.slice( 5 ) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdataPriv.set( elem, \"hasDataAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each( function() {\n\t\t\t\tdataUser.set( this, key );\n\t\t\t} );\n\t\t}\n\n\t\treturn access( this, function( value ) {\n\t\t\tvar data;\n\n\t\t\t// The calling jQuery object (element matches) is not empty\n\t\t\t// (and therefore has an element appears at this[ 0 ]) and the\n\t\t\t// `value` parameter was not undefined. An empty jQuery object\n\t\t\t// will result in `undefined` for elem = this[ 0 ] which will\n\t\t\t// throw an exception if an attempt to read a data cache is made.\n\t\t\tif ( elem && value === undefined ) {\n\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// The key will always be camelCased in Data\n\t\t\t\tdata = dataUser.get( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// Attempt to \"discover\" the data in\n\t\t\t\t// HTML5 custom data-* attrs\n\t\t\t\tdata = dataAttr( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// We tried really hard, but the data doesn't exist.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set the data...\n\t\t\tthis.each( function() {\n\n\t\t\t\t// We always store the camelCased key\n\t\t\t\tdataUser.set( this, key, value );\n\t\t\t} );\n\t\t}, null, value, arguments.length > 1, null, true );\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each( function() {\n\t\t\tdataUser.remove( this, key );\n\t\t} );\n\t}\n} );\n\n\njQuery.extend( {\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = dataPriv.get( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || Array.isArray( data ) ) {\n\t\t\t\t\tqueue = dataPriv.access( elem, type, jQuery.makeArray( data ) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// Clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// Not public - generate a queueHooks object, or return the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn dataPriv.get( elem, key ) || dataPriv.access( elem, key, {\n\t\t\tempty: jQuery.Callbacks( \"once memory\" ).add( function() {\n\t\t\t\tdataPriv.remove( elem, [ type + \"queue\", key ] );\n\t\t\t} )\n\t\t} );\n\t}\n} );\n\njQuery.fn.extend( {\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[ 0 ], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each( function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// Ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[ 0 ] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t} );\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t} );\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = dataPriv.get( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n} );\nvar pnum = ( /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/ ).source;\n\nvar rcssNum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" );\n\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar documentElement = document.documentElement;\n\n\n\n\tvar isAttached = function( elem ) {\n\t\t\treturn jQuery.contains( elem.ownerDocument, elem );\n\t\t},\n\t\tcomposed = { composed: true };\n\n\t// Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only\n\t// Check attachment across shadow DOM boundaries when possible (gh-3504)\n\t// Support: iOS 10.0-10.2 only\n\t// Early iOS 10 versions support `attachShadow` but not `getRootNode`,\n\t// leading to errors. We need to check for `getRootNode`.\n\tif ( documentElement.getRootNode ) {\n\t\tisAttached = function( elem ) {\n\t\t\treturn jQuery.contains( elem.ownerDocument, elem ) ||\n\t\t\t\telem.getRootNode( composed ) === elem.ownerDocument;\n\t\t};\n\t}\nvar isHiddenWithinTree = function( elem, el ) {\n\n\t\t// isHiddenWithinTree might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\n\t\t// Inline style trumps all\n\t\treturn elem.style.display === \"none\" ||\n\t\t\telem.style.display === \"\" &&\n\n\t\t\t// Otherwise, check computed style\n\t\t\t// Support: Firefox <=43 - 45\n\t\t\t// Disconnected elements can have computed display: none, so first confirm that elem is\n\t\t\t// in the document.\n\t\t\tisAttached( elem ) &&\n\n\t\t\tjQuery.css( elem, \"display\" ) === \"none\";\n\t};\n\nvar swap = function( elem, options, callback, args ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.apply( elem, args || [] );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\n\n\nfunction adjustCSS( elem, prop, valueParts, tween ) {\n\tvar adjusted, scale,\n\t\tmaxIterations = 20,\n\t\tcurrentValue = tween ?\n\t\t\tfunction() {\n\t\t\t\treturn tween.cur();\n\t\t\t} :\n\t\t\tfunction() {\n\t\t\t\treturn jQuery.css( elem, prop, \"\" );\n\t\t\t},\n\t\tinitial = currentValue(),\n\t\tunit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t// Starting value computation is required for potential unit mismatches\n\t\tinitialInUnit = elem.nodeType &&\n\t\t\t( jQuery.cssNumber[ prop ] || unit !== \"px\" && +initial ) &&\n\t\t\trcssNum.exec( jQuery.css( elem, prop ) );\n\n\tif ( initialInUnit && initialInUnit[ 3 ] !== unit ) {\n\n\t\t// Support: Firefox <=54\n\t\t// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)\n\t\tinitial = initial / 2;\n\n\t\t// Trust units reported by jQuery.css\n\t\tunit = unit || initialInUnit[ 3 ];\n\n\t\t// Iteratively approximate from a nonzero starting point\n\t\tinitialInUnit = +initial || 1;\n\n\t\twhile ( maxIterations-- ) {\n\n\t\t\t// Evaluate and update our best guess (doubling guesses that zero out).\n\t\t\t// Finish if the scale equals or crosses 1 (making the old*new product non-positive).\n\t\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\t\t\tif ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {\n\t\t\t\tmaxIterations = 0;\n\t\t\t}\n\t\t\tinitialInUnit = initialInUnit / scale;\n\n\t\t}\n\n\t\tinitialInUnit = initialInUnit * 2;\n\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\n\t\t// Make sure we update the tween properties later on\n\t\tvalueParts = valueParts || [];\n\t}\n\n\tif ( valueParts ) {\n\t\tinitialInUnit = +initialInUnit || +initial || 0;\n\n\t\t// Apply relative offset (+=/-=) if specified\n\t\tadjusted = valueParts[ 1 ] ?\n\t\t\tinitialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :\n\t\t\t+valueParts[ 2 ];\n\t\tif ( tween ) {\n\t\t\ttween.unit = unit;\n\t\t\ttween.start = initialInUnit;\n\t\t\ttween.end = adjusted;\n\t\t}\n\t}\n\treturn adjusted;\n}\n\n\nvar defaultDisplayMap = {};\n\nfunction getDefaultDisplay( elem ) {\n\tvar temp,\n\t\tdoc = elem.ownerDocument,\n\t\tnodeName = elem.nodeName,\n\t\tdisplay = defaultDisplayMap[ nodeName ];\n\n\tif ( display ) {\n\t\treturn display;\n\t}\n\n\ttemp = doc.body.appendChild( doc.createElement( nodeName ) );\n\tdisplay = jQuery.css( temp, \"display\" );\n\n\ttemp.parentNode.removeChild( temp );\n\n\tif ( display === \"none\" ) {\n\t\tdisplay = \"block\";\n\t}\n\tdefaultDisplayMap[ nodeName ] = display;\n\n\treturn display;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\t// Determine new display value for elements that need to change\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\n\t\t\t// Since we force visibility upon cascade-hidden elements, an immediate (and slow)\n\t\t\t// check is required in this first loop unless we have a nonempty display value (either\n\t\t\t// inline or about-to-be-restored)\n\t\t\tif ( display === \"none\" ) {\n\t\t\t\tvalues[ index ] = dataPriv.get( elem, \"display\" ) || null;\n\t\t\t\tif ( !values[ index ] ) {\n\t\t\t\t\telem.style.display = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( elem.style.display === \"\" && isHiddenWithinTree( elem ) ) {\n\t\t\t\tvalues[ index ] = getDefaultDisplay( elem );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( display !== \"none\" ) {\n\t\t\t\tvalues[ index ] = \"none\";\n\n\t\t\t\t// Remember what we're overwriting\n\t\t\t\tdataPriv.set( elem, \"display\", display );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of the elements in a second loop to avoid constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\tif ( values[ index ] != null ) {\n\t\t\telements[ index ].style.display = values[ index ];\n\t\t}\n\t}\n\n\treturn elements;\n}\n\njQuery.fn.extend( {\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tif ( isHiddenWithinTree( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t} );\n\t}\n} );\nvar rcheckableType = ( /^(?:checkbox|radio)$/i );\n\nvar rtagName = ( /<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)/i );\n\nvar rscriptType = ( /^$|^module$|\\/(?:java|ecma)script/i );\n\n\n\n// We have to close these tags to support XHTML (#13200)\nvar wrapMap = {\n\n\t// Support: IE <=9 only\n\toption: [ 1, \"\" ],\n\n\t// XHTML parsers do not magically insert elements in the\n\t// same way that tag soup parsers do. So we cannot shorten\n\t// this by omitting or other required elements.\n\tthead: [ 1, \"\", \"
            \" ],\n\tcol: [ 2, \"\", \"
            \" ],\n\ttr: [ 2, \"\", \"
            \" ],\n\ttd: [ 3, \"\", \"
            \" ],\n\n\t_default: [ 0, \"\", \"\" ]\n};\n\n// Support: IE <=9 only\nwrapMap.optgroup = wrapMap.option;\n\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n\nfunction getAll( context, tag ) {\n\n\t// Support: IE <=9 - 11 only\n\t// Use typeof to avoid zero-argument method invocation on host objects (#15151)\n\tvar ret;\n\n\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\tret = context.getElementsByTagName( tag || \"*\" );\n\n\t} else if ( typeof context.querySelectorAll !== \"undefined\" ) {\n\t\tret = context.querySelectorAll( tag || \"*\" );\n\n\t} else {\n\t\tret = [];\n\t}\n\n\tif ( tag === undefined || tag && nodeName( context, tag ) ) {\n\t\treturn jQuery.merge( [ context ], ret );\n\t}\n\n\treturn ret;\n}\n\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar i = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\tdataPriv.set(\n\t\t\telems[ i ],\n\t\t\t\"globalEval\",\n\t\t\t!refElements || dataPriv.get( refElements[ i ], \"globalEval\" )\n\t\t);\n\t}\n}\n\n\nvar rhtml = /<|&#?\\w+;/;\n\nfunction buildFragment( elems, context, scripts, selection, ignored ) {\n\tvar elem, tmp, tag, wrap, attached, j,\n\t\tfragment = context.createDocumentFragment(),\n\t\tnodes = [],\n\t\ti = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\telem = elems[ i ];\n\n\t\tif ( elem || elem === 0 ) {\n\n\t\t\t// Add nodes directly\n\t\t\tif ( toType( elem ) === \"object\" ) {\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t// Convert non-html into a text node\n\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t// Convert html into DOM nodes\n\t\t\t} else {\n\t\t\t\ttmp = tmp || fragment.appendChild( context.createElement( \"div\" ) );\n\n\t\t\t\t// Deserialize a standard representation\n\t\t\t\ttag = ( rtagName.exec( elem ) || [ \"\", \"\" ] )[ 1 ].toLowerCase();\n\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\t\t\t\ttmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];\n\n\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\tj = wrap[ 0 ];\n\t\t\t\twhile ( j-- ) {\n\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t}\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t// Remember the top-level container\n\t\t\t\ttmp = fragment.firstChild;\n\n\t\t\t\t// Ensure the created nodes are orphaned (#12392)\n\t\t\t\ttmp.textContent = \"\";\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove wrapper from fragment\n\tfragment.textContent = \"\";\n\n\ti = 0;\n\twhile ( ( elem = nodes[ i++ ] ) ) {\n\n\t\t// Skip elements already in the context collection (trac-4087)\n\t\tif ( selection && jQuery.inArray( elem, selection ) > -1 ) {\n\t\t\tif ( ignored ) {\n\t\t\t\tignored.push( elem );\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tattached = isAttached( elem );\n\n\t\t// Append to fragment\n\t\ttmp = getAll( fragment.appendChild( elem ), \"script\" );\n\n\t\t// Preserve script evaluation history\n\t\tif ( attached ) {\n\t\t\tsetGlobalEval( tmp );\n\t\t}\n\n\t\t// Capture executables\n\t\tif ( scripts ) {\n\t\t\tj = 0;\n\t\t\twhile ( ( elem = tmp[ j++ ] ) ) {\n\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\tscripts.push( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fragment;\n}\n\n\n( function() {\n\tvar fragment = document.createDocumentFragment(),\n\t\tdiv = fragment.appendChild( document.createElement( \"div\" ) ),\n\t\tinput = document.createElement( \"input\" );\n\n\t// Support: Android 4.0 - 4.3 only\n\t// Check state lost if the name is set (#11217)\n\t// Support: Windows Web Apps (WWA)\n\t// `name` and `type` must use .setAttribute for WWA (#14901)\n\tinput.setAttribute( \"type\", \"radio\" );\n\tinput.setAttribute( \"checked\", \"checked\" );\n\tinput.setAttribute( \"name\", \"t\" );\n\n\tdiv.appendChild( input );\n\n\t// Support: Android <=4.1 only\n\t// Older WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE <=11 only\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\tdiv.innerHTML = \"\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n} )();\n\n\nvar\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\n// Support: IE <=9 - 11+\n// focus() and blur() are asynchronous, except when they are no-op.\n// So expect focus to be synchronous when the element is already active,\n// and blur to be synchronous when the element is not already active.\n// (focus and blur are always synchronous in other supported browsers,\n// this just defines when we can count on it).\nfunction expectSync( elem, type ) {\n\treturn ( elem === safeActiveElement() ) === ( type === \"focus\" );\n}\n\n// Support: IE <=9 only\n// Accessing document.activeElement can throw unexpectedly\n// https://bugs.jquery.com/ticket/13393\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\nfunction on( elem, types, selector, data, fn, one ) {\n\tvar origFn, type;\n\n\t// Types can be a map of types/handlers\n\tif ( typeof types === \"object\" ) {\n\n\t\t// ( types-Object, selector, data )\n\t\tif ( typeof selector !== \"string\" ) {\n\n\t\t\t// ( types-Object, data )\n\t\t\tdata = data || selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tfor ( type in types ) {\n\t\t\ton( elem, type, selector, data, types[ type ], one );\n\t\t}\n\t\treturn elem;\n\t}\n\n\tif ( data == null && fn == null ) {\n\n\t\t// ( types, fn )\n\t\tfn = selector;\n\t\tdata = selector = undefined;\n\t} else if ( fn == null ) {\n\t\tif ( typeof selector === \"string\" ) {\n\n\t\t\t// ( types, selector, fn )\n\t\t\tfn = data;\n\t\t\tdata = undefined;\n\t\t} else {\n\n\t\t\t// ( types, data, fn )\n\t\t\tfn = data;\n\t\t\tdata = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t}\n\tif ( fn === false ) {\n\t\tfn = returnFalse;\n\t} else if ( !fn ) {\n\t\treturn elem;\n\t}\n\n\tif ( one === 1 ) {\n\t\torigFn = fn;\n\t\tfn = function( event ) {\n\n\t\t\t// Can use an empty set, since event contains the info\n\t\t\tjQuery().off( event );\n\t\t\treturn origFn.apply( this, arguments );\n\t\t};\n\n\t\t// Use same guid so caller can remove using origFn\n\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t}\n\treturn elem.each( function() {\n\t\tjQuery.event.add( this, types, fn, data, selector );\n\t} );\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\n\t\tvar handleObjIn, eventHandle, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.get( elem );\n\n\t\t// Don't attach events to noData or text/comment nodes (but allow plain objects)\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Ensure that invalid selectors throw exceptions at attach time\n\t\t// Evaluate against documentElement in case elem is a non-element node (e.g., document)\n\t\tif ( selector ) {\n\t\t\tjQuery.find.matchesSelector( documentElement, selector );\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !( events = elemData.events ) ) {\n\t\t\tevents = elemData.events = {};\n\t\t}\n\t\tif ( !( eventHandle = elemData.handle ) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== \"undefined\" && jQuery.event.triggered !== e.type ?\n\t\t\t\t\tjQuery.event.dispatch.apply( elem, arguments ) : undefined;\n\t\t\t};\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend( {\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join( \".\" )\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !( handlers = events[ type ] ) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener if the special events handler returns false\n\t\t\t\tif ( !special.setup ||\n\t\t\t\t\tspecial.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\n\t\tvar j, origCount, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.hasData( elem ) && dataPriv.get( elem );\n\n\t\tif ( !elemData || !( events = elemData.events ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[ 2 ] &&\n\t\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector ||\n\t\t\t\t\t\tselector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown ||\n\t\t\t\t\tspecial.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove data and the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdataPriv.remove( elem, \"handle events\" );\n\t\t}\n\t},\n\n\tdispatch: function( nativeEvent ) {\n\n\t\t// Make a writable jQuery.Event from the native event object\n\t\tvar event = jQuery.event.fix( nativeEvent );\n\n\t\tvar i, j, ret, matched, handleObj, handlerQueue,\n\t\t\targs = new Array( arguments.length ),\n\t\t\thandlers = ( dataPriv.get( this, \"events\" ) || {} )[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[ 0 ] = event;\n\n\t\tfor ( i = 1; i < arguments.length; i++ ) {\n\t\t\targs[ i ] = arguments[ i ];\n\t\t}\n\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( ( handleObj = matched.handlers[ j++ ] ) &&\n\t\t\t\t!event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// If the event is namespaced, then each handler is only invoked if it is\n\t\t\t\t// specially universal or its namespaces are a superset of the event's.\n\t\t\t\tif ( !event.rnamespace || handleObj.namespace === false ||\n\t\t\t\t\tevent.rnamespace.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||\n\t\t\t\t\t\thandleObj.handler ).apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( ( event.result = ret ) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar i, handleObj, sel, matchedHandlers, matchedSelectors,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\tif ( delegateCount &&\n\n\t\t\t// Support: IE <=9\n\t\t\t// Black-hole SVG instance trees (trac-13180)\n\t\t\tcur.nodeType &&\n\n\t\t\t// Support: Firefox <=42\n\t\t\t// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)\n\t\t\t// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click\n\t\t\t// Support: IE 11 only\n\t\t\t// ...but not arrow key \"clicks\" of radio inputs, which can have `button` -1 (gh-2343)\n\t\t\t!( event.type === \"click\" && event.button >= 1 ) ) {\n\n\t\t\tfor ( ; cur !== this; cur = cur.parentNode || this ) {\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && !( event.type === \"click\" && cur.disabled === true ) ) {\n\t\t\t\t\tmatchedHandlers = [];\n\t\t\t\t\tmatchedSelectors = {};\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatchedSelectors[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) > -1 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] ) {\n\t\t\t\t\t\t\tmatchedHandlers.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matchedHandlers.length ) {\n\t\t\t\t\t\thandlerQueue.push( { elem: cur, handlers: matchedHandlers } );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tcur = this;\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\taddProp: function( name, hook ) {\n\t\tObject.defineProperty( jQuery.Event.prototype, name, {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\n\t\t\tget: isFunction( hook ) ?\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn hook( this.originalEvent );\n\t\t\t\t\t}\n\t\t\t\t} :\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn this.originalEvent[ name ];\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\tset: function( value ) {\n\t\t\t\tObject.defineProperty( this, name, {\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t\tvalue: value\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t},\n\n\tfix: function( originalEvent ) {\n\t\treturn originalEvent[ jQuery.expando ] ?\n\t\t\toriginalEvent :\n\t\t\tnew jQuery.Event( originalEvent );\n\t},\n\n\tspecial: {\n\t\tload: {\n\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tclick: {\n\n\t\t\t// Utilize native event to ensure correct state for checkable inputs\n\t\t\tsetup: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Claim the first handler\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, \"input\" ) ) {\n\n\t\t\t\t\t// dataPriv.set( el, \"click\", ... )\n\t\t\t\t\tleverageNative( el, \"click\", returnTrue );\n\t\t\t\t}\n\n\t\t\t\t// Return false to allow normal processing in the caller\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\ttrigger: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Force setup before triggering a click\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, \"input\" ) ) {\n\n\t\t\t\t\tleverageNative( el, \"click\" );\n\t\t\t\t}\n\n\t\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\t\treturn true;\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, suppress native .click() on links\n\t\t\t// Also prevent it if we're currently inside a leveraged native-event stack\n\t\t\t_default: function( event ) {\n\t\t\t\tvar target = event.target;\n\t\t\t\treturn rcheckableType.test( target.type ) &&\n\t\t\t\t\ttarget.click && nodeName( target, \"input\" ) &&\n\t\t\t\t\tdataPriv.get( target, \"click\" ) ||\n\t\t\t\t\tnodeName( target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Ensure the presence of an event listener that handles manually-triggered\n// synthetic events by interrupting progress until reinvoked in response to\n// *native* events that it fires directly, ensuring that state changes have\n// already occurred before other listeners are invoked.\nfunction leverageNative( el, type, expectSync ) {\n\n\t// Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add\n\tif ( !expectSync ) {\n\t\tif ( dataPriv.get( el, type ) === undefined ) {\n\t\t\tjQuery.event.add( el, type, returnTrue );\n\t\t}\n\t\treturn;\n\t}\n\n\t// Register the controller as a special universal handler for all event namespaces\n\tdataPriv.set( el, type, false );\n\tjQuery.event.add( el, type, {\n\t\tnamespace: false,\n\t\thandler: function( event ) {\n\t\t\tvar notAsync, result,\n\t\t\t\tsaved = dataPriv.get( this, type );\n\n\t\t\tif ( ( event.isTrigger & 1 ) && this[ type ] ) {\n\n\t\t\t\t// Interrupt processing of the outer synthetic .trigger()ed event\n\t\t\t\t// Saved data should be false in such cases, but might be a leftover capture object\n\t\t\t\t// from an async native handler (gh-4350)\n\t\t\t\tif ( !saved.length ) {\n\n\t\t\t\t\t// Store arguments for use when handling the inner native event\n\t\t\t\t\t// There will always be at least one argument (an event object), so this array\n\t\t\t\t\t// will not be confused with a leftover capture object.\n\t\t\t\t\tsaved = slice.call( arguments );\n\t\t\t\t\tdataPriv.set( this, type, saved );\n\n\t\t\t\t\t// Trigger the native event and capture its result\n\t\t\t\t\t// Support: IE <=9 - 11+\n\t\t\t\t\t// focus() and blur() are asynchronous\n\t\t\t\t\tnotAsync = expectSync( this, type );\n\t\t\t\t\tthis[ type ]();\n\t\t\t\t\tresult = dataPriv.get( this, type );\n\t\t\t\t\tif ( saved !== result || notAsync ) {\n\t\t\t\t\t\tdataPriv.set( this, type, false );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = {};\n\t\t\t\t\t}\n\t\t\t\t\tif ( saved !== result ) {\n\n\t\t\t\t\t\t// Cancel the outer synthetic event\n\t\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\treturn result.value;\n\t\t\t\t\t}\n\n\t\t\t\t// If this is an inner synthetic event for an event with a bubbling surrogate\n\t\t\t\t// (focus or blur), assume that the surrogate already propagated from triggering the\n\t\t\t\t// native event and prevent that from happening again here.\n\t\t\t\t// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the\n\t\t\t\t// bubbling surrogate propagates *after* the non-bubbling base), but that seems\n\t\t\t\t// less bad than duplication.\n\t\t\t\t} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t}\n\n\t\t\t// If this is a native event triggered above, everything is now in order\n\t\t\t// Fire an inner synthetic event with the original arguments\n\t\t\t} else if ( saved.length ) {\n\n\t\t\t\t// ...and capture the result\n\t\t\t\tdataPriv.set( this, type, {\n\t\t\t\t\tvalue: jQuery.event.trigger(\n\n\t\t\t\t\t\t// Support: IE <=9 - 11+\n\t\t\t\t\t\t// Extend with the prototype to reset the above stopImmediatePropagation()\n\t\t\t\t\t\tjQuery.extend( saved[ 0 ], jQuery.Event.prototype ),\n\t\t\t\t\t\tsaved.slice( 1 ),\n\t\t\t\t\t\tthis\n\t\t\t\t\t)\n\t\t\t\t} );\n\n\t\t\t\t// Abort handling of the native event\n\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t}\n\t\t}\n\t} );\n}\n\njQuery.removeEvent = function( elem, type, handle ) {\n\n\t// This \"if\" is needed for plain objects\n\tif ( elem.removeEventListener ) {\n\t\telem.removeEventListener( type, handle );\n\t}\n};\n\njQuery.Event = function( src, props ) {\n\n\t// Allow instantiation without the 'new' keyword\n\tif ( !( this instanceof jQuery.Event ) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\n\t\t\t\t// Support: Android <=2.3 only\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t\t// Create target properties\n\t\t// Support: Safari <=6 - 7 only\n\t\t// Target should not be a text node (#504, #13143)\n\t\tthis.target = ( src.target && src.target.nodeType === 3 ) ?\n\t\t\tsrc.target.parentNode :\n\t\t\tsrc.target;\n\n\t\tthis.currentTarget = src.currentTarget;\n\t\tthis.relatedTarget = src.relatedTarget;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || Date.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tconstructor: jQuery.Event,\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\tisSimulated: false,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.preventDefault();\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Includes all common event props including KeyEvent and MouseEvent specific props\njQuery.each( {\n\taltKey: true,\n\tbubbles: true,\n\tcancelable: true,\n\tchangedTouches: true,\n\tctrlKey: true,\n\tdetail: true,\n\teventPhase: true,\n\tmetaKey: true,\n\tpageX: true,\n\tpageY: true,\n\tshiftKey: true,\n\tview: true,\n\t\"char\": true,\n\tcode: true,\n\tcharCode: true,\n\tkey: true,\n\tkeyCode: true,\n\tbutton: true,\n\tbuttons: true,\n\tclientX: true,\n\tclientY: true,\n\toffsetX: true,\n\toffsetY: true,\n\tpointerId: true,\n\tpointerType: true,\n\tscreenX: true,\n\tscreenY: true,\n\ttargetTouches: true,\n\ttoElement: true,\n\ttouches: true,\n\n\twhich: function( event ) {\n\t\tvar button = event.button;\n\n\t\t// Add which for key events\n\t\tif ( event.which == null && rkeyEvent.test( event.type ) ) {\n\t\t\treturn event.charCode != null ? event.charCode : event.keyCode;\n\t\t}\n\n\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\tif ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {\n\t\t\tif ( button & 1 ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tif ( button & 2 ) {\n\t\t\t\treturn 3;\n\t\t\t}\n\n\t\t\tif ( button & 4 ) {\n\t\t\t\treturn 2;\n\t\t\t}\n\n\t\t\treturn 0;\n\t\t}\n\n\t\treturn event.which;\n\t}\n}, jQuery.event.addProp );\n\njQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( type, delegateType ) {\n\tjQuery.event.special[ type ] = {\n\n\t\t// Utilize native event if possible so blur/focus sequence is correct\n\t\tsetup: function() {\n\n\t\t\t// Claim the first handler\n\t\t\t// dataPriv.set( this, \"focus\", ... )\n\t\t\t// dataPriv.set( this, \"blur\", ... )\n\t\t\tleverageNative( this, type, expectSync );\n\n\t\t\t// Return false to allow normal processing in the caller\n\t\t\treturn false;\n\t\t},\n\t\ttrigger: function() {\n\n\t\t\t// Force setup before trigger\n\t\t\tleverageNative( this, type );\n\n\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\treturn true;\n\t\t},\n\n\t\tdelegateType: delegateType\n\t};\n} );\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\n// so that event delegation works in jQuery.\n// Do the same for pointerenter/pointerleave and pointerover/pointerout\n//\n// Support: Safari 7 only\n// Safari sends mouseenter too often; see:\n// https://bugs.chromium.org/p/chromium/issues/detail?id=470258\n// for the description of the bug (it existed in older Chrome versions as well).\njQuery.each( {\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mouseenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n} );\n\njQuery.fn.extend( {\n\n\ton: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn );\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\n\t\t\t// ( event ) dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ?\n\t\t\t\t\thandleObj.origType + \".\" + handleObj.namespace :\n\t\t\t\t\thandleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t} );\n\t}\n} );\n\n\nvar\n\n\t/* eslint-disable max-len */\n\n\t// See https://github.com/eslint/eslint/issues/3229\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)[^>]*)\\/>/gi,\n\n\t/* eslint-enable */\n\n\t// Support: IE <=10 - 11, Edge 12 - 13 only\n\t// In IE/Edge using regex groups here causes severe slowdowns.\n\t// See https://connect.microsoft.com/IE/feedback/details/1736512/\n\trnoInnerhtml = /\\s*$/g;\n\n// Prefer a tbody over its parent table for containing new rows\nfunction manipulationTarget( elem, content ) {\n\tif ( nodeName( elem, \"table\" ) &&\n\t\tnodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ) {\n\n\t\treturn jQuery( elem ).children( \"tbody\" )[ 0 ] || elem;\n\t}\n\n\treturn elem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = ( elem.getAttribute( \"type\" ) !== null ) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tif ( ( elem.type || \"\" ).slice( 0, 5 ) === \"true/\" ) {\n\t\telem.type = elem.type.slice( 5 );\n\t} else {\n\t\telem.removeAttribute( \"type\" );\n\t}\n\n\treturn elem;\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\tvar i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;\n\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// 1. Copy private data: events, handlers, etc.\n\tif ( dataPriv.hasData( src ) ) {\n\t\tpdataOld = dataPriv.access( src );\n\t\tpdataCur = dataPriv.set( dest, pdataOld );\n\t\tevents = pdataOld.events;\n\n\t\tif ( events ) {\n\t\t\tdelete pdataCur.handle;\n\t\t\tpdataCur.events = {};\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Copy user data\n\tif ( dataUser.hasData( src ) ) {\n\t\tudataOld = dataUser.access( src );\n\t\tudataCur = jQuery.extend( {}, udataOld );\n\n\t\tdataUser.set( dest, udataCur );\n\t}\n}\n\n// Fix IE bugs, see support tests\nfunction fixInput( src, dest ) {\n\tvar nodeName = dest.nodeName.toLowerCase();\n\n\t// Fails to persist the checked state of a cloned checkbox or radio button.\n\tif ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\tdest.checked = src.checked;\n\n\t// Fails to return the selected option to the default selected state when cloning options\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\nfunction domManip( collection, args, callback, ignored ) {\n\n\t// Flatten any nested arrays\n\targs = concat.apply( [], args );\n\n\tvar fragment, first, scripts, hasScripts, node, doc,\n\t\ti = 0,\n\t\tl = collection.length,\n\t\tiNoClone = l - 1,\n\t\tvalue = args[ 0 ],\n\t\tvalueIsFunction = isFunction( value );\n\n\t// We can't cloneNode fragments that contain checked, in WebKit\n\tif ( valueIsFunction ||\n\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\treturn collection.each( function( index ) {\n\t\t\tvar self = collection.eq( index );\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\targs[ 0 ] = value.call( this, index, self.html() );\n\t\t\t}\n\t\t\tdomManip( self, args, callback, ignored );\n\t\t} );\n\t}\n\n\tif ( l ) {\n\t\tfragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );\n\t\tfirst = fragment.firstChild;\n\n\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\tfragment = first;\n\t\t}\n\n\t\t// Require either new content or an interest in ignored elements to invoke the callback\n\t\tif ( first || ignored ) {\n\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\thasScripts = scripts.length;\n\n\t\t\t// Use the original fragment for the last item\n\t\t\t// instead of the first because it can end up\n\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tnode = fragment;\n\n\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\tif ( hasScripts ) {\n\n\t\t\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcallback.call( collection[ i ], node, i );\n\t\t\t}\n\n\t\t\tif ( hasScripts ) {\n\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t// Reenable scripts\n\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t!dataPriv.access( node, \"globalEval\" ) &&\n\t\t\t\t\t\tjQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\tif ( node.src && ( node.type || \"\" ).toLowerCase() !== \"module\" ) {\n\n\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\tif ( jQuery._evalUrl && !node.noModule ) {\n\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src, {\n\t\t\t\t\t\t\t\t\tnonce: node.nonce || node.getAttribute( \"nonce\" )\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tDOMEval( node.textContent.replace( rcleanScript, \"\" ), node, doc );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn collection;\n}\n\nfunction remove( elem, selector, keepData ) {\n\tvar node,\n\t\tnodes = selector ? jQuery.filter( selector, elem ) : elem,\n\t\ti = 0;\n\n\tfor ( ; ( node = nodes[ i ] ) != null; i++ ) {\n\t\tif ( !keepData && node.nodeType === 1 ) {\n\t\t\tjQuery.cleanData( getAll( node ) );\n\t\t}\n\n\t\tif ( node.parentNode ) {\n\t\t\tif ( keepData && isAttached( node ) ) {\n\t\t\t\tsetGlobalEval( getAll( node, \"script\" ) );\n\t\t\t}\n\t\t\tnode.parentNode.removeChild( node );\n\t\t}\n\t}\n\n\treturn elem;\n}\n\njQuery.extend( {\n\thtmlPrefilter: function( html ) {\n\t\treturn html.replace( rxhtmlTag, \"<$1>\" );\n\t},\n\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar i, l, srcElements, destElements,\n\t\t\tclone = elem.cloneNode( true ),\n\t\t\tinPage = isAttached( elem );\n\n\t\t// Fix IE cloning issues\n\t\tif ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&\n\t\t\t\t!jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\tfixInput( srcElements[ i ], destElements[ i ] );\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[ i ], destElements[ i ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, elem, type,\n\t\t\tspecial = jQuery.event.special,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {\n\t\t\tif ( acceptData( elem ) ) {\n\t\t\t\tif ( ( data = elem[ dataPriv.expando ] ) ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataPriv.expando ] = undefined;\n\t\t\t\t}\n\t\t\t\tif ( elem[ dataUser.expando ] ) {\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataUser.expando ] = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n} );\n\njQuery.fn.extend( {\n\tdetach: function( selector ) {\n\t\treturn remove( this, selector, true );\n\t},\n\n\tremove: function( selector ) {\n\t\treturn remove( this, selector );\n\t},\n\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().each( function() {\n\t\t\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\t\t\tthis.textContent = value;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t} );\n\t},\n\n\tprepend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t} );\n\t},\n\n\tbefore: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t} );\n\t},\n\n\tafter: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t} );\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = this[ i ] ) != null; i++ ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\n\t\t\t\t// Prevent memory leaks\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\n\t\t\t\t// Remove any remaining nodes\n\t\t\t\telem.textContent = \"\";\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t} );\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined && elem.nodeType === 1 ) {\n\t\t\t\treturn elem.innerHTML;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [ \"\", \"\" ] )[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = jQuery.htmlPrefilter( value );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\t\telem = this[ i ] || {};\n\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch ( e ) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar ignored = [];\n\n\t\t// Make the changes, replacing each non-ignored context element with the new content\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tvar parent = this.parentNode;\n\n\t\t\tif ( jQuery.inArray( this, ignored ) < 0 ) {\n\t\t\t\tjQuery.cleanData( getAll( this ) );\n\t\t\t\tif ( parent ) {\n\t\t\t\t\tparent.replaceChild( elem, this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Force callback invocation\n\t\t}, ignored );\n\t}\n} );\n\njQuery.each( {\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1,\n\t\t\ti = 0;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone( true );\n\t\t\tjQuery( insert[ i ] )[ original ]( elems );\n\n\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t// .get() because push.apply(_, arraylike) throws on ancient WebKit\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n} );\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\nvar getStyles = function( elem ) {\n\n\t\t// Support: IE <=11 only, Firefox <=30 (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tvar view = elem.ownerDocument.defaultView;\n\n\t\tif ( !view || !view.opener ) {\n\t\t\tview = window;\n\t\t}\n\n\t\treturn view.getComputedStyle( elem );\n\t};\n\nvar rboxStyle = new RegExp( cssExpand.join( \"|\" ), \"i\" );\n\n\n\n( function() {\n\n\t// Executing both pixelPosition & boxSizingReliable tests require only one layout\n\t// so they're executed at the same time to save the second computation.\n\tfunction computeStyleTests() {\n\n\t\t// This is a singleton, we need to execute it only once\n\t\tif ( !div ) {\n\t\t\treturn;\n\t\t}\n\n\t\tcontainer.style.cssText = \"position:absolute;left:-11111px;width:60px;\" +\n\t\t\t\"margin-top:1px;padding:0;border:0\";\n\t\tdiv.style.cssText =\n\t\t\t\"position:relative;display:block;box-sizing:border-box;overflow:scroll;\" +\n\t\t\t\"margin:auto;border:1px;padding:1px;\" +\n\t\t\t\"width:60%;top:1%\";\n\t\tdocumentElement.appendChild( container ).appendChild( div );\n\n\t\tvar divStyle = window.getComputedStyle( div );\n\t\tpixelPositionVal = divStyle.top !== \"1%\";\n\n\t\t// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44\n\t\treliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;\n\n\t\t// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3\n\t\t// Some styles come back with percentage values, even though they shouldn't\n\t\tdiv.style.right = \"60%\";\n\t\tpixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;\n\n\t\t// Support: IE 9 - 11 only\n\t\t// Detect misreporting of content dimensions for box-sizing:border-box elements\n\t\tboxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;\n\n\t\t// Support: IE 9 only\n\t\t// Detect overflow:scroll screwiness (gh-3699)\n\t\t// Support: Chrome <=64\n\t\t// Don't get tricked when zoom affects offsetWidth (gh-4029)\n\t\tdiv.style.position = \"absolute\";\n\t\tscrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;\n\n\t\tdocumentElement.removeChild( container );\n\n\t\t// Nullify the div so it wouldn't be stored in the memory and\n\t\t// it will also be a sign that checks already performed\n\t\tdiv = null;\n\t}\n\n\tfunction roundPixelMeasures( measure ) {\n\t\treturn Math.round( parseFloat( measure ) );\n\t}\n\n\tvar pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,\n\t\treliableMarginLeftVal,\n\t\tcontainer = document.createElement( \"div\" ),\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !div.style ) {\n\t\treturn;\n\t}\n\n\t// Support: IE <=9 - 11 only\n\t// Style of cloned element affects source element cloned (#8908)\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\tjQuery.extend( support, {\n\t\tboxSizingReliable: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\t\tpixelBoxStyles: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelBoxStylesVal;\n\t\t},\n\t\tpixelPosition: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelPositionVal;\n\t\t},\n\t\treliableMarginLeft: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn reliableMarginLeftVal;\n\t\t},\n\t\tscrollboxSize: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn scrollboxSizeVal;\n\t\t}\n\t} );\n} )();\n\n\nfunction curCSS( elem, name, computed ) {\n\tvar width, minWidth, maxWidth, ret,\n\n\t\t// Support: Firefox 51+\n\t\t// Retrieving style before computed somehow\n\t\t// fixes an issue with getting wrong values\n\t\t// on detached elements\n\t\tstyle = elem.style;\n\n\tcomputed = computed || getStyles( elem );\n\n\t// getPropertyValue is needed for:\n\t// .css('filter') (IE 9 only, #12537)\n\t// .css('--customProperty) (#3144)\n\tif ( computed ) {\n\t\tret = computed.getPropertyValue( name ) || computed[ name ];\n\n\t\tif ( ret === \"\" && !isAttached( elem ) ) {\n\t\t\tret = jQuery.style( elem, name );\n\t\t}\n\n\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t// Android Browser returns percentage for some values,\n\t\t// but width seems to be reliably pixels.\n\t\t// This is against the CSSOM draft spec:\n\t\t// https://drafts.csswg.org/cssom/#resolved-values\n\t\tif ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\twidth = style.width;\n\t\t\tminWidth = style.minWidth;\n\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\tret = computed.width;\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.width = width;\n\t\t\tstyle.minWidth = minWidth;\n\t\t\tstyle.maxWidth = maxWidth;\n\t\t}\n\t}\n\n\treturn ret !== undefined ?\n\n\t\t// Support: IE <=9 - 11 only\n\t\t// IE returns zIndex value as an integer.\n\t\tret + \"\" :\n\t\tret;\n}\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tif ( conditionFn() ) {\n\n\t\t\t\t// Hook not needed (or it's not possible to use it due\n\t\t\t\t// to missing dependency), remove it.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\t\t\treturn ( this.get = hookFn ).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\nvar cssPrefixes = [ \"Webkit\", \"Moz\", \"ms\" ],\n\temptyStyle = document.createElement( \"div\" ).style,\n\tvendorProps = {};\n\n// Return a vendor-prefixed property or undefined\nfunction vendorPropName( name ) {\n\n\t// Check for vendor prefixed names\n\tvar capName = name[ 0 ].toUpperCase() + name.slice( 1 ),\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in emptyStyle ) {\n\t\t\treturn name;\n\t\t}\n\t}\n}\n\n// Return a potentially-mapped jQuery.cssProps or vendor prefixed property\nfunction finalPropName( name ) {\n\tvar final = jQuery.cssProps[ name ] || vendorProps[ name ];\n\n\tif ( final ) {\n\t\treturn final;\n\t}\n\tif ( name in emptyStyle ) {\n\t\treturn name;\n\t}\n\treturn vendorProps[ name ] = vendorPropName( name ) || name;\n}\n\n\nvar\n\n\t// Swappable if display is none or starts with table\n\t// except \"table\", \"table-cell\", or \"table-caption\"\n\t// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trcustomProp = /^--/,\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t};\n\nfunction setPositiveNumber( elem, value, subtract ) {\n\n\t// Any relative (+/-) values have already been\n\t// normalized at this point\n\tvar matches = rcssNum.exec( value );\n\treturn matches ?\n\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {\n\tvar i = dimension === \"width\" ? 1 : 0,\n\t\textra = 0,\n\t\tdelta = 0;\n\n\t// Adjustment may not be necessary\n\tif ( box === ( isBorderBox ? \"border\" : \"content\" ) ) {\n\t\treturn 0;\n\t}\n\n\tfor ( ; i < 4; i += 2 ) {\n\n\t\t// Both box models exclude margin\n\t\tif ( box === \"margin\" ) {\n\t\t\tdelta += jQuery.css( elem, box + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\t// If we get here with a content-box, we're seeking \"padding\" or \"border\" or \"margin\"\n\t\tif ( !isBorderBox ) {\n\n\t\t\t// Add padding\n\t\t\tdelta += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// For \"border\" or \"margin\", add border\n\t\t\tif ( box !== \"padding\" ) {\n\t\t\t\tdelta += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\n\t\t\t// But still keep track of it otherwise\n\t\t\t} else {\n\t\t\t\textra += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\n\t\t// If we get here with a border-box (content + padding + border), we're seeking \"content\" or\n\t\t// \"padding\" or \"margin\"\n\t\t} else {\n\n\t\t\t// For \"content\", subtract padding\n\t\t\tif ( box === \"content\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// For \"content\" or \"padding\", subtract border\n\t\t\tif ( box !== \"margin\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Account for positive content-box scroll gutter when requested by providing computedVal\n\tif ( !isBorderBox && computedVal >= 0 ) {\n\n\t\t// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border\n\t\t// Assuming integer scroll gutter, subtract the rest and round down\n\t\tdelta += Math.max( 0, Math.ceil(\n\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\tcomputedVal -\n\t\t\tdelta -\n\t\t\textra -\n\t\t\t0.5\n\n\t\t// If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter\n\t\t// Use an explicit zero to avoid NaN (gh-3964)\n\t\t) ) || 0;\n\t}\n\n\treturn delta;\n}\n\nfunction getWidthOrHeight( elem, dimension, extra ) {\n\n\t// Start with computed style\n\tvar styles = getStyles( elem ),\n\n\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).\n\t\t// Fake content-box until we know it's needed to know the true value.\n\t\tboxSizingNeeded = !support.boxSizingReliable() || extra,\n\t\tisBorderBox = boxSizingNeeded &&\n\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\tvalueIsBorderBox = isBorderBox,\n\n\t\tval = curCSS( elem, dimension, styles ),\n\t\toffsetProp = \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );\n\n\t// Support: Firefox <=54\n\t// Return a confounding non-pixel value or feign ignorance, as appropriate.\n\tif ( rnumnonpx.test( val ) ) {\n\t\tif ( !extra ) {\n\t\t\treturn val;\n\t\t}\n\t\tval = \"auto\";\n\t}\n\n\n\t// Fall back to offsetWidth/offsetHeight when value is \"auto\"\n\t// This happens for inline elements with no explicit setting (gh-3571)\n\t// Support: Android <=4.1 - 4.3 only\n\t// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)\n\t// Support: IE 9-11 only\n\t// Also use offsetWidth/offsetHeight for when box sizing is unreliable\n\t// We use getClientRects() to check for hidden/disconnected.\n\t// In those cases, the computed value can be trusted to be border-box\n\tif ( ( !support.boxSizingReliable() && isBorderBox ||\n\t\tval === \"auto\" ||\n\t\t!parseFloat( val ) && jQuery.css( elem, \"display\", false, styles ) === \"inline\" ) &&\n\t\telem.getClientRects().length ) {\n\n\t\tisBorderBox = jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t\t// Where available, offsetWidth/offsetHeight approximate border box dimensions.\n\t\t// Where not available (e.g., SVG), assume unreliable box-sizing and interpret the\n\t\t// retrieved value as a content box dimension.\n\t\tvalueIsBorderBox = offsetProp in elem;\n\t\tif ( valueIsBorderBox ) {\n\t\t\tval = elem[ offsetProp ];\n\t\t}\n\t}\n\n\t// Normalize \"\" and auto\n\tval = parseFloat( val ) || 0;\n\n\t// Adjust for the element's box model\n\treturn ( val +\n\t\tboxModelAdjustment(\n\t\t\telem,\n\t\t\tdimension,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles,\n\n\t\t\t// Provide the current computed size to request scroll gutter calculation (gh-3589)\n\t\t\tval\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend( {\n\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"animationIterationCount\": true,\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"gridArea\": true,\n\t\t\"gridColumn\": true,\n\t\t\"gridColumnEnd\": true,\n\t\t\"gridColumnStart\": true,\n\t\t\"gridRow\": true,\n\t\t\"gridRowEnd\": true,\n\t\t\"gridRowStart\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name ),\n\t\t\tstyle = elem.style;\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to query the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Gets hook for the prefixed version, then unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// Convert \"+=\" or \"-=\" to relative numbers (#7345)\n\t\t\tif ( type === \"string\" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {\n\t\t\t\tvalue = adjustCSS( elem, name, ret );\n\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set (#7116)\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add the unit (except for certain CSS properties)\n\t\t\t// The isCustomProp check can be removed in jQuery 4.0 when we only auto-append\n\t\t\t// \"px\" to a few hardcoded values.\n\t\t\tif ( type === \"number\" && !isCustomProp ) {\n\t\t\t\tvalue += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? \"\" : \"px\" );\n\t\t\t}\n\n\t\t\t// background-* props affect original clone's values\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf( \"background\" ) === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !( \"set\" in hooks ) ||\n\t\t\t\t( value = hooks.set( elem, value, extra ) ) !== undefined ) {\n\n\t\t\t\tif ( isCustomProp ) {\n\t\t\t\t\tstyle.setProperty( name, value );\n\t\t\t\t} else {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks &&\n\t\t\t\t( ret = hooks.get( elem, false, extra ) ) !== undefined ) {\n\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar val, num, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name );\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to modify the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Try prefixed name followed by the unprefixed name\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t// Convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Make numeric if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || isFinite( num ) ? num || 0 : val;\n\t\t}\n\n\t\treturn val;\n\t}\n} );\n\njQuery.each( [ \"height\", \"width\" ], function( i, dimension ) {\n\tjQuery.cssHooks[ dimension ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\n\t\t\t\t// Certain elements can have dimension info if we invisibly show them\n\t\t\t\t// but it must have a current display style that would benefit\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) &&\n\n\t\t\t\t\t// Support: Safari 8+\n\t\t\t\t\t// Table columns in Safari have non-zero offsetWidth & zero\n\t\t\t\t\t// getBoundingClientRect().width unless display is changed.\n\t\t\t\t\t// Support: IE <=11 only\n\t\t\t\t\t// Running getBoundingClientRect on a disconnected node\n\t\t\t\t\t// in IE throws an error.\n\t\t\t\t\t( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?\n\t\t\t\t\t\tswap( elem, cssShow, function() {\n\t\t\t\t\t\t\treturn getWidthOrHeight( elem, dimension, extra );\n\t\t\t\t\t\t} ) :\n\t\t\t\t\t\tgetWidthOrHeight( elem, dimension, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar matches,\n\t\t\t\tstyles = getStyles( elem ),\n\n\t\t\t\t// Only read styles.position if the test has a chance to fail\n\t\t\t\t// to avoid forcing a reflow.\n\t\t\t\tscrollboxSizeBuggy = !support.scrollboxSize() &&\n\t\t\t\t\tstyles.position === \"absolute\",\n\n\t\t\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)\n\t\t\t\tboxSizingNeeded = scrollboxSizeBuggy || extra,\n\t\t\t\tisBorderBox = boxSizingNeeded &&\n\t\t\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\tsubtract = extra ?\n\t\t\t\t\tboxModelAdjustment(\n\t\t\t\t\t\telem,\n\t\t\t\t\t\tdimension,\n\t\t\t\t\t\textra,\n\t\t\t\t\t\tisBorderBox,\n\t\t\t\t\t\tstyles\n\t\t\t\t\t) :\n\t\t\t\t\t0;\n\n\t\t\t// Account for unreliable border-box dimensions by comparing offset* to computed and\n\t\t\t// faking a content-box to get border and padding (gh-3699)\n\t\t\tif ( isBorderBox && scrollboxSizeBuggy ) {\n\t\t\t\tsubtract -= Math.ceil(\n\t\t\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\t\t\tparseFloat( styles[ dimension ] ) -\n\t\t\t\t\tboxModelAdjustment( elem, dimension, \"border\", false, styles ) -\n\t\t\t\t\t0.5\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Convert to pixels if value adjustment is needed\n\t\t\tif ( subtract && ( matches = rcssNum.exec( value ) ) &&\n\t\t\t\t( matches[ 3 ] || \"px\" ) !== \"px\" ) {\n\n\t\t\t\telem.style[ dimension ] = value;\n\t\t\t\tvalue = jQuery.css( elem, dimension );\n\t\t\t}\n\n\t\t\treturn setPositiveNumber( elem, value, subtract );\n\t\t}\n\t};\n} );\n\njQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\treturn ( parseFloat( curCSS( elem, \"marginLeft\" ) ) ||\n\t\t\t\telem.getBoundingClientRect().left -\n\t\t\t\t\tswap( elem, { marginLeft: 0 }, function() {\n\t\t\t\t\t\treturn elem.getBoundingClientRect().left;\n\t\t\t\t\t} )\n\t\t\t\t) + \"px\";\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each( {\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// Assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split( \" \" ) : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( prefix !== \"margin\" ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n} );\n\njQuery.fn.extend( {\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( Array.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t}\n} );\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || jQuery.easing._default;\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\t// Use a property on the element directly when it is not a DOM element,\n\t\t\t// or when there is no matching style property that exists.\n\t\t\tif ( tween.elem.nodeType !== 1 ||\n\t\t\t\ttween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// Passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails.\n\t\t\t// Simple values such as \"10px\" are parsed to Float;\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as-is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\n\t\t\t// Use step hook for back compat.\n\t\t\t// Use cssHook if its there.\n\t\t\t// Use .style if available and use plain properties where available.\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.nodeType === 1 && (\n\t\t\t\t\tjQuery.cssHooks[ tween.prop ] ||\n\t\t\t\t\ttween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE <=9 only\n// Panic based approach to setting things on disconnected nodes\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t},\n\t_default: \"swing\"\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, inProgress,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trrun = /queueHooks$/;\n\nfunction schedule() {\n\tif ( inProgress ) {\n\t\tif ( document.hidden === false && window.requestAnimationFrame ) {\n\t\t\twindow.requestAnimationFrame( schedule );\n\t\t} else {\n\t\t\twindow.setTimeout( schedule, jQuery.fx.interval );\n\t\t}\n\n\t\tjQuery.fx.tick();\n\t}\n}\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\twindow.setTimeout( function() {\n\t\tfxNow = undefined;\n\t} );\n\treturn ( fxNow = Date.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\ti = 0,\n\t\tattrs = { height: type };\n\n\t// If we include width, step value is 1 to do all cssExpand values,\n\t// otherwise step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {\n\n\t\t\t// We're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\tvar prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,\n\t\tisBox = \"width\" in props || \"height\" in props,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHiddenWithinTree( elem ),\n\t\tdataShow = dataPriv.get( elem, \"fxshow\" );\n\n\t// Queue-skipping animations hijack the fx hooks\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always( function() {\n\n\t\t\t// Ensure the complete handler is called before this completes\n\t\t\tanim.always( function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\t// Detect show/hide animations\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.test( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// Pretend to be hidden if this is a \"show\" and\n\t\t\t\t// there is still data from a stopped show/hide\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\n\t\t\t\t// Ignore all other no-op show/hide data\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\t\t}\n\t}\n\n\t// Bail out if this is a no-op like .hide().hide()\n\tpropTween = !jQuery.isEmptyObject( props );\n\tif ( !propTween && jQuery.isEmptyObject( orig ) ) {\n\t\treturn;\n\t}\n\n\t// Restrict \"overflow\" and \"display\" styles during box animations\n\tif ( isBox && elem.nodeType === 1 ) {\n\n\t\t// Support: IE <=9 - 11, Edge 12 - 15\n\t\t// Record all 3 overflow attributes because IE does not infer the shorthand\n\t\t// from identically-valued overflowX and overflowY and Edge just mirrors\n\t\t// the overflowX value there.\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Identify a display type, preferring old show/hide data over the CSS cascade\n\t\trestoreDisplay = dataShow && dataShow.display;\n\t\tif ( restoreDisplay == null ) {\n\t\t\trestoreDisplay = dataPriv.get( elem, \"display\" );\n\t\t}\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\tif ( display === \"none\" ) {\n\t\t\tif ( restoreDisplay ) {\n\t\t\t\tdisplay = restoreDisplay;\n\t\t\t} else {\n\n\t\t\t\t// Get nonempty value(s) by temporarily forcing visibility\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t\trestoreDisplay = elem.style.display || restoreDisplay;\n\t\t\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\t\t\tshowHide( [ elem ] );\n\t\t\t}\n\t\t}\n\n\t\t// Animate inline elements as inline-block\n\t\tif ( display === \"inline\" || display === \"inline-block\" && restoreDisplay != null ) {\n\t\t\tif ( jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t\t// Restore the original display value at the end of pure show/hide animations\n\t\t\t\tif ( !propTween ) {\n\t\t\t\t\tanim.done( function() {\n\t\t\t\t\t\tstyle.display = restoreDisplay;\n\t\t\t\t\t} );\n\t\t\t\t\tif ( restoreDisplay == null ) {\n\t\t\t\t\t\tdisplay = style.display;\n\t\t\t\t\t\trestoreDisplay = display === \"none\" ? \"\" : display;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tanim.always( function() {\n\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t} );\n\t}\n\n\t// Implement show/hide animations\n\tpropTween = false;\n\tfor ( prop in orig ) {\n\n\t\t// General show/hide setup for this element animation\n\t\tif ( !propTween ) {\n\t\t\tif ( dataShow ) {\n\t\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\t\thidden = dataShow.hidden;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdataShow = dataPriv.access( elem, \"fxshow\", { display: restoreDisplay } );\n\t\t\t}\n\n\t\t\t// Store hidden/visible for toggle so `.stop().toggle()` \"reverses\"\n\t\t\tif ( toggle ) {\n\t\t\t\tdataShow.hidden = !hidden;\n\t\t\t}\n\n\t\t\t// Show elements before animating them\n\t\t\tif ( hidden ) {\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t}\n\n\t\t\t/* eslint-disable no-loop-func */\n\n\t\t\tanim.done( function() {\n\n\t\t\t/* eslint-enable no-loop-func */\n\n\t\t\t\t// The final step of a \"hide\" animation is actually hiding the element\n\t\t\t\tif ( !hidden ) {\n\t\t\t\t\tshowHide( [ elem ] );\n\t\t\t\t}\n\t\t\t\tdataPriv.remove( elem, \"fxshow\" );\n\t\t\t\tfor ( prop in orig ) {\n\t\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Per-property setup\n\t\tpropTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\t\tif ( !( prop in dataShow ) ) {\n\t\t\tdataShow[ prop ] = propTween.start;\n\t\t\tif ( hidden ) {\n\t\t\t\tpropTween.end = propTween.start;\n\t\t\t\tpropTween.start = 0;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( Array.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// Not quite $.extend, this won't overwrite existing keys.\n\t\t\t// Reusing 'index' because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = Animation.prefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\n\t\t\t// Don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t} ),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\n\t\t\t\t// Support: Android 2.3 only\n\t\t\t\t// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ] );\n\n\t\t\t// If there's more to do, yield\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t}\n\n\t\t\t// If this was an empty animation, synthesize a final progress notification\n\t\t\tif ( !length ) {\n\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t}\n\n\t\t\t// Resolve the animation and report its conclusion\n\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\treturn false;\n\t\t},\n\t\tanimation = deferred.promise( {\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, {\n\t\t\t\tspecialEasing: {},\n\t\t\t\teasing: jQuery.easing._default\n\t\t\t}, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\n\t\t\t\t\t// If we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// Resolve when we played the last frame; otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t} ),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length; index++ ) {\n\t\tresult = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\tif ( isFunction( result.stop ) ) {\n\t\t\t\tjQuery._queueHooks( animation.elem, animation.opts.queue ).stop =\n\t\t\t\t\tresult.stop.bind( result );\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\t// Attach callbacks from options\n\tanimation\n\t\t.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t} )\n\t);\n\n\treturn animation;\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n\ttweeners: {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value );\n\t\t\tadjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );\n\t\t\treturn tween;\n\t\t} ]\n\t},\n\n\ttweener: function( props, callback ) {\n\t\tif ( isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.match( rnothtmlwhite );\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\tAnimation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];\n\t\t\tAnimation.tweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilters: [ defaultPrefilter ],\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tAnimation.prefilters.unshift( callback );\n\t\t} else {\n\t\t\tAnimation.prefilters.push( callback );\n\t\t}\n\t}\n} );\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tisFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !isFunction( easing ) && easing\n\t};\n\n\t// Go to the end state if fx are off\n\tif ( jQuery.fx.off ) {\n\t\topt.duration = 0;\n\n\t} else {\n\t\tif ( typeof opt.duration !== \"number\" ) {\n\t\t\tif ( opt.duration in jQuery.fx.speeds ) {\n\t\t\t\topt.duration = jQuery.fx.speeds[ opt.duration ];\n\n\t\t\t} else {\n\t\t\t\topt.duration = jQuery.fx.speeds._default;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend( {\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// Show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHiddenWithinTree ).css( \"opacity\", 0 ).show()\n\n\t\t\t// Animate to the value specified\n\t\t\t.end().animate( { opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || dataPriv.get( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue && type !== false ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = dataPriv.get( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this &&\n\t\t\t\t\t( type == null || timers[ index ].queue === type ) ) {\n\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Start the next in the queue if the last step wasn't forced.\n\t\t\t// Timers currently will call their complete callbacks, which\n\t\t\t// will dequeue but only if they were gotoEnd.\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t} );\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tvar index,\n\t\t\t\tdata = dataPriv.get( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// Enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// Empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// Look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t} );\n\t}\n} );\n\njQuery.each( [ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n} );\n\n// Generate shortcuts for custom animations\njQuery.each( {\n\tslideDown: genFx( \"show\" ),\n\tslideUp: genFx( \"hide\" ),\n\tslideToggle: genFx( \"toggle\" ),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n} );\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ti = 0,\n\t\ttimers = jQuery.timers;\n\n\tfxNow = Date.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\n\t\t// Run the timer and safely remove it when done (allowing for external removal)\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tjQuery.fx.start();\n};\n\njQuery.fx.interval = 13;\njQuery.fx.start = function() {\n\tif ( inProgress ) {\n\t\treturn;\n\t}\n\n\tinProgress = true;\n\tschedule();\n};\n\njQuery.fx.stop = function() {\n\tinProgress = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = window.setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\twindow.clearTimeout( timeout );\n\t\t};\n\t} );\n};\n\n\n( function() {\n\tvar input = document.createElement( \"input\" ),\n\t\tselect = document.createElement( \"select\" ),\n\t\topt = select.appendChild( document.createElement( \"option\" ) );\n\n\tinput.type = \"checkbox\";\n\n\t// Support: Android <=4.3 only\n\t// Default value for a checkbox should be \"on\"\n\tsupport.checkOn = input.value !== \"\";\n\n\t// Support: IE <=11 only\n\t// Must access selectedIndex to make default options select\n\tsupport.optSelected = opt.selected;\n\n\t// Support: IE <=11 only\n\t// An input loses its value after becoming a radio\n\tinput = document.createElement( \"input\" );\n\tinput.value = \"t\";\n\tinput.type = \"radio\";\n\tsupport.radioValue = input.value === \"t\";\n} )();\n\n\nvar boolHook,\n\tattrHandle = jQuery.expr.attrHandle;\n\njQuery.fn.extend( {\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tattr: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set attributes on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === \"undefined\" ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// Attribute hooks are determined by the lowercase version\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\thooks = jQuery.attrHooks[ name.toLowerCase() ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\treturn value;\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\tret = jQuery.find.attr( elem, name );\n\n\t\t// Non-existent attributes return null, we normalize to undefined\n\t\treturn ret == null ? undefined : ret;\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" &&\n\t\t\t\t\tnodeName( elem, \"input\" ) ) {\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name,\n\t\t\ti = 0,\n\n\t\t\t// Attribute names can contain non-HTML whitespace characters\n\t\t\t// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n\t\t\tattrNames = value && value.match( rnothtmlwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( ( name = attrNames[ i++ ] ) ) {\n\t\t\t\telem.removeAttribute( name );\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Hooks for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\telem.setAttribute( name, name );\n\t\t}\n\t\treturn name;\n\t}\n};\n\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( i, name ) {\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = function( elem, name, isXML ) {\n\t\tvar ret, handle,\n\t\t\tlowercaseName = name.toLowerCase();\n\n\t\tif ( !isXML ) {\n\n\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\thandle = attrHandle[ lowercaseName ];\n\t\t\tattrHandle[ lowercaseName ] = ret;\n\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\tlowercaseName :\n\t\t\t\tnull;\n\t\t\tattrHandle[ lowercaseName ] = handle;\n\t\t}\n\t\treturn ret;\n\t};\n} );\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend( {\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tdelete this[ jQuery.propFix[ name ] || name ];\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set properties on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\treturn ( elem[ name ] = value );\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\treturn elem[ name ];\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\t// Support: IE <=9 - 11 only\n\t\t\t\t// elem.tabIndex doesn't always return the\n\t\t\t\t// correct value when it hasn't been explicitly set\n\t\t\t\t// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\tif ( tabindex ) {\n\t\t\t\t\treturn parseInt( tabindex, 10 );\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\trfocusable.test( elem.nodeName ) ||\n\t\t\t\t\trclickable.test( elem.nodeName ) &&\n\t\t\t\t\telem.href\n\t\t\t\t) {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t}\n} );\n\n// Support: IE <=11 only\n// Accessing the selectedIndex property\n// forces the browser to respect setting selected\n// on the option\n// The getter ensures a default option is selected\n// when in an optgroup\n// eslint rule \"no-unused-expressions\" is disabled for this code\n// since it considers such accessions noop\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent && parent.parentNode ) {\n\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\tset: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\njQuery.each( [\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n} );\n\n\n\n\n\t// Strip and collapse whitespace according to HTML spec\n\t// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace\n\tfunction stripAndCollapse( value ) {\n\t\tvar tokens = value.match( rnothtmlwhite ) || [];\n\t\treturn tokens.join( \" \" );\n\t}\n\n\nfunction getClass( elem ) {\n\treturn elem.getAttribute && elem.getAttribute( \"class\" ) || \"\";\n}\n\nfunction classesToArray( value ) {\n\tif ( Array.isArray( value ) ) {\n\t\treturn value;\n\t}\n\tif ( typeof value === \"string\" ) {\n\t\treturn value.match( rnothtmlwhite ) || [];\n\t}\n\treturn [];\n}\n\njQuery.fn.extend( {\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( !arguments.length ) {\n\t\t\treturn this.attr( \"class\", \"\" );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) > -1 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value,\n\t\t\tisValidValue = type === \"string\" || Array.isArray( value );\n\n\t\tif ( typeof stateVal === \"boolean\" && isValidValue ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).toggleClass(\n\t\t\t\t\tvalue.call( this, i, getClass( this ), stateVal ),\n\t\t\t\t\tstateVal\n\t\t\t\t);\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar className, i, self, classNames;\n\n\t\t\tif ( isValidValue ) {\n\n\t\t\t\t// Toggle individual class names\n\t\t\t\ti = 0;\n\t\t\t\tself = jQuery( this );\n\t\t\t\tclassNames = classesToArray( value );\n\n\t\t\t\twhile ( ( className = classNames[ i++ ] ) ) {\n\n\t\t\t\t\t// Check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( value === undefined || type === \"boolean\" ) {\n\t\t\t\tclassName = getClass( this );\n\t\t\t\tif ( className ) {\n\n\t\t\t\t\t// Store className if set\n\t\t\t\t\tdataPriv.set( this, \"__className__\", className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed `false`,\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tif ( this.setAttribute ) {\n\t\t\t\t\tthis.setAttribute( \"class\",\n\t\t\t\t\t\tclassName || value === false ?\n\t\t\t\t\t\t\"\" :\n\t\t\t\t\t\tdataPriv.get( this, \"__className__\" ) || \"\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className, elem,\n\t\t\ti = 0;\n\n\t\tclassName = \" \" + selector + \" \";\n\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\tif ( elem.nodeType === 1 &&\n\t\t\t\t( \" \" + stripAndCollapse( getClass( elem ) ) + \" \" ).indexOf( className ) > -1 ) {\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n} );\n\n\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend( {\n\tval: function( value ) {\n\t\tvar hooks, ret, valueIsFunction,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] ||\n\t\t\t\t\tjQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks &&\n\t\t\t\t\t\"get\" in hooks &&\n\t\t\t\t\t( ret = hooks.get( elem, \"value\" ) ) !== undefined\n\t\t\t\t) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\t// Handle most common string cases\n\t\t\t\tif ( typeof ret === \"string\" ) {\n\t\t\t\t\treturn ret.replace( rreturn, \"\" );\n\t\t\t\t}\n\n\t\t\t\t// Handle cases where value is null/undef or number\n\t\t\t\treturn ret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tvalueIsFunction = isFunction( value );\n\n\t\treturn this.each( function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\n\t\t\t} else if ( Array.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !( \"set\" in hooks ) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\n\t\t\t\t\t// Support: IE <=10 - 11 only\n\t\t\t\t\t// option.text throws exceptions (#14686, #14858)\n\t\t\t\t\t// Strip and collapse whitespace\n\t\t\t\t\t// https://html.spec.whatwg.org/#strip-and-collapse-whitespace\n\t\t\t\t\tstripAndCollapse( jQuery.text( elem ) );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option, i,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\",\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length;\n\n\t\t\t\tif ( index < 0 ) {\n\t\t\t\t\ti = max;\n\n\t\t\t\t} else {\n\t\t\t\t\ti = one ? index : 0;\n\t\t\t\t}\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t// IE8-9 doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t!option.disabled &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled ||\n\t\t\t\t\t\t\t\t!nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t/* eslint-disable no-cond-assign */\n\n\t\t\t\t\tif ( option.selected =\n\t\t\t\t\t\tjQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1\n\t\t\t\t\t) {\n\t\t\t\t\t\toptionSet = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t/* eslint-enable no-cond-assign */\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Radios and checkboxes getter/setter\njQuery.each( [ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( Array.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\treturn elem.getAttribute( \"value\" ) === null ? \"on\" : elem.value;\n\t\t};\n\t}\n} );\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\nsupport.focusin = \"onfocusin\" in window;\n\n\nvar rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\tstopPropagationCallback = function( e ) {\n\t\te.stopPropagation();\n\t};\n\njQuery.extend( jQuery.event, {\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\n\t\tvar i, cur, tmp, bubbleType, ontype, handle, special, lastElement,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split( \".\" ) : [];\n\n\t\tcur = lastElement = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf( \".\" ) > -1 ) {\n\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split( \".\" );\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf( \":\" ) < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join( \".\" );\n\t\tevent.rnamespace = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === ( elem.ownerDocument || document ) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tlastElement = cur;\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( dataPriv.get( cur, \"events\" ) || {} )[ event.type ] &&\n\t\t\t\tdataPriv.get( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( ( !special._default ||\n\t\t\t\tspecial._default.apply( eventPath.pop(), data ) === false ) &&\n\t\t\t\tacceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name as the event.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.addEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\telem[ type ]();\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.removeEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\t// Piggyback on a donor event to simulate a different one\n\t// Used only for `focus(in | out)` events\n\tsimulate: function( type, elem, event ) {\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true\n\t\t\t}\n\t\t);\n\n\t\tjQuery.event.trigger( e, null, elem );\n\t}\n\n} );\n\njQuery.fn.extend( {\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t} );\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[ 0 ];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n} );\n\n\n// Support: Firefox <=44\n// Firefox doesn't have focus(in | out) events\n// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787\n//\n// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1\n// focus(in | out) events fire after focus & blur events,\n// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order\n// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857\nif ( !support.focusin ) {\n\tjQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );\n\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tdataPriv.access( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tdataPriv.remove( doc, fix );\n\n\t\t\t\t} else {\n\t\t\t\t\tdataPriv.access( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t} );\n}\nvar location = window.location;\n\nvar nonce = Date.now();\n\nvar rquery = ( /\\?/ );\n\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\n\t// Support: IE 9 - 11 only\n\t// IE throws on parseFromString with invalid input.\n\ttry {\n\t\txml = ( new window.DOMParser() ).parseFromString( data, \"text/xml\" );\n\t} catch ( e ) {\n\t\txml = undefined;\n\t}\n\n\tif ( !xml || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\tjQuery.error( \"Invalid XML: \" + data );\n\t}\n\treturn xml;\n};\n\n\nvar\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( Array.isArray( obj ) ) {\n\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams(\n\t\t\t\t\tprefix + \"[\" + ( typeof v === \"object\" && v != null ? i : \"\" ) + \"]\",\n\t\t\t\t\tv,\n\t\t\t\t\ttraditional,\n\t\t\t\t\tadd\n\t\t\t\t);\n\t\t\t}\n\t\t} );\n\n\t} else if ( !traditional && toType( obj ) === \"object\" ) {\n\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, valueOrFunction ) {\n\n\t\t\t// If value is a function, invoke it and use its return value\n\t\t\tvar value = isFunction( valueOrFunction ) ?\n\t\t\t\tvalueOrFunction() :\n\t\t\t\tvalueOrFunction;\n\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" +\n\t\t\t\tencodeURIComponent( value == null ? \"\" : value );\n\t\t};\n\n\tif ( a == null ) {\n\t\treturn \"\";\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t} );\n\n\t} else {\n\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" );\n};\n\njQuery.fn.extend( {\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map( function() {\n\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t} )\n\t\t.filter( function() {\n\t\t\tvar type = this.type;\n\n\t\t\t// Use .is( \":disabled\" ) so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t} )\n\t\t.map( function( i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\tif ( val == null ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif ( Array.isArray( val ) ) {\n\t\t\t\treturn jQuery.map( val, function( val ) {\n\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t} ).get();\n\t}\n} );\n\n\nvar\n\tr20 = /%20/g,\n\trhash = /#.*$/,\n\trantiCache = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)$/mg,\n\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t * - BEFORE asking for a transport\n\t * - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat( \"*\" ),\n\n\t// Anchor tag for parsing the document origin\n\toriginAnchor = document.createElement( \"a\" );\n\toriginAnchor.href = location.href;\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];\n\n\t\tif ( isFunction( func ) ) {\n\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( ( dataType = dataTypes[ i++ ] ) ) {\n\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType[ 0 ] === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" &&\n\t\t\t\t!seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t} );\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar ct, type, finalDataType, firstDataType,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader( \"Content-Type\" );\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[ 0 ] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s.throws ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tstate: \"parsererror\",\n\t\t\t\t\t\t\t\terror: conv ? e : \"No conversion from \" + prev + \" to \" + current\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend( {\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: location.href,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( location.protocol ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /\\bxml\\b/,\n\t\t\thtml: /\\bhtml/,\n\t\t\tjson: /\\bjson\\b/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": JSON.parse,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar transport,\n\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// Url cleanup var\n\t\t\turlAnchor,\n\n\t\t\t// Request state (becomes false upon send and true upon completion)\n\t\t\tcompleted,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\t// Loop variable\n\t\t\ti,\n\n\t\t\t// uncached part of the url\n\t\t\tuncached,\n\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context &&\n\t\t\t\t( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\t\tjQuery.event,\n\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks( \"once memory\" ),\n\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( completed ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( ( match = rheaders.exec( responseHeadersString ) ) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[ 1 ].toLowerCase() + \" \" ] =\n\t\t\t\t\t\t\t\t\t( responseHeaders[ match[ 1 ].toLowerCase() + \" \" ] || [] )\n\t\t\t\t\t\t\t\t\t\t.concat( match[ 2 ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() + \" \" ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match.join( \", \" );\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn completed ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\tname = requestHeadersNames[ name.toLowerCase() ] =\n\t\t\t\t\t\t\trequestHeadersNames[ name.toLowerCase() ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( completed ) {\n\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Lazy-add the new callbacks in a way that preserves old ones\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR );\n\n\t\t// Add protocol if not provided (prefilters might expect it)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || location.href ) + \"\" )\n\t\t\t.replace( rprotocol, location.protocol + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = ( s.dataType || \"*\" ).toLowerCase().match( rnothtmlwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when the origin doesn't match the current origin.\n\t\tif ( s.crossDomain == null ) {\n\t\t\turlAnchor = document.createElement( \"a\" );\n\n\t\t\t// Support: IE <=8 - 11, Edge 12 - 15\n\t\t\t// IE throws exception on accessing the href property if url is malformed,\n\t\t\t// e.g. http://example.com:80x/\n\t\t\ttry {\n\t\t\t\turlAnchor.href = s.url;\n\n\t\t\t\t// Support: IE <=8 - 11 only\n\t\t\t\t// Anchor's host property isn't correctly set when s.url is relative\n\t\t\t\turlAnchor.href = urlAnchor.href;\n\t\t\t\ts.crossDomain = originAnchor.protocol + \"//\" + originAnchor.host !==\n\t\t\t\t\turlAnchor.protocol + \"//\" + urlAnchor.host;\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// If there is an error parsing the URL, assume it is crossDomain,\n\t\t\t\t// it can be rejected by the transport if it is invalid\n\t\t\t\ts.crossDomain = true;\n\t\t\t}\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( completed ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger( \"ajaxStart\" );\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\t// Remove hash to simplify url manipulation\n\t\tcacheURL = s.url.replace( rhash, \"\" );\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// Remember the hash so we can put it back\n\t\t\tuncached = s.url.slice( cacheURL.length );\n\n\t\t\t// If data is available and should be processed, append data to url\n\t\t\tif ( s.data && ( s.processData || typeof s.data === \"string\" ) ) {\n\t\t\t\tcacheURL += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data;\n\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add or update anti-cache param if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\tcacheURL = cacheURL.replace( rantiCache, \"$1\" );\n\t\t\t\tuncached = ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + ( nonce++ ) + uncached;\n\t\t\t}\n\n\t\t\t// Put hash and anti-cache on the URL that will be requested (gh-1732)\n\t\t\ts.url = cacheURL + uncached;\n\n\t\t// Change '%20' to '+' if this is encoded form body content (gh-2658)\n\t\t} else if ( s.data && s.processData &&\n\t\t\t( s.contentType || \"\" ).indexOf( \"application/x-www-form-urlencoded\" ) === 0 ) {\n\t\t\ts.data = s.data.replace( r20, \"+\" );\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[ 0 ] ] +\n\t\t\t\t\t( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend &&\n\t\t\t( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {\n\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// Aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tcompleteDeferred.add( s.complete );\n\t\tjqXHR.done( s.success );\n\t\tjqXHR.fail( s.error );\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\n\t\t\t// If request was aborted inside ajaxSend, stop there\n\t\t\tif ( completed ) {\n\t\t\t\treturn jqXHR;\n\t\t\t}\n\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = window.setTimeout( function() {\n\t\t\t\t\tjqXHR.abort( \"timeout\" );\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tcompleted = false;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// Rethrow post-completion exceptions\n\t\t\t\tif ( completed ) {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\n\t\t\t\t// Propagate others as results\n\t\t\t\tdone( -1, e );\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Ignore repeat invocations\n\t\t\tif ( completed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcompleted = true;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\twindow.clearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"Last-Modified\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"etag\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\n\t\t\t\t// Extract error from statusText and normalize for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger( \"ajaxStop\" );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n} );\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\n\t\t// Shift arguments if data argument was omitted\n\t\tif ( isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\t// The url can be an options object (which then must have .url)\n\t\treturn jQuery.ajax( jQuery.extend( {\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t}, jQuery.isPlainObject( url ) && url ) );\n\t};\n} );\n\n\njQuery._evalUrl = function( url, options ) {\n\treturn jQuery.ajax( {\n\t\turl: url,\n\n\t\t// Make this explicit, since user can override this through ajaxSetup (#11264)\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tcache: true,\n\t\tasync: false,\n\t\tglobal: false,\n\n\t\t// Only evaluate the response if it is successful (gh-4126)\n\t\t// dataFilter is not invoked for failure responses, so using it instead\n\t\t// of the default converter is kludgy but it works.\n\t\tconverters: {\n\t\t\t\"text script\": function() {}\n\t\t},\n\t\tdataFilter: function( response ) {\n\t\t\tjQuery.globalEval( response, options );\n\t\t}\n\t} );\n};\n\n\njQuery.fn.extend( {\n\twrapAll: function( html ) {\n\t\tvar wrap;\n\n\t\tif ( this[ 0 ] ) {\n\t\t\tif ( isFunction( html ) ) {\n\t\t\t\thtml = html.call( this[ 0 ] );\n\t\t\t}\n\n\t\t\t// The elements to wrap the target around\n\t\t\twrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );\n\n\t\t\tif ( this[ 0 ].parentNode ) {\n\t\t\t\twrap.insertBefore( this[ 0 ] );\n\t\t\t}\n\n\t\t\twrap.map( function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstElementChild ) {\n\t\t\t\t\telem = elem.firstElementChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t} ).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( isFunction( html ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).wrapInner( html.call( this, i ) );\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t} );\n\t},\n\n\twrap: function( html ) {\n\t\tvar htmlIsFunction = isFunction( html );\n\n\t\treturn this.each( function( i ) {\n\t\t\tjQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );\n\t\t} );\n\t},\n\n\tunwrap: function( selector ) {\n\t\tthis.parent( selector ).not( \"body\" ).each( function() {\n\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t} );\n\t\treturn this;\n\t}\n} );\n\n\njQuery.expr.pseudos.hidden = function( elem ) {\n\treturn !jQuery.expr.pseudos.visible( elem );\n};\njQuery.expr.pseudos.visible = function( elem ) {\n\treturn !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );\n};\n\n\n\n\njQuery.ajaxSettings.xhr = function() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch ( e ) {}\n};\n\nvar xhrSuccessStatus = {\n\n\t\t// File protocol always yields status code 0, assume 200\n\t\t0: 200,\n\n\t\t// Support: IE <=9 only\n\t\t// #1450: sometimes IE returns 1223 when it should be 204\n\t\t1223: 204\n\t},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nsupport.ajax = xhrSupported = !!xhrSupported;\n\njQuery.ajaxTransport( function( options ) {\n\tvar callback, errorCallback;\n\n\t// Cross domain only allowed if supported through XMLHttpRequest\n\tif ( support.cors || xhrSupported && !options.crossDomain ) {\n\t\treturn {\n\t\t\tsend: function( headers, complete ) {\n\t\t\t\tvar i,\n\t\t\t\t\txhr = options.xhr();\n\n\t\t\t\txhr.open(\n\t\t\t\t\toptions.type,\n\t\t\t\t\toptions.url,\n\t\t\t\t\toptions.async,\n\t\t\t\t\toptions.username,\n\t\t\t\t\toptions.password\n\t\t\t\t);\n\n\t\t\t\t// Apply custom fields if provided\n\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Override mime type if needed\n\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t}\n\n\t\t\t\t// X-Requested-With header\n\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\tif ( !options.crossDomain && !headers[ \"X-Requested-With\" ] ) {\n\t\t\t\t\theaders[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n\t\t\t\t}\n\n\t\t\t\t// Set headers\n\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t}\n\n\t\t\t\t// Callback\n\t\t\t\tcallback = function( type ) {\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\tcallback = errorCallback = xhr.onload =\n\t\t\t\t\t\t\t\txhr.onerror = xhr.onabort = xhr.ontimeout =\n\t\t\t\t\t\t\t\t\txhr.onreadystatechange = null;\n\n\t\t\t\t\t\t\tif ( type === \"abort\" ) {\n\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t} else if ( type === \"error\" ) {\n\n\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t// On a manual native abort, IE9 throws\n\t\t\t\t\t\t\t\t// errors on any property access that is not readyState\n\t\t\t\t\t\t\t\tif ( typeof xhr.status !== \"number\" ) {\n\t\t\t\t\t\t\t\t\tcomplete( 0, \"error\" );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcomplete(\n\n\t\t\t\t\t\t\t\t\t\t// File: protocol always yields status 0; see #8605, #14207\n\t\t\t\t\t\t\t\t\t\txhr.status,\n\t\t\t\t\t\t\t\t\t\txhr.statusText\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\txhrSuccessStatus[ xhr.status ] || xhr.status,\n\t\t\t\t\t\t\t\t\txhr.statusText,\n\n\t\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t\t// IE9 has no XHR2 but throws on binary (trac-11426)\n\t\t\t\t\t\t\t\t\t// For XHR2 non-text, let the caller handle it (gh-2498)\n\t\t\t\t\t\t\t\t\t( xhr.responseType || \"text\" ) !== \"text\" ||\n\t\t\t\t\t\t\t\t\ttypeof xhr.responseText !== \"string\" ?\n\t\t\t\t\t\t\t\t\t\t{ binary: xhr.response } :\n\t\t\t\t\t\t\t\t\t\t{ text: xhr.responseText },\n\t\t\t\t\t\t\t\t\txhr.getAllResponseHeaders()\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\t// Listen to events\n\t\t\t\txhr.onload = callback();\n\t\t\t\terrorCallback = xhr.onerror = xhr.ontimeout = callback( \"error\" );\n\n\t\t\t\t// Support: IE 9 only\n\t\t\t\t// Use onreadystatechange to replace onabort\n\t\t\t\t// to handle uncaught aborts\n\t\t\t\tif ( xhr.onabort !== undefined ) {\n\t\t\t\t\txhr.onabort = errorCallback;\n\t\t\t\t} else {\n\t\t\t\t\txhr.onreadystatechange = function() {\n\n\t\t\t\t\t\t// Check readyState before timeout as it changes\n\t\t\t\t\t\tif ( xhr.readyState === 4 ) {\n\n\t\t\t\t\t\t\t// Allow onerror to be called first,\n\t\t\t\t\t\t\t// but that will not handle a native abort\n\t\t\t\t\t\t\t// Also, save errorCallback to a variable\n\t\t\t\t\t\t\t// as xhr.onerror cannot be accessed\n\t\t\t\t\t\t\twindow.setTimeout( function() {\n\t\t\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\t\t\terrorCallback();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Create the abort callback\n\t\t\t\tcallback = callback( \"abort\" );\n\n\t\t\t\ttry {\n\n\t\t\t\t\t// Do send the request (this may raise an exception)\n\t\t\t\t\txhr.send( options.hasContent && options.data || null );\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t// #14683: Only rethrow if this hasn't been notified as an error yet\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\n// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)\njQuery.ajaxPrefilter( function( s ) {\n\tif ( s.crossDomain ) {\n\t\ts.contents.script = false;\n\t}\n} );\n\n// Install script dataType\njQuery.ajaxSetup( {\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, \" +\n\t\t\t\"application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /\\b(?:java|ecma)script\\b/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n} );\n\n// Handle cache's special case and crossDomain\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t}\n} );\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function( s ) {\n\n\t// This transport only deals with cross domain or forced-by-attrs requests\n\tif ( s.crossDomain || s.scriptAttrs ) {\n\t\tvar script, callback;\n\t\treturn {\n\t\t\tsend: function( _, complete ) {\n\t\t\t\tscript = jQuery( \" +Redirecting + + +

            Redirecting

            +

            Redirecting...
            +

            Click here

            + + diff --git a/src/bin/hamcore/wwwroot/index.html b/src/bin/hamcore/wwwroot/index.html new file mode 100644 index 00000000..8faeb33b --- /dev/null +++ b/src/bin/hamcore/wwwroot/index.html @@ -0,0 +1,57 @@ + + + + + + + +SoftEther VPN Server + + + + +

            SoftEther VPN Server / Bridge

            +

            For VPN users:

            + +

            For VPN administrators:

            + + +

             

            + + + + diff --git a/src/bin/vpnweb.cab b/src/bin/vpnweb.cab index 73ed0f0de7a1a5fb46cc568bfa255c080d8da24a..473b1855ed2e54dc6527bb5a0bb0c690e731f3e4 100644 GIT binary patch delta 59255 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

            $!buTo@ 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�^gQx!l2b!W z8xzdyfF2K4qm393GB7bYFgGwaF)=eRF*CPf8UyzWJ2x;lF)=eRF*8~)F9r!JhDe6@ z4FL%RF(L#YlKK)Spl4Kcz82a$CH4Tr$Sb{Xe$(%sZppPZZY^>BRD|`pX=pd*L9J7sCnxzdtN-d*c*c)s0k;hrZX9agYeqI z(#zbOX8&BuA!S8g@wmfhK4X+Z@w7eZ5#MG39?gvq>T;bik>&&$!e}fbbc!NFp?H?k z4W2t$g@LU)pST3KX=mdRtABLw%dN)9eX^GEE)lZ_& A2LJ#7 delta 59252 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

            q_!S#Z!v^>`NyG)^w9J&l|R^%PXI+AAX zX<%Pc%%&i-cQ~0mSlUyoaknDR1;^O3Ym^8?WA4n<;V|>Wpl@^k7V>aBkyE9l(+K=)T1i*xd9qj7$HSr@p&y%4lMd%TX_sW zj)Re`TXGsW$SLB$RtVkq4lID7HfU71)7}5go(bb-FgwPQdNNCb1BpiZL2)gtk>_*V zRKjUAj6Ncvx91q#D4lKkFW$hp%x>!mV=l|z=^WbQ_!axen$EEQXWsn0i`*0oiTLB} zV=1${(aXPPw;+yPN6QV|BhB=WUHjlmy3F~8pnmiaGb4@M3lwiC4e^sBd7WohUHsjy z9Zfiv>seIq*N4x@RPoe%oZPMwBr3m+ZDq#i7n9JGrTq~+F=jp%G|*%;Z;l{S&c?xs z+^etOiq|j6NF}GvVxX_voLnEDq({}zQzIe6l&BgOuh7XMUgrj!-MnUR2u;4S9gKN( zOg^+-Jb1590tYX?2W=yxheKmQGXjdz^LrC&l^LUORQ?se?<~H!r_kP|;fpk2`s5hL41P42-jp9Er%q!T2%e1H(CdG^y21y{0zp?dE)loEGOqDc$h!&-q2)~~ z?2L*9CJ()z%i0QGgwm;Jn;rwsEhbG;3a{r5{^8qGg-&e=Ds&^ zu`IWG15hqAjTlPI-lBvu$XQ5|A$P+=yX9?2NRTs!``uEDx`ro<4}C4s6ve_qfGfi3 zhu~x+>nqw1{R)ebxQfqq&N;Lv=1<1LHE25?OuZ|S@+l#S*_s5iO=GUb1xj8*t=PlW zjnJl8C8`M5GAAIc6@!N21YAucq|&$s-ue2kI2+@;&uJ25a+$=5sQ*)3Ni%G!TBFMf*LDSI2{&0$a+Q$5GorFSD{*fOq_ zun5D~Du64bQbr(JYVOb~8BtL=AFXGgyVugYo3O6g z_S0ElL+tAEW)wroE9Uf$YoLKT>_d?UujYIr%e%jPqA=)>*5{+w*9*rMsd6q~@G3@pgKn zx#m3`HiM$KrU8JmNPn4n0enPN*y@?YxEgVW)CgZref5Ju^VzJp>CTeSuM}>gPj;!h zrJF7CZyrv#(0A}BN=2@t@f?%9BtQe23*1_=(7I6|L*&o0*EaSd_z}+`l3JJW(@Cf~ z9D;B^M4J@5fm>StmdL|Yc6dM8NW8i7r^ew)L$S0y)l^>gCYV`BZcD3gR^nyM-#IN) zIY=k?R&#{8iSS z{fQzlva52*%G!$iPVT{cXL{K8xnq{-?RNYua9SL`d#=LEY{?!OUf%5diuPUFj6j!< zz^~CXCnkv1*-G(*2k6XxH7wILkmS=acEZIxwe}Yw;wbDa`r5+!(saxx@i*udvR+bCxj@;-+njT%ZJ>jZ@2jK}sC!$I0JM|ZKz%kZo^ zgmzxHhpfYD1I&Eh8K0O$)(Nnn6!#>D>Zv@w(P~j62^*XCszAv+b z^7YaibRSaJo8;wFBJt3B%5K5w{Y?efOpNyWH6bqS9go3&hp z_!ywJb`p!a#brAs4s39-O`1lVCEeIt$kDH-G}*h`RhH8j#Xm()+YRp=Gd3u+b7^d8 zKLa{7lg#%0p2bN>b5$aJQ|?Y}gux1Z4>m?5&Kk{_>$S`Fvc+s@_td_7heKxaTBy&7sEDw>&Or_y%0 zO=oL-0&SF!a;`-t&C#RmD7Djqp&U=iAEWN#GlkKjxfk%*Nn9Ik3RHY{Qm zOoFvyeXWs0Qu-*FjL=TlQYmYp;kma?zX^BLCUCA$X^Q`Z2us*_XKAE4G1*tMDh@3Y zUL=zoy?gvR0AAHcWLcQuMPCu+Lt^QG7F9JZ2c;xc0_^#{9&GPvUYox`P~-zU)P^3V zy!cEFZedzy0hQn!AQ`@;)_*>U(y)mMIU8v0-%Ck*-(~hu)HUHj+P(-a+iq10K4{&+YrtX`4Y7aIAmy%@T_+2w{*zSspu12(R{kX8{gimI~M9JQS+g%^2LFpY{`q(NV9`*q+ zK>J@>v#gs?g9U|*Duf|7(vnJ#+zd<~!N2bT8eUl~Z`jh#p_U<>ZUgxD12Wjz8a=3B z)bP!)OSwr;)RFm6CBbO)FPUjzBFE1wm#KaK-od;w5n(>Y65`TQ;P2}fMXuhLpHt(J zO>g00m*K0wf@svLvUkG%C|!kV{FeXOp}?!_ota^sYoGqyQB-~zK`g&D-0XrsaiX~n zP@dkKRlUwxd6ZMp0Dv*6AWyD|G8@R*{rdPcUyP^*2cOS_X-$Cq2fW2gLyqR^< zsYaHT5(=nArCAadC5|){hFQK@#24;`rHD1_aoD~5Uh7lD6MF0Z^MM19A`(xe=4Kp>Fz~-ym$U;Pb~8wW-frCoxoe{m7eb?Xfexa`%rPl# z6wXLXE`1ogi@z3l-^YRF=628kFPYN-lF=$hJs$&D0QzTfTBlEu^iOva6u$j|I$?T_ zsLtHE!G?DC=cP{__HoyHfApl(fZ6b<6V-8SK$pK?jx3{fwJ5nW=aCiVKPO1Ye-Q|P zgz%9X4l^t&i$s*CHP+7?`+|qw@pm4yysVRucg1YxpPua)fmU%MQxdk-N73juv{kS> zS9J-{{;vM9ao!K;=@Pi@(e=vIl8Co$#Wg)8pU|(yl$mRH4Z=VuC3;n`mk!Sk^j3jF zIF(9R#z|N@*%AmM9Lh}u8X7Q2dctdjur+S}Ksg`UOD-}t1`=!AG`C6Ab!57rQuX(c zb~nEWa2wxTPd5KJ9XW;hvQblLmujh5I}pY+c}EguMdT=c5jn(ow$mc`(Y5uOlisIn z_Ow*XAhCvCS?Vrf-sD;3A!DQ>s?3DM<{u);1x=iHr$qltqe4{ayHtc5BiB-yG&A*J z3N{ibicCMV%X=q@Ue{KtFx~wDPs5P>`KMd1BJkIk+)V>h$Red134}@3sp%GsNDsc5 zqtV`ot( zF#V}T7+*sDOzHm<2SN;f8vALGWt0Sxe(Jg4!6pP^P=@WiIdY$NE#D!=oYA1^lwaRA z%niPKD5s8WFL+dx_*@`x4I4~-w|4mRTnb+H1(N7bw2+B`6p$=9(djl$u$b;>#A6`~ zGqrLKac?0OMfj!kroR))kB7$2%Ert3A08Ub2|y1>{Qv2?te^i&{eSqNfF|QJ z=Kt4W7SNpE=_+$CB@S;9hI|s<%u^D~p#D`A$A>W`nFb^aqdD$`q|^EA1M>yi zv_o}rflhNC`{S#W#~o`LJk20=wKCY**l(`^p$t0(ZSY1$wVe)g$I1_q{L+j=v7gi&5CtOq{T|T>QCT96LGg+IJzg;QuR>`(CiSgE==6@XJhe4 znj_I@8;HzWAC|9nLQcuOPTfKA3 zhh&3OB2R{NN`Z}t&O6(4q!#8ZQ)3v0`TfW2qiH(L@~Z}3r|hVg0KQ}nXMwZVwZQYi rUxTwhw)B=o8IuCNE!D0TTna23Q(87N#%|fE)Ms~gaD%51|119k*qPJi diff --git a/src/bin/vpnweb.ocx b/src/bin/vpnweb.ocx index 0fcb24889e386b8ccbcb2ca0959358c691035ea6..6484ad0b4295045ee4d998f2caf0c4b4755be96b 100644 GIT binary patch delta 1603 zcmZ{kdpOez7{`CRBn)x*2M?6`}ZoAre>3S>vlEmAHz~ZQeU5OhGId zCPpB_IE3kT4e9ZbwAV6`Zs?qv`8E>wfEvt(P4z1Ys`;>JIZ7^b<6W~e6vs>^=qo7Q z6l|&HgmCB)Wohf=%fBh!zv2un3u;Kve3U8LUfArpt61^IY0tQF`mh-iQxI|YC0AW~aG}W(YZCYy zTZ9{a8S497(`cOPq2t9(|8gjMw$h~Yvl~ApDWl+#HpiG_v3Lv?OUA5UA!nHEm@H8M z$w9G5DB{|yvE^djE~v8HnYzj4<`HI_hCfE(mk9)d0nm65;Of8Tsm0k;P8org)T!Co zmA8B;y=arJEqqtDdyK~1>XIGx`gA@>`Bstf9Wcb0@0XIVG{L{8coA2^jbumJBzmW- zZyaK@I2cEe0am2F_|7BIki}^Y*S;nL2yc;uYhL;aB{%)^t%wGwrRy`{{gC z@X8UURSRh7@Ort{igc3wJEWqcb@}?l-NUR1C?pq6t?nfSsO`s<5B9RU2pMY^^qaQs zRCkqk^SQq7##LRP6O<*O&aOv^s?pwS*E%v<8qq{>7=7l|HtJWaW33J*Os={tJv1(R zx|D_5d;U`z%JMrJp6lq<_O@KkwpL5La^g{4an!z$?p@rQYhbb31Njrq2+o5+_(Fji zOl(DAchmT1Pz?b}!*HVnoYY?6qydXr#olcfWo8~K3~xkshm$YjR~&6VCObfDbi+?3 zmBvu7`Ta-2gtM(gEh4^f2mvV&Yes*A}dH}GG(>wG;MuCgHyiOPaY zyAU4Ld>qR{E-=uCzI0&wr-zCUC0U7MY?tKOE>b*O818)e!`fSq+g)hPrPa&(AK=Ww zik+T1sI~CK{w0?biWA^|^E`2HZF7f8PatD=Cr}h5!(l96z?Vcl5A7KDHqrG*%6P9kfwI#ni{yDb{JaQDm45q4_Z^>1C0<_Qfs>JoU zgoT-Qvhv8~Q>m@bQIVd?7U=AOoO9N>=}3sEvggyR`9POyS>;g5@`Y->23Ap{G^O6i zyXi8IJBxmhXOIhaD_Ue`L_YD^IVUq|9_xOmXAM^n*gjopr@#nwJfdBSBrh}^ zqu5i91yWLzN`_EMf4v~gzo6p;cMV{YmD_&pWQ@r#rhkC13)P0Iwjr(NAaZJHNpz7= zE{4}(vfW!Jveq{`VJ0f`MLl=I6z0T+oG#N0rZfj$@rCbnKUf1Vepu-zfzSRiV?^w6 zR#WWAQ)9gfbN9M^_zZF#YfNkM^PbQgzkp7P`Z>jlB|dttJ8k)frjEYP#rG%3^9JCQ z3&vGXuV-4>4)xY)rS^9k*Cd2U!ID)mg}lN?#0^yYk7th#^lf$8rR2|Me)5-LN9Jbp zxUr-&lLsrC?i|}3McY^v9$(}Li3;dv-M^ZCn^)kvy>(SX>Yz@I#%TV#%rIe4km9mKvu}N7%e@5$jprbNh9-p3VIuXx~zs eyJ1_$`LfcF6^uj?t+8cbXTQoIY*rQkfIk7sGt))@ delta 1603 zcmZ{kdpOez7{`Cxep8f7%m`^L8c9D}V=f)$8Zt|k=%_GVM#*I^xeU3aT$5)rcUGc@ zM8~W`E~$j&q)?KMbHq@&HgV>3I?w5^bN+eX=Y784=lMR*_xU_;(??X(M^qgS2C^F? ze$F+39YB;$BQHk7Qlnuoel!g3S^iz&4^_Yy2@1Ql>{JV-g|_$ZR;7gvE)VfX2H{Os z|2R0Rh*QMv?x&d;dw*XHo`f+nHNz9kjEERKWMnF%1YG-;kg7>R@HHtQB|>%^00Pf- z0O0%PM?C^*Fl9Vo3K#$w0Qx>n0b_s!K>YD8&;jv3nq@brPeP5O3p`31GdqasN@lf! z>d^wUF`XX^NA{pla&d`cNx?{=?K^#Q*Ff?UVSf8O+gk-mW=Rz$$>;1nT6HT2hMuU= zE!y7dTsipF#UXH$Rh<-b@={yM%TTm-vY>b>kH*j~iZo>@tv0v~9)>+L74O}a;v zGYftD=J#qls?M+)<9q}!g2M^NBN-M3T@LTWy*H&?;P-9V#j40&79LMBg75@9-V4G? zN$aQVPx&GXlLn2@Ac~S>gCsA`O4`dC_2jFhTIiE~sgUds6AXp~z(g2;|6Fh|-Wb^` zlF6W#rn+wWs`GBUpRVM%d+zJxv_bUmq3&pl2-rNMoEGO&4;@<*S5i~7;*wTRNJUyJ zvAhYvxp`}_hZ0u7$U+5)ckXJhN89pny&V>Ox_`@#*3K&wjS^$e%Wg$$7r2+WSuvTX zRZ=_E=hHefBP=RRWhiE2$vv_C>l2&?udbarhW=fpN3k<4-cS4^Ux-J2Lab2|t2VXU zLEx^lx5H*P6rMv+D-sUsB`R-oqcW6^+jgBSUS~@JxT|6IqN?4W@fz|b6m?DwLKQ`( z)ZIJ0;?)BwT9l1B>H6ljn4dM-@S=hGS#k^#I`fzMufIws%;k%4>>4#>EM_6OW3qV4 zLp_}{5i)$|d8{*EIj%W@ZUo8e?>qU-X^`)vj*Q&Q0<30h^=KgX*{k~MUXs$m46WXH zj4LmyDfq*p!8}*{KN>E}xm(SQD!(ywRk%wqA&n`I-e&7$=`q$-R*DhWVkeoVk8uH0 z!u+r=K0+g8Jfm&CnNjq6>F8`>Y}y1=1ux}{&Nmi%Ig&18wAm>of~F>G(yH!cr^ zQ=)>pDviPiyA;#E(oP_f=8gk@K%U07Rboq)ey6_97MlB4t)~tEI(5#)0 zz20p07v=pLfNSv2%D(-!=j4pX5i5g2I~{uQYzD=B!J$((tj_yv`>A6lDdYPp!#b|p z(mrwZqQo6gh9hx;x}&87T*i4JO3ozWsco6mw;vBGwZGT3R`5AYw5gA;-{PMBvcbD1 zaloGcIk97W=7P2~dkKe(vv2Ox@m&@vwiyPJWw1Df9;M2GP{~s;l$b^3$YtG%hNIm2 zJF;^PUs`CzSSvG4%2vsrg3MLr|9(Nxzn~NN0zKrHP3AvtFKEvXroVx&4Pr3yZ3&ic zTQH5;HQ*mPmP6&axTB35X5u0Z^p)wu*`@4hBGQRJ+sl^1YxvmX&y|17Ln%livHgnvI_4B9*zaU--16J#P6W;L_de+ufB+r6$70rw4a|vFh+ALgE)U`q>cKbhflB{xg~i*tIZ*f6ZF~0mkr}8oqqB@2&Q}A zO+7f7eMbey<_)~Bkn_{0rVB*Rj+Lx|S(TE^@VtSxyoH+^<*RSH-cE|BPeUitV~JE9 iarlaYa>O;F=5XM8vIS0Sn)R{O5jr>QflS^A0Ki{xLCH`6 diff --git a/src/makefiles/freebsd_32bit.mak b/src/makefiles/freebsd_32bit.mak index 4a2c8d70..8dbf6ea3 100644 --- a/src/makefiles/freebsd_32bit.mak +++ b/src/makefiles/freebsd_32bit.mak @@ -89,7 +89,7 @@ HEADERS_MAYAQUA=src/Mayaqua/Cfg.h src/Mayaqua/cryptoki.h src/Mayaqua/Encrypt.h s HEADERS_CEDAR=src/Cedar/Account.h src/Cedar/Admin.h src/Cedar/AzureClient.h src/Cedar/AzureServer.h src/Cedar/Bridge.h src/Cedar/BridgeUnix.h src/Cedar/BridgeWin32.h src/Cedar/Cedar.h src/Cedar/CedarPch.h src/Cedar/CedarType.h src/Cedar/Client.h src/Cedar/CM.h src/Cedar/CMInner.h src/Cedar/Command.h src/Cedar/Connection.h src/Cedar/Console.h src/Cedar/Database.h src/Cedar/DDNS.h src/Cedar/EM.h src/Cedar/EMInner.h src/Cedar/EtherLog.h src/Cedar/Hub.h src/Cedar/Interop_OpenVPN.h src/Cedar/Interop_SSTP.h src/Cedar/IPsec.h src/Cedar/IPsec_EtherIP.h src/Cedar/IPsec_IKE.h src/Cedar/IPsec_IkePacket.h src/Cedar/IPsec_IPC.h src/Cedar/IPsec_L2TP.h src/Cedar/IPsec_PPP.h src/Cedar/IPsec_Win7.h src/Cedar/IPsec_Win7Inner.h src/Cedar/Layer3.h src/Cedar/Link.h src/Cedar/Listener.h src/Cedar/Logging.h src/Cedar/Nat.h src/Cedar/NativeStack.h src/Cedar/netcfgn.h src/Cedar/netcfgx.h src/Cedar/NM.h src/Cedar/NMInner.h src/Cedar/NullLan.h src/Cedar/Protocol.h src/Cedar/Radius.h src/Cedar/Remote.h src/Cedar/Sam.h src/Cedar/SecureInfo.h src/Cedar/SecureNAT.h src/Cedar/SeLowUser.h src/Cedar/Server.h src/Cedar/Session.h src/Cedar/SM.h src/Cedar/SMInner.h src/Cedar/SW.h src/Cedar/SWInner.h src/Cedar/UdpAccel.h src/Cedar/UT.h src/Cedar/VG.h src/Cedar/Virtual.h src/Cedar/VLan.h src/Cedar/VLanUnix.h src/Cedar/VLanWin32.h src/Cedar/WaterMark.h src/Cedar/WebUI.h src/Cedar/Win32Com.h src/Cedar/winpcap/bittypes.h src/Cedar/winpcap/bucket_lookup.h src/Cedar/winpcap/count_packets.h src/Cedar/winpcap/Devioctl.h src/Cedar/winpcap/Gnuc.h src/Cedar/winpcap/ip6_misc.h src/Cedar/winpcap/memory_t.h src/Cedar/winpcap/normal_lookup.h src/Cedar/winpcap/Ntddndis.h src/Cedar/winpcap/Ntddpack.h src/Cedar/winpcap/Packet32.h src/Cedar/winpcap/pcap.h src/Cedar/winpcap/pcap-bpf.h src/Cedar/winpcap/pcap-int.h src/Cedar/winpcap/pcap-stdinc.h src/Cedar/winpcap/pthread.h src/Cedar/winpcap/remote-ext.h src/Cedar/winpcap/sched.h src/Cedar/winpcap/semaphore.h src/Cedar/winpcap/tcp_session.h src/Cedar/winpcap/time_calls.h src/Cedar/winpcap/tme.h src/Cedar/winpcap/Win32-Extensions.h src/Cedar/WinUi.h src/Cedar/Wpc.h OBJECTS_MAYAQUA=tmp/objs/Mayaqua/Cfg.o tmp/objs/Mayaqua/Encrypt.o tmp/objs/Mayaqua/FileIO.o tmp/objs/Mayaqua/Internat.o tmp/objs/Mayaqua/Kernel.o tmp/objs/Mayaqua/Mayaqua.o tmp/objs/Mayaqua/Memory.o tmp/objs/Mayaqua/Microsoft.o tmp/objs/Mayaqua/Network.o tmp/objs/Mayaqua/Object.o tmp/objs/Mayaqua/OS.o tmp/objs/Mayaqua/Pack.o tmp/objs/Mayaqua/Secure.o tmp/objs/Mayaqua/Str.o tmp/objs/Mayaqua/Table.o tmp/objs/Mayaqua/TcpIp.o tmp/objs/Mayaqua/Tick64.o tmp/objs/Mayaqua/Tracking.o tmp/objs/Mayaqua/Unix.o tmp/objs/Mayaqua/Win32.o OBJECTS_CEDAR=tmp/objs/Cedar/Account.o tmp/objs/Cedar/Admin.o tmp/objs/Cedar/AzureClient.o tmp/objs/Cedar/AzureServer.o tmp/objs/Cedar/Bridge.o tmp/objs/Cedar/BridgeUnix.o tmp/objs/Cedar/BridgeWin32.o tmp/objs/Cedar/Cedar.o tmp/objs/Cedar/CedarPch.o tmp/objs/Cedar/Client.o tmp/objs/Cedar/CM.o tmp/objs/Cedar/Command.o tmp/objs/Cedar/Connection.o tmp/objs/Cedar/Console.o tmp/objs/Cedar/Database.o tmp/objs/Cedar/DDNS.o tmp/objs/Cedar/EM.o tmp/objs/Cedar/EtherLog.o tmp/objs/Cedar/Hub.o tmp/objs/Cedar/Interop_OpenVPN.o tmp/objs/Cedar/Interop_SSTP.o tmp/objs/Cedar/IPsec.o tmp/objs/Cedar/IPsec_EtherIP.o tmp/objs/Cedar/IPsec_IKE.o tmp/objs/Cedar/IPsec_IkePacket.o tmp/objs/Cedar/IPsec_IPC.o tmp/objs/Cedar/IPsec_L2TP.o tmp/objs/Cedar/IPsec_PPP.o tmp/objs/Cedar/IPsec_Win7.o tmp/objs/Cedar/Layer3.o tmp/objs/Cedar/Link.o tmp/objs/Cedar/Listener.o tmp/objs/Cedar/Logging.o tmp/objs/Cedar/Nat.o tmp/objs/Cedar/NativeStack.o tmp/objs/Cedar/NM.o tmp/objs/Cedar/NullLan.o tmp/objs/Cedar/Protocol.o tmp/objs/Cedar/Radius.o tmp/objs/Cedar/Remote.o tmp/objs/Cedar/Sam.o tmp/objs/Cedar/SecureInfo.o tmp/objs/Cedar/SecureNAT.o tmp/objs/Cedar/SeLowUser.o tmp/objs/Cedar/Server.o tmp/objs/Cedar/Session.o tmp/objs/Cedar/SM.o tmp/objs/Cedar/SW.o tmp/objs/Cedar/UdpAccel.o tmp/objs/Cedar/UT.o tmp/objs/Cedar/VG.o tmp/objs/Cedar/Virtual.o tmp/objs/Cedar/VLan.o tmp/objs/Cedar/VLanUnix.o tmp/objs/Cedar/VLanWin32.o tmp/objs/Cedar/WaterMark.o tmp/objs/Cedar/WebUI.o tmp/objs/Cedar/WinUi.o tmp/objs/Cedar/Wpc.o -HAMCORE_FILES=src/bin/hamcore/authors.txt src/bin/hamcore/backup_dir_readme.txt src/bin/hamcore/empty.config src/bin/hamcore/empty_sevpnclient.config src/bin/hamcore/eula.txt src/bin/hamcore/install_src.dat src/bin/hamcore/lang.config src/bin/hamcore/languages.txt src/bin/hamcore/languages_wine.txt src/bin/hamcore/legal.txt src/bin/hamcore/openvpn_readme.pdf src/bin/hamcore/openvpn_readme.txt src/bin/hamcore/openvpn_sample.ovpn src/bin/hamcore/root_certs.dat src/bin/hamcore/SOURCES_OF_BINARY_FILES.TXT src/bin/hamcore/strtable_cn.stb src/bin/hamcore/strtable_en.stb src/bin/hamcore/strtable_ja.stb src/bin/hamcore/vpnweb_sample_cn.htm src/bin/hamcore/vpnweb_sample_en.htm src/bin/hamcore/vpnweb_sample_ja.htm src/bin/hamcore/warning_cn.txt src/bin/hamcore/warning_en.txt src/bin/hamcore/warning_ja.txt src/bin/hamcore/webui/cryptcom.cgi src/bin/hamcore/webui/edituser.cgi src/bin/hamcore/webui/error.cgi src/bin/hamcore/webui/hub.cgi src/bin/hamcore/webui/license.cgi src/bin/hamcore/webui/listener.cgi src/bin/hamcore/webui/localbridge.cgi src/bin/hamcore/webui/login.cgi src/bin/hamcore/webui/newhub.cgi src/bin/hamcore/webui/redirect.cgi src/bin/hamcore/webui/securenat.cgi src/bin/hamcore/webui/server.cgi src/bin/hamcore/webui/session.cgi src/bin/hamcore/webui/user.cgi src/bin/hamcore/webui/webui.css +HAMCORE_FILES=src/bin/hamcore/authors.txt src/bin/hamcore/backup_dir_readme.txt src/bin/hamcore/empty.config src/bin/hamcore/empty_sevpnclient.config src/bin/hamcore/eula.txt src/bin/hamcore/install_src.dat src/bin/hamcore/languages.txt src/bin/hamcore/languages_wine.txt src/bin/hamcore/legal.txt src/bin/hamcore/openvpn_readme.pdf src/bin/hamcore/openvpn_readme.txt src/bin/hamcore/openvpn_sample.ovpn src/bin/hamcore/root_certs.dat src/bin/hamcore/SOURCES_OF_BINARY_FILES.TXT src/bin/hamcore/strtable_cn.stb src/bin/hamcore/strtable_en.stb src/bin/hamcore/strtable_ja.stb src/bin/hamcore/vpnserver_api_doc.html src/bin/hamcore/vpnweb_sample_cn.htm src/bin/hamcore/vpnweb_sample_en.htm src/bin/hamcore/vpnweb_sample_ja.htm src/bin/hamcore/warning_cn.txt src/bin/hamcore/warning_en.txt src/bin/hamcore/warning_ja.txt src/bin/hamcore/webui/cryptcom.cgi src/bin/hamcore/webui/edituser.cgi src/bin/hamcore/webui/error.cgi src/bin/hamcore/webui/hub.cgi src/bin/hamcore/webui/license.cgi src/bin/hamcore/webui/listener.cgi src/bin/hamcore/webui/localbridge.cgi src/bin/hamcore/webui/login.cgi src/bin/hamcore/webui/newhub.cgi src/bin/hamcore/webui/redirect.cgi src/bin/hamcore/webui/securenat.cgi src/bin/hamcore/webui/server.cgi src/bin/hamcore/webui/session.cgi src/bin/hamcore/webui/user.cgi src/bin/hamcore/webui/webui.css src/bin/hamcore/wwwroot/admin/default/.gitignore src/bin/hamcore/wwwroot/admin/default/.vscode/launch.json src/bin/hamcore/wwwroot/admin/default/.vscode/settings.json src/bin/hamcore/wwwroot/admin/default/.vscode/tasks.json src/bin/hamcore/wwwroot/admin/default/hub.html src/bin/hamcore/wwwroot/admin/default/include_footer.html src/bin/hamcore/wwwroot/admin/default/include_head.html src/bin/hamcore/wwwroot/admin/default/include_menu.html src/bin/hamcore/wwwroot/admin/default/index.html src/bin/hamcore/wwwroot/admin/default/out_webpack/bundle.js src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/index.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/index.d.ts.map src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/main.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/main.d.ts.map src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/vpnadmin.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/vpnadmin.d.ts.map src/bin/hamcore/wwwroot/admin/default/package.json src/bin/hamcore/wwwroot/admin/default/package-lock.json src/bin/hamcore/wwwroot/admin/default/src/ts/main.ts src/bin/hamcore/wwwroot/admin/default/theme.css src/bin/hamcore/wwwroot/admin/default/tsconfig.json src/bin/hamcore/wwwroot/admin/default/tsconfig_webpack.json src/bin/hamcore/wwwroot/admin/default/tslint.json src/bin/hamcore/wwwroot/admin/default/webpack.config.js src/bin/hamcore/wwwroot/admin/index.html src/bin/hamcore/wwwroot/admin/README.md src/bin/hamcore/wwwroot/index.html # Build Action default: build diff --git a/src/makefiles/freebsd_64bit.mak b/src/makefiles/freebsd_64bit.mak index 8819752e..5180f457 100644 --- a/src/makefiles/freebsd_64bit.mak +++ b/src/makefiles/freebsd_64bit.mak @@ -89,7 +89,7 @@ HEADERS_MAYAQUA=src/Mayaqua/Cfg.h src/Mayaqua/cryptoki.h src/Mayaqua/Encrypt.h s HEADERS_CEDAR=src/Cedar/Account.h src/Cedar/Admin.h src/Cedar/AzureClient.h src/Cedar/AzureServer.h src/Cedar/Bridge.h src/Cedar/BridgeUnix.h src/Cedar/BridgeWin32.h src/Cedar/Cedar.h src/Cedar/CedarPch.h src/Cedar/CedarType.h src/Cedar/Client.h src/Cedar/CM.h src/Cedar/CMInner.h src/Cedar/Command.h src/Cedar/Connection.h src/Cedar/Console.h src/Cedar/Database.h src/Cedar/DDNS.h src/Cedar/EM.h src/Cedar/EMInner.h src/Cedar/EtherLog.h src/Cedar/Hub.h src/Cedar/Interop_OpenVPN.h src/Cedar/Interop_SSTP.h src/Cedar/IPsec.h src/Cedar/IPsec_EtherIP.h src/Cedar/IPsec_IKE.h src/Cedar/IPsec_IkePacket.h src/Cedar/IPsec_IPC.h src/Cedar/IPsec_L2TP.h src/Cedar/IPsec_PPP.h src/Cedar/IPsec_Win7.h src/Cedar/IPsec_Win7Inner.h src/Cedar/Layer3.h src/Cedar/Link.h src/Cedar/Listener.h src/Cedar/Logging.h src/Cedar/Nat.h src/Cedar/NativeStack.h src/Cedar/netcfgn.h src/Cedar/netcfgx.h src/Cedar/NM.h src/Cedar/NMInner.h src/Cedar/NullLan.h src/Cedar/Protocol.h src/Cedar/Radius.h src/Cedar/Remote.h src/Cedar/Sam.h src/Cedar/SecureInfo.h src/Cedar/SecureNAT.h src/Cedar/SeLowUser.h src/Cedar/Server.h src/Cedar/Session.h src/Cedar/SM.h src/Cedar/SMInner.h src/Cedar/SW.h src/Cedar/SWInner.h src/Cedar/UdpAccel.h src/Cedar/UT.h src/Cedar/VG.h src/Cedar/Virtual.h src/Cedar/VLan.h src/Cedar/VLanUnix.h src/Cedar/VLanWin32.h src/Cedar/WaterMark.h src/Cedar/WebUI.h src/Cedar/Win32Com.h src/Cedar/winpcap/bittypes.h src/Cedar/winpcap/bucket_lookup.h src/Cedar/winpcap/count_packets.h src/Cedar/winpcap/Devioctl.h src/Cedar/winpcap/Gnuc.h src/Cedar/winpcap/ip6_misc.h src/Cedar/winpcap/memory_t.h src/Cedar/winpcap/normal_lookup.h src/Cedar/winpcap/Ntddndis.h src/Cedar/winpcap/Ntddpack.h src/Cedar/winpcap/Packet32.h src/Cedar/winpcap/pcap.h src/Cedar/winpcap/pcap-bpf.h src/Cedar/winpcap/pcap-int.h src/Cedar/winpcap/pcap-stdinc.h src/Cedar/winpcap/pthread.h src/Cedar/winpcap/remote-ext.h src/Cedar/winpcap/sched.h src/Cedar/winpcap/semaphore.h src/Cedar/winpcap/tcp_session.h src/Cedar/winpcap/time_calls.h src/Cedar/winpcap/tme.h src/Cedar/winpcap/Win32-Extensions.h src/Cedar/WinUi.h src/Cedar/Wpc.h OBJECTS_MAYAQUA=tmp/objs/Mayaqua/Cfg.o tmp/objs/Mayaqua/Encrypt.o tmp/objs/Mayaqua/FileIO.o tmp/objs/Mayaqua/Internat.o tmp/objs/Mayaqua/Kernel.o tmp/objs/Mayaqua/Mayaqua.o tmp/objs/Mayaqua/Memory.o tmp/objs/Mayaqua/Microsoft.o tmp/objs/Mayaqua/Network.o tmp/objs/Mayaqua/Object.o tmp/objs/Mayaqua/OS.o tmp/objs/Mayaqua/Pack.o tmp/objs/Mayaqua/Secure.o tmp/objs/Mayaqua/Str.o tmp/objs/Mayaqua/Table.o tmp/objs/Mayaqua/TcpIp.o tmp/objs/Mayaqua/Tick64.o tmp/objs/Mayaqua/Tracking.o tmp/objs/Mayaqua/Unix.o tmp/objs/Mayaqua/Win32.o OBJECTS_CEDAR=tmp/objs/Cedar/Account.o tmp/objs/Cedar/Admin.o tmp/objs/Cedar/AzureClient.o tmp/objs/Cedar/AzureServer.o tmp/objs/Cedar/Bridge.o tmp/objs/Cedar/BridgeUnix.o tmp/objs/Cedar/BridgeWin32.o tmp/objs/Cedar/Cedar.o tmp/objs/Cedar/CedarPch.o tmp/objs/Cedar/Client.o tmp/objs/Cedar/CM.o tmp/objs/Cedar/Command.o tmp/objs/Cedar/Connection.o tmp/objs/Cedar/Console.o tmp/objs/Cedar/Database.o tmp/objs/Cedar/DDNS.o tmp/objs/Cedar/EM.o tmp/objs/Cedar/EtherLog.o tmp/objs/Cedar/Hub.o tmp/objs/Cedar/Interop_OpenVPN.o tmp/objs/Cedar/Interop_SSTP.o tmp/objs/Cedar/IPsec.o tmp/objs/Cedar/IPsec_EtherIP.o tmp/objs/Cedar/IPsec_IKE.o tmp/objs/Cedar/IPsec_IkePacket.o tmp/objs/Cedar/IPsec_IPC.o tmp/objs/Cedar/IPsec_L2TP.o tmp/objs/Cedar/IPsec_PPP.o tmp/objs/Cedar/IPsec_Win7.o tmp/objs/Cedar/Layer3.o tmp/objs/Cedar/Link.o tmp/objs/Cedar/Listener.o tmp/objs/Cedar/Logging.o tmp/objs/Cedar/Nat.o tmp/objs/Cedar/NativeStack.o tmp/objs/Cedar/NM.o tmp/objs/Cedar/NullLan.o tmp/objs/Cedar/Protocol.o tmp/objs/Cedar/Radius.o tmp/objs/Cedar/Remote.o tmp/objs/Cedar/Sam.o tmp/objs/Cedar/SecureInfo.o tmp/objs/Cedar/SecureNAT.o tmp/objs/Cedar/SeLowUser.o tmp/objs/Cedar/Server.o tmp/objs/Cedar/Session.o tmp/objs/Cedar/SM.o tmp/objs/Cedar/SW.o tmp/objs/Cedar/UdpAccel.o tmp/objs/Cedar/UT.o tmp/objs/Cedar/VG.o tmp/objs/Cedar/Virtual.o tmp/objs/Cedar/VLan.o tmp/objs/Cedar/VLanUnix.o tmp/objs/Cedar/VLanWin32.o tmp/objs/Cedar/WaterMark.o tmp/objs/Cedar/WebUI.o tmp/objs/Cedar/WinUi.o tmp/objs/Cedar/Wpc.o -HAMCORE_FILES=src/bin/hamcore/authors.txt src/bin/hamcore/backup_dir_readme.txt src/bin/hamcore/empty.config src/bin/hamcore/empty_sevpnclient.config src/bin/hamcore/eula.txt src/bin/hamcore/install_src.dat src/bin/hamcore/lang.config src/bin/hamcore/languages.txt src/bin/hamcore/languages_wine.txt src/bin/hamcore/legal.txt src/bin/hamcore/openvpn_readme.pdf src/bin/hamcore/openvpn_readme.txt src/bin/hamcore/openvpn_sample.ovpn src/bin/hamcore/root_certs.dat src/bin/hamcore/SOURCES_OF_BINARY_FILES.TXT src/bin/hamcore/strtable_cn.stb src/bin/hamcore/strtable_en.stb src/bin/hamcore/strtable_ja.stb src/bin/hamcore/vpnweb_sample_cn.htm src/bin/hamcore/vpnweb_sample_en.htm src/bin/hamcore/vpnweb_sample_ja.htm src/bin/hamcore/warning_cn.txt src/bin/hamcore/warning_en.txt src/bin/hamcore/warning_ja.txt src/bin/hamcore/webui/cryptcom.cgi src/bin/hamcore/webui/edituser.cgi src/bin/hamcore/webui/error.cgi src/bin/hamcore/webui/hub.cgi src/bin/hamcore/webui/license.cgi src/bin/hamcore/webui/listener.cgi src/bin/hamcore/webui/localbridge.cgi src/bin/hamcore/webui/login.cgi src/bin/hamcore/webui/newhub.cgi src/bin/hamcore/webui/redirect.cgi src/bin/hamcore/webui/securenat.cgi src/bin/hamcore/webui/server.cgi src/bin/hamcore/webui/session.cgi src/bin/hamcore/webui/user.cgi src/bin/hamcore/webui/webui.css +HAMCORE_FILES=src/bin/hamcore/authors.txt src/bin/hamcore/backup_dir_readme.txt src/bin/hamcore/empty.config src/bin/hamcore/empty_sevpnclient.config src/bin/hamcore/eula.txt src/bin/hamcore/install_src.dat src/bin/hamcore/languages.txt src/bin/hamcore/languages_wine.txt src/bin/hamcore/legal.txt src/bin/hamcore/openvpn_readme.pdf src/bin/hamcore/openvpn_readme.txt src/bin/hamcore/openvpn_sample.ovpn src/bin/hamcore/root_certs.dat src/bin/hamcore/SOURCES_OF_BINARY_FILES.TXT src/bin/hamcore/strtable_cn.stb src/bin/hamcore/strtable_en.stb src/bin/hamcore/strtable_ja.stb src/bin/hamcore/vpnserver_api_doc.html src/bin/hamcore/vpnweb_sample_cn.htm src/bin/hamcore/vpnweb_sample_en.htm src/bin/hamcore/vpnweb_sample_ja.htm src/bin/hamcore/warning_cn.txt src/bin/hamcore/warning_en.txt src/bin/hamcore/warning_ja.txt src/bin/hamcore/webui/cryptcom.cgi src/bin/hamcore/webui/edituser.cgi src/bin/hamcore/webui/error.cgi src/bin/hamcore/webui/hub.cgi src/bin/hamcore/webui/license.cgi src/bin/hamcore/webui/listener.cgi src/bin/hamcore/webui/localbridge.cgi src/bin/hamcore/webui/login.cgi src/bin/hamcore/webui/newhub.cgi src/bin/hamcore/webui/redirect.cgi src/bin/hamcore/webui/securenat.cgi src/bin/hamcore/webui/server.cgi src/bin/hamcore/webui/session.cgi src/bin/hamcore/webui/user.cgi src/bin/hamcore/webui/webui.css src/bin/hamcore/wwwroot/admin/default/.gitignore src/bin/hamcore/wwwroot/admin/default/.vscode/launch.json src/bin/hamcore/wwwroot/admin/default/.vscode/settings.json src/bin/hamcore/wwwroot/admin/default/.vscode/tasks.json src/bin/hamcore/wwwroot/admin/default/hub.html src/bin/hamcore/wwwroot/admin/default/include_footer.html src/bin/hamcore/wwwroot/admin/default/include_head.html src/bin/hamcore/wwwroot/admin/default/include_menu.html src/bin/hamcore/wwwroot/admin/default/index.html src/bin/hamcore/wwwroot/admin/default/out_webpack/bundle.js src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/index.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/index.d.ts.map src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/main.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/main.d.ts.map src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/vpnadmin.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/vpnadmin.d.ts.map src/bin/hamcore/wwwroot/admin/default/package.json src/bin/hamcore/wwwroot/admin/default/package-lock.json src/bin/hamcore/wwwroot/admin/default/src/ts/main.ts src/bin/hamcore/wwwroot/admin/default/theme.css src/bin/hamcore/wwwroot/admin/default/tsconfig.json src/bin/hamcore/wwwroot/admin/default/tsconfig_webpack.json src/bin/hamcore/wwwroot/admin/default/tslint.json src/bin/hamcore/wwwroot/admin/default/webpack.config.js src/bin/hamcore/wwwroot/admin/index.html src/bin/hamcore/wwwroot/admin/README.md src/bin/hamcore/wwwroot/index.html # Build Action default: build diff --git a/src/makefiles/linux_32bit.mak b/src/makefiles/linux_32bit.mak index 385bcab8..b4f2ab06 100644 --- a/src/makefiles/linux_32bit.mak +++ b/src/makefiles/linux_32bit.mak @@ -89,7 +89,7 @@ HEADERS_MAYAQUA=src/Mayaqua/Cfg.h src/Mayaqua/cryptoki.h src/Mayaqua/Encrypt.h s HEADERS_CEDAR=src/Cedar/Account.h src/Cedar/Admin.h src/Cedar/AzureClient.h src/Cedar/AzureServer.h src/Cedar/Bridge.h src/Cedar/BridgeUnix.h src/Cedar/BridgeWin32.h src/Cedar/Cedar.h src/Cedar/CedarPch.h src/Cedar/CedarType.h src/Cedar/Client.h src/Cedar/CM.h src/Cedar/CMInner.h src/Cedar/Command.h src/Cedar/Connection.h src/Cedar/Console.h src/Cedar/Database.h src/Cedar/DDNS.h src/Cedar/EM.h src/Cedar/EMInner.h src/Cedar/EtherLog.h src/Cedar/Hub.h src/Cedar/Interop_OpenVPN.h src/Cedar/Interop_SSTP.h src/Cedar/IPsec.h src/Cedar/IPsec_EtherIP.h src/Cedar/IPsec_IKE.h src/Cedar/IPsec_IkePacket.h src/Cedar/IPsec_IPC.h src/Cedar/IPsec_L2TP.h src/Cedar/IPsec_PPP.h src/Cedar/IPsec_Win7.h src/Cedar/IPsec_Win7Inner.h src/Cedar/Layer3.h src/Cedar/Link.h src/Cedar/Listener.h src/Cedar/Logging.h src/Cedar/Nat.h src/Cedar/NativeStack.h src/Cedar/netcfgn.h src/Cedar/netcfgx.h src/Cedar/NM.h src/Cedar/NMInner.h src/Cedar/NullLan.h src/Cedar/Protocol.h src/Cedar/Radius.h src/Cedar/Remote.h src/Cedar/Sam.h src/Cedar/SecureInfo.h src/Cedar/SecureNAT.h src/Cedar/SeLowUser.h src/Cedar/Server.h src/Cedar/Session.h src/Cedar/SM.h src/Cedar/SMInner.h src/Cedar/SW.h src/Cedar/SWInner.h src/Cedar/UdpAccel.h src/Cedar/UT.h src/Cedar/VG.h src/Cedar/Virtual.h src/Cedar/VLan.h src/Cedar/VLanUnix.h src/Cedar/VLanWin32.h src/Cedar/WaterMark.h src/Cedar/WebUI.h src/Cedar/Win32Com.h src/Cedar/winpcap/bittypes.h src/Cedar/winpcap/bucket_lookup.h src/Cedar/winpcap/count_packets.h src/Cedar/winpcap/Devioctl.h src/Cedar/winpcap/Gnuc.h src/Cedar/winpcap/ip6_misc.h src/Cedar/winpcap/memory_t.h src/Cedar/winpcap/normal_lookup.h src/Cedar/winpcap/Ntddndis.h src/Cedar/winpcap/Ntddpack.h src/Cedar/winpcap/Packet32.h src/Cedar/winpcap/pcap.h src/Cedar/winpcap/pcap-bpf.h src/Cedar/winpcap/pcap-int.h src/Cedar/winpcap/pcap-stdinc.h src/Cedar/winpcap/pthread.h src/Cedar/winpcap/remote-ext.h src/Cedar/winpcap/sched.h src/Cedar/winpcap/semaphore.h src/Cedar/winpcap/tcp_session.h src/Cedar/winpcap/time_calls.h src/Cedar/winpcap/tme.h src/Cedar/winpcap/Win32-Extensions.h src/Cedar/WinUi.h src/Cedar/Wpc.h OBJECTS_MAYAQUA=tmp/objs/Mayaqua/Cfg.o tmp/objs/Mayaqua/Encrypt.o tmp/objs/Mayaqua/FileIO.o tmp/objs/Mayaqua/Internat.o tmp/objs/Mayaqua/Kernel.o tmp/objs/Mayaqua/Mayaqua.o tmp/objs/Mayaqua/Memory.o tmp/objs/Mayaqua/Microsoft.o tmp/objs/Mayaqua/Network.o tmp/objs/Mayaqua/Object.o tmp/objs/Mayaqua/OS.o tmp/objs/Mayaqua/Pack.o tmp/objs/Mayaqua/Secure.o tmp/objs/Mayaqua/Str.o tmp/objs/Mayaqua/Table.o tmp/objs/Mayaqua/TcpIp.o tmp/objs/Mayaqua/Tick64.o tmp/objs/Mayaqua/Tracking.o tmp/objs/Mayaqua/Unix.o tmp/objs/Mayaqua/Win32.o OBJECTS_CEDAR=tmp/objs/Cedar/Account.o tmp/objs/Cedar/Admin.o tmp/objs/Cedar/AzureClient.o tmp/objs/Cedar/AzureServer.o tmp/objs/Cedar/Bridge.o tmp/objs/Cedar/BridgeUnix.o tmp/objs/Cedar/BridgeWin32.o tmp/objs/Cedar/Cedar.o tmp/objs/Cedar/CedarPch.o tmp/objs/Cedar/Client.o tmp/objs/Cedar/CM.o tmp/objs/Cedar/Command.o tmp/objs/Cedar/Connection.o tmp/objs/Cedar/Console.o tmp/objs/Cedar/Database.o tmp/objs/Cedar/DDNS.o tmp/objs/Cedar/EM.o tmp/objs/Cedar/EtherLog.o tmp/objs/Cedar/Hub.o tmp/objs/Cedar/Interop_OpenVPN.o tmp/objs/Cedar/Interop_SSTP.o tmp/objs/Cedar/IPsec.o tmp/objs/Cedar/IPsec_EtherIP.o tmp/objs/Cedar/IPsec_IKE.o tmp/objs/Cedar/IPsec_IkePacket.o tmp/objs/Cedar/IPsec_IPC.o tmp/objs/Cedar/IPsec_L2TP.o tmp/objs/Cedar/IPsec_PPP.o tmp/objs/Cedar/IPsec_Win7.o tmp/objs/Cedar/Layer3.o tmp/objs/Cedar/Link.o tmp/objs/Cedar/Listener.o tmp/objs/Cedar/Logging.o tmp/objs/Cedar/Nat.o tmp/objs/Cedar/NativeStack.o tmp/objs/Cedar/NM.o tmp/objs/Cedar/NullLan.o tmp/objs/Cedar/Protocol.o tmp/objs/Cedar/Radius.o tmp/objs/Cedar/Remote.o tmp/objs/Cedar/Sam.o tmp/objs/Cedar/SecureInfo.o tmp/objs/Cedar/SecureNAT.o tmp/objs/Cedar/SeLowUser.o tmp/objs/Cedar/Server.o tmp/objs/Cedar/Session.o tmp/objs/Cedar/SM.o tmp/objs/Cedar/SW.o tmp/objs/Cedar/UdpAccel.o tmp/objs/Cedar/UT.o tmp/objs/Cedar/VG.o tmp/objs/Cedar/Virtual.o tmp/objs/Cedar/VLan.o tmp/objs/Cedar/VLanUnix.o tmp/objs/Cedar/VLanWin32.o tmp/objs/Cedar/WaterMark.o tmp/objs/Cedar/WebUI.o tmp/objs/Cedar/WinUi.o tmp/objs/Cedar/Wpc.o -HAMCORE_FILES=src/bin/hamcore/authors.txt src/bin/hamcore/backup_dir_readme.txt src/bin/hamcore/empty.config src/bin/hamcore/empty_sevpnclient.config src/bin/hamcore/eula.txt src/bin/hamcore/install_src.dat src/bin/hamcore/lang.config src/bin/hamcore/languages.txt src/bin/hamcore/languages_wine.txt src/bin/hamcore/legal.txt src/bin/hamcore/openvpn_readme.pdf src/bin/hamcore/openvpn_readme.txt src/bin/hamcore/openvpn_sample.ovpn src/bin/hamcore/root_certs.dat src/bin/hamcore/SOURCES_OF_BINARY_FILES.TXT src/bin/hamcore/strtable_cn.stb src/bin/hamcore/strtable_en.stb src/bin/hamcore/strtable_ja.stb src/bin/hamcore/vpnweb_sample_cn.htm src/bin/hamcore/vpnweb_sample_en.htm src/bin/hamcore/vpnweb_sample_ja.htm src/bin/hamcore/warning_cn.txt src/bin/hamcore/warning_en.txt src/bin/hamcore/warning_ja.txt src/bin/hamcore/webui/cryptcom.cgi src/bin/hamcore/webui/edituser.cgi src/bin/hamcore/webui/error.cgi src/bin/hamcore/webui/hub.cgi src/bin/hamcore/webui/license.cgi src/bin/hamcore/webui/listener.cgi src/bin/hamcore/webui/localbridge.cgi src/bin/hamcore/webui/login.cgi src/bin/hamcore/webui/newhub.cgi src/bin/hamcore/webui/redirect.cgi src/bin/hamcore/webui/securenat.cgi src/bin/hamcore/webui/server.cgi src/bin/hamcore/webui/session.cgi src/bin/hamcore/webui/user.cgi src/bin/hamcore/webui/webui.css +HAMCORE_FILES=src/bin/hamcore/authors.txt src/bin/hamcore/backup_dir_readme.txt src/bin/hamcore/empty.config src/bin/hamcore/empty_sevpnclient.config src/bin/hamcore/eula.txt src/bin/hamcore/install_src.dat src/bin/hamcore/languages.txt src/bin/hamcore/languages_wine.txt src/bin/hamcore/legal.txt src/bin/hamcore/openvpn_readme.pdf src/bin/hamcore/openvpn_readme.txt src/bin/hamcore/openvpn_sample.ovpn src/bin/hamcore/root_certs.dat src/bin/hamcore/SOURCES_OF_BINARY_FILES.TXT src/bin/hamcore/strtable_cn.stb src/bin/hamcore/strtable_en.stb src/bin/hamcore/strtable_ja.stb src/bin/hamcore/vpnserver_api_doc.html src/bin/hamcore/vpnweb_sample_cn.htm src/bin/hamcore/vpnweb_sample_en.htm src/bin/hamcore/vpnweb_sample_ja.htm src/bin/hamcore/warning_cn.txt src/bin/hamcore/warning_en.txt src/bin/hamcore/warning_ja.txt src/bin/hamcore/webui/cryptcom.cgi src/bin/hamcore/webui/edituser.cgi src/bin/hamcore/webui/error.cgi src/bin/hamcore/webui/hub.cgi src/bin/hamcore/webui/license.cgi src/bin/hamcore/webui/listener.cgi src/bin/hamcore/webui/localbridge.cgi src/bin/hamcore/webui/login.cgi src/bin/hamcore/webui/newhub.cgi src/bin/hamcore/webui/redirect.cgi src/bin/hamcore/webui/securenat.cgi src/bin/hamcore/webui/server.cgi src/bin/hamcore/webui/session.cgi src/bin/hamcore/webui/user.cgi src/bin/hamcore/webui/webui.css src/bin/hamcore/wwwroot/admin/default/.gitignore src/bin/hamcore/wwwroot/admin/default/.vscode/launch.json src/bin/hamcore/wwwroot/admin/default/.vscode/settings.json src/bin/hamcore/wwwroot/admin/default/.vscode/tasks.json src/bin/hamcore/wwwroot/admin/default/hub.html src/bin/hamcore/wwwroot/admin/default/include_footer.html src/bin/hamcore/wwwroot/admin/default/include_head.html src/bin/hamcore/wwwroot/admin/default/include_menu.html src/bin/hamcore/wwwroot/admin/default/index.html src/bin/hamcore/wwwroot/admin/default/out_webpack/bundle.js src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/index.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/index.d.ts.map src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/main.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/main.d.ts.map src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/vpnadmin.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/vpnadmin.d.ts.map src/bin/hamcore/wwwroot/admin/default/package.json src/bin/hamcore/wwwroot/admin/default/package-lock.json src/bin/hamcore/wwwroot/admin/default/src/ts/main.ts src/bin/hamcore/wwwroot/admin/default/theme.css src/bin/hamcore/wwwroot/admin/default/tsconfig.json src/bin/hamcore/wwwroot/admin/default/tsconfig_webpack.json src/bin/hamcore/wwwroot/admin/default/tslint.json src/bin/hamcore/wwwroot/admin/default/webpack.config.js src/bin/hamcore/wwwroot/admin/index.html src/bin/hamcore/wwwroot/admin/README.md src/bin/hamcore/wwwroot/index.html # Build Action default: build diff --git a/src/makefiles/linux_64bit.mak b/src/makefiles/linux_64bit.mak index ff78822c..c078b1b0 100644 --- a/src/makefiles/linux_64bit.mak +++ b/src/makefiles/linux_64bit.mak @@ -89,7 +89,7 @@ HEADERS_MAYAQUA=src/Mayaqua/Cfg.h src/Mayaqua/cryptoki.h src/Mayaqua/Encrypt.h s HEADERS_CEDAR=src/Cedar/Account.h src/Cedar/Admin.h src/Cedar/AzureClient.h src/Cedar/AzureServer.h src/Cedar/Bridge.h src/Cedar/BridgeUnix.h src/Cedar/BridgeWin32.h src/Cedar/Cedar.h src/Cedar/CedarPch.h src/Cedar/CedarType.h src/Cedar/Client.h src/Cedar/CM.h src/Cedar/CMInner.h src/Cedar/Command.h src/Cedar/Connection.h src/Cedar/Console.h src/Cedar/Database.h src/Cedar/DDNS.h src/Cedar/EM.h src/Cedar/EMInner.h src/Cedar/EtherLog.h src/Cedar/Hub.h src/Cedar/Interop_OpenVPN.h src/Cedar/Interop_SSTP.h src/Cedar/IPsec.h src/Cedar/IPsec_EtherIP.h src/Cedar/IPsec_IKE.h src/Cedar/IPsec_IkePacket.h src/Cedar/IPsec_IPC.h src/Cedar/IPsec_L2TP.h src/Cedar/IPsec_PPP.h src/Cedar/IPsec_Win7.h src/Cedar/IPsec_Win7Inner.h src/Cedar/Layer3.h src/Cedar/Link.h src/Cedar/Listener.h src/Cedar/Logging.h src/Cedar/Nat.h src/Cedar/NativeStack.h src/Cedar/netcfgn.h src/Cedar/netcfgx.h src/Cedar/NM.h src/Cedar/NMInner.h src/Cedar/NullLan.h src/Cedar/Protocol.h src/Cedar/Radius.h src/Cedar/Remote.h src/Cedar/Sam.h src/Cedar/SecureInfo.h src/Cedar/SecureNAT.h src/Cedar/SeLowUser.h src/Cedar/Server.h src/Cedar/Session.h src/Cedar/SM.h src/Cedar/SMInner.h src/Cedar/SW.h src/Cedar/SWInner.h src/Cedar/UdpAccel.h src/Cedar/UT.h src/Cedar/VG.h src/Cedar/Virtual.h src/Cedar/VLan.h src/Cedar/VLanUnix.h src/Cedar/VLanWin32.h src/Cedar/WaterMark.h src/Cedar/WebUI.h src/Cedar/Win32Com.h src/Cedar/winpcap/bittypes.h src/Cedar/winpcap/bucket_lookup.h src/Cedar/winpcap/count_packets.h src/Cedar/winpcap/Devioctl.h src/Cedar/winpcap/Gnuc.h src/Cedar/winpcap/ip6_misc.h src/Cedar/winpcap/memory_t.h src/Cedar/winpcap/normal_lookup.h src/Cedar/winpcap/Ntddndis.h src/Cedar/winpcap/Ntddpack.h src/Cedar/winpcap/Packet32.h src/Cedar/winpcap/pcap.h src/Cedar/winpcap/pcap-bpf.h src/Cedar/winpcap/pcap-int.h src/Cedar/winpcap/pcap-stdinc.h src/Cedar/winpcap/pthread.h src/Cedar/winpcap/remote-ext.h src/Cedar/winpcap/sched.h src/Cedar/winpcap/semaphore.h src/Cedar/winpcap/tcp_session.h src/Cedar/winpcap/time_calls.h src/Cedar/winpcap/tme.h src/Cedar/winpcap/Win32-Extensions.h src/Cedar/WinUi.h src/Cedar/Wpc.h OBJECTS_MAYAQUA=tmp/objs/Mayaqua/Cfg.o tmp/objs/Mayaqua/Encrypt.o tmp/objs/Mayaqua/FileIO.o tmp/objs/Mayaqua/Internat.o tmp/objs/Mayaqua/Kernel.o tmp/objs/Mayaqua/Mayaqua.o tmp/objs/Mayaqua/Memory.o tmp/objs/Mayaqua/Microsoft.o tmp/objs/Mayaqua/Network.o tmp/objs/Mayaqua/Object.o tmp/objs/Mayaqua/OS.o tmp/objs/Mayaqua/Pack.o tmp/objs/Mayaqua/Secure.o tmp/objs/Mayaqua/Str.o tmp/objs/Mayaqua/Table.o tmp/objs/Mayaqua/TcpIp.o tmp/objs/Mayaqua/Tick64.o tmp/objs/Mayaqua/Tracking.o tmp/objs/Mayaqua/Unix.o tmp/objs/Mayaqua/Win32.o OBJECTS_CEDAR=tmp/objs/Cedar/Account.o tmp/objs/Cedar/Admin.o tmp/objs/Cedar/AzureClient.o tmp/objs/Cedar/AzureServer.o tmp/objs/Cedar/Bridge.o tmp/objs/Cedar/BridgeUnix.o tmp/objs/Cedar/BridgeWin32.o tmp/objs/Cedar/Cedar.o tmp/objs/Cedar/CedarPch.o tmp/objs/Cedar/Client.o tmp/objs/Cedar/CM.o tmp/objs/Cedar/Command.o tmp/objs/Cedar/Connection.o tmp/objs/Cedar/Console.o tmp/objs/Cedar/Database.o tmp/objs/Cedar/DDNS.o tmp/objs/Cedar/EM.o tmp/objs/Cedar/EtherLog.o tmp/objs/Cedar/Hub.o tmp/objs/Cedar/Interop_OpenVPN.o tmp/objs/Cedar/Interop_SSTP.o tmp/objs/Cedar/IPsec.o tmp/objs/Cedar/IPsec_EtherIP.o tmp/objs/Cedar/IPsec_IKE.o tmp/objs/Cedar/IPsec_IkePacket.o tmp/objs/Cedar/IPsec_IPC.o tmp/objs/Cedar/IPsec_L2TP.o tmp/objs/Cedar/IPsec_PPP.o tmp/objs/Cedar/IPsec_Win7.o tmp/objs/Cedar/Layer3.o tmp/objs/Cedar/Link.o tmp/objs/Cedar/Listener.o tmp/objs/Cedar/Logging.o tmp/objs/Cedar/Nat.o tmp/objs/Cedar/NativeStack.o tmp/objs/Cedar/NM.o tmp/objs/Cedar/NullLan.o tmp/objs/Cedar/Protocol.o tmp/objs/Cedar/Radius.o tmp/objs/Cedar/Remote.o tmp/objs/Cedar/Sam.o tmp/objs/Cedar/SecureInfo.o tmp/objs/Cedar/SecureNAT.o tmp/objs/Cedar/SeLowUser.o tmp/objs/Cedar/Server.o tmp/objs/Cedar/Session.o tmp/objs/Cedar/SM.o tmp/objs/Cedar/SW.o tmp/objs/Cedar/UdpAccel.o tmp/objs/Cedar/UT.o tmp/objs/Cedar/VG.o tmp/objs/Cedar/Virtual.o tmp/objs/Cedar/VLan.o tmp/objs/Cedar/VLanUnix.o tmp/objs/Cedar/VLanWin32.o tmp/objs/Cedar/WaterMark.o tmp/objs/Cedar/WebUI.o tmp/objs/Cedar/WinUi.o tmp/objs/Cedar/Wpc.o -HAMCORE_FILES=src/bin/hamcore/authors.txt src/bin/hamcore/backup_dir_readme.txt src/bin/hamcore/empty.config src/bin/hamcore/empty_sevpnclient.config src/bin/hamcore/eula.txt src/bin/hamcore/install_src.dat src/bin/hamcore/lang.config src/bin/hamcore/languages.txt src/bin/hamcore/languages_wine.txt src/bin/hamcore/legal.txt src/bin/hamcore/openvpn_readme.pdf src/bin/hamcore/openvpn_readme.txt src/bin/hamcore/openvpn_sample.ovpn src/bin/hamcore/root_certs.dat src/bin/hamcore/SOURCES_OF_BINARY_FILES.TXT src/bin/hamcore/strtable_cn.stb src/bin/hamcore/strtable_en.stb src/bin/hamcore/strtable_ja.stb src/bin/hamcore/vpnweb_sample_cn.htm src/bin/hamcore/vpnweb_sample_en.htm src/bin/hamcore/vpnweb_sample_ja.htm src/bin/hamcore/warning_cn.txt src/bin/hamcore/warning_en.txt src/bin/hamcore/warning_ja.txt src/bin/hamcore/webui/cryptcom.cgi src/bin/hamcore/webui/edituser.cgi src/bin/hamcore/webui/error.cgi src/bin/hamcore/webui/hub.cgi src/bin/hamcore/webui/license.cgi src/bin/hamcore/webui/listener.cgi src/bin/hamcore/webui/localbridge.cgi src/bin/hamcore/webui/login.cgi src/bin/hamcore/webui/newhub.cgi src/bin/hamcore/webui/redirect.cgi src/bin/hamcore/webui/securenat.cgi src/bin/hamcore/webui/server.cgi src/bin/hamcore/webui/session.cgi src/bin/hamcore/webui/user.cgi src/bin/hamcore/webui/webui.css +HAMCORE_FILES=src/bin/hamcore/authors.txt src/bin/hamcore/backup_dir_readme.txt src/bin/hamcore/empty.config src/bin/hamcore/empty_sevpnclient.config src/bin/hamcore/eula.txt src/bin/hamcore/install_src.dat src/bin/hamcore/languages.txt src/bin/hamcore/languages_wine.txt src/bin/hamcore/legal.txt src/bin/hamcore/openvpn_readme.pdf src/bin/hamcore/openvpn_readme.txt src/bin/hamcore/openvpn_sample.ovpn src/bin/hamcore/root_certs.dat src/bin/hamcore/SOURCES_OF_BINARY_FILES.TXT src/bin/hamcore/strtable_cn.stb src/bin/hamcore/strtable_en.stb src/bin/hamcore/strtable_ja.stb src/bin/hamcore/vpnserver_api_doc.html src/bin/hamcore/vpnweb_sample_cn.htm src/bin/hamcore/vpnweb_sample_en.htm src/bin/hamcore/vpnweb_sample_ja.htm src/bin/hamcore/warning_cn.txt src/bin/hamcore/warning_en.txt src/bin/hamcore/warning_ja.txt src/bin/hamcore/webui/cryptcom.cgi src/bin/hamcore/webui/edituser.cgi src/bin/hamcore/webui/error.cgi src/bin/hamcore/webui/hub.cgi src/bin/hamcore/webui/license.cgi src/bin/hamcore/webui/listener.cgi src/bin/hamcore/webui/localbridge.cgi src/bin/hamcore/webui/login.cgi src/bin/hamcore/webui/newhub.cgi src/bin/hamcore/webui/redirect.cgi src/bin/hamcore/webui/securenat.cgi src/bin/hamcore/webui/server.cgi src/bin/hamcore/webui/session.cgi src/bin/hamcore/webui/user.cgi src/bin/hamcore/webui/webui.css src/bin/hamcore/wwwroot/admin/default/.gitignore src/bin/hamcore/wwwroot/admin/default/.vscode/launch.json src/bin/hamcore/wwwroot/admin/default/.vscode/settings.json src/bin/hamcore/wwwroot/admin/default/.vscode/tasks.json src/bin/hamcore/wwwroot/admin/default/hub.html src/bin/hamcore/wwwroot/admin/default/include_footer.html src/bin/hamcore/wwwroot/admin/default/include_head.html src/bin/hamcore/wwwroot/admin/default/include_menu.html src/bin/hamcore/wwwroot/admin/default/index.html src/bin/hamcore/wwwroot/admin/default/out_webpack/bundle.js src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/index.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/index.d.ts.map src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/main.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/main.d.ts.map src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/vpnadmin.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/vpnadmin.d.ts.map src/bin/hamcore/wwwroot/admin/default/package.json src/bin/hamcore/wwwroot/admin/default/package-lock.json src/bin/hamcore/wwwroot/admin/default/src/ts/main.ts src/bin/hamcore/wwwroot/admin/default/theme.css src/bin/hamcore/wwwroot/admin/default/tsconfig.json src/bin/hamcore/wwwroot/admin/default/tsconfig_webpack.json src/bin/hamcore/wwwroot/admin/default/tslint.json src/bin/hamcore/wwwroot/admin/default/webpack.config.js src/bin/hamcore/wwwroot/admin/index.html src/bin/hamcore/wwwroot/admin/README.md src/bin/hamcore/wwwroot/index.html # Build Action default: build diff --git a/src/makefiles/macos_32bit.mak b/src/makefiles/macos_32bit.mak index 0957275b..7f021eb9 100644 --- a/src/makefiles/macos_32bit.mak +++ b/src/makefiles/macos_32bit.mak @@ -89,7 +89,7 @@ HEADERS_MAYAQUA=src/Mayaqua/Cfg.h src/Mayaqua/cryptoki.h src/Mayaqua/Encrypt.h s HEADERS_CEDAR=src/Cedar/Account.h src/Cedar/Admin.h src/Cedar/AzureClient.h src/Cedar/AzureServer.h src/Cedar/Bridge.h src/Cedar/BridgeUnix.h src/Cedar/BridgeWin32.h src/Cedar/Cedar.h src/Cedar/CedarPch.h src/Cedar/CedarType.h src/Cedar/Client.h src/Cedar/CM.h src/Cedar/CMInner.h src/Cedar/Command.h src/Cedar/Connection.h src/Cedar/Console.h src/Cedar/Database.h src/Cedar/DDNS.h src/Cedar/EM.h src/Cedar/EMInner.h src/Cedar/EtherLog.h src/Cedar/Hub.h src/Cedar/Interop_OpenVPN.h src/Cedar/Interop_SSTP.h src/Cedar/IPsec.h src/Cedar/IPsec_EtherIP.h src/Cedar/IPsec_IKE.h src/Cedar/IPsec_IkePacket.h src/Cedar/IPsec_IPC.h src/Cedar/IPsec_L2TP.h src/Cedar/IPsec_PPP.h src/Cedar/IPsec_Win7.h src/Cedar/IPsec_Win7Inner.h src/Cedar/Layer3.h src/Cedar/Link.h src/Cedar/Listener.h src/Cedar/Logging.h src/Cedar/Nat.h src/Cedar/NativeStack.h src/Cedar/netcfgn.h src/Cedar/netcfgx.h src/Cedar/NM.h src/Cedar/NMInner.h src/Cedar/NullLan.h src/Cedar/Protocol.h src/Cedar/Radius.h src/Cedar/Remote.h src/Cedar/Sam.h src/Cedar/SecureInfo.h src/Cedar/SecureNAT.h src/Cedar/SeLowUser.h src/Cedar/Server.h src/Cedar/Session.h src/Cedar/SM.h src/Cedar/SMInner.h src/Cedar/SW.h src/Cedar/SWInner.h src/Cedar/UdpAccel.h src/Cedar/UT.h src/Cedar/VG.h src/Cedar/Virtual.h src/Cedar/VLan.h src/Cedar/VLanUnix.h src/Cedar/VLanWin32.h src/Cedar/WaterMark.h src/Cedar/WebUI.h src/Cedar/Win32Com.h src/Cedar/winpcap/bittypes.h src/Cedar/winpcap/bucket_lookup.h src/Cedar/winpcap/count_packets.h src/Cedar/winpcap/Devioctl.h src/Cedar/winpcap/Gnuc.h src/Cedar/winpcap/ip6_misc.h src/Cedar/winpcap/memory_t.h src/Cedar/winpcap/normal_lookup.h src/Cedar/winpcap/Ntddndis.h src/Cedar/winpcap/Ntddpack.h src/Cedar/winpcap/Packet32.h src/Cedar/winpcap/pcap.h src/Cedar/winpcap/pcap-bpf.h src/Cedar/winpcap/pcap-int.h src/Cedar/winpcap/pcap-stdinc.h src/Cedar/winpcap/pthread.h src/Cedar/winpcap/remote-ext.h src/Cedar/winpcap/sched.h src/Cedar/winpcap/semaphore.h src/Cedar/winpcap/tcp_session.h src/Cedar/winpcap/time_calls.h src/Cedar/winpcap/tme.h src/Cedar/winpcap/Win32-Extensions.h src/Cedar/WinUi.h src/Cedar/Wpc.h OBJECTS_MAYAQUA=tmp/objs/Mayaqua/Cfg.o tmp/objs/Mayaqua/Encrypt.o tmp/objs/Mayaqua/FileIO.o tmp/objs/Mayaqua/Internat.o tmp/objs/Mayaqua/Kernel.o tmp/objs/Mayaqua/Mayaqua.o tmp/objs/Mayaqua/Memory.o tmp/objs/Mayaqua/Microsoft.o tmp/objs/Mayaqua/Network.o tmp/objs/Mayaqua/Object.o tmp/objs/Mayaqua/OS.o tmp/objs/Mayaqua/Pack.o tmp/objs/Mayaqua/Secure.o tmp/objs/Mayaqua/Str.o tmp/objs/Mayaqua/Table.o tmp/objs/Mayaqua/TcpIp.o tmp/objs/Mayaqua/Tick64.o tmp/objs/Mayaqua/Tracking.o tmp/objs/Mayaqua/Unix.o tmp/objs/Mayaqua/Win32.o OBJECTS_CEDAR=tmp/objs/Cedar/Account.o tmp/objs/Cedar/Admin.o tmp/objs/Cedar/AzureClient.o tmp/objs/Cedar/AzureServer.o tmp/objs/Cedar/Bridge.o tmp/objs/Cedar/BridgeUnix.o tmp/objs/Cedar/BridgeWin32.o tmp/objs/Cedar/Cedar.o tmp/objs/Cedar/CedarPch.o tmp/objs/Cedar/Client.o tmp/objs/Cedar/CM.o tmp/objs/Cedar/Command.o tmp/objs/Cedar/Connection.o tmp/objs/Cedar/Console.o tmp/objs/Cedar/Database.o tmp/objs/Cedar/DDNS.o tmp/objs/Cedar/EM.o tmp/objs/Cedar/EtherLog.o tmp/objs/Cedar/Hub.o tmp/objs/Cedar/Interop_OpenVPN.o tmp/objs/Cedar/Interop_SSTP.o tmp/objs/Cedar/IPsec.o tmp/objs/Cedar/IPsec_EtherIP.o tmp/objs/Cedar/IPsec_IKE.o tmp/objs/Cedar/IPsec_IkePacket.o tmp/objs/Cedar/IPsec_IPC.o tmp/objs/Cedar/IPsec_L2TP.o tmp/objs/Cedar/IPsec_PPP.o tmp/objs/Cedar/IPsec_Win7.o tmp/objs/Cedar/Layer3.o tmp/objs/Cedar/Link.o tmp/objs/Cedar/Listener.o tmp/objs/Cedar/Logging.o tmp/objs/Cedar/Nat.o tmp/objs/Cedar/NativeStack.o tmp/objs/Cedar/NM.o tmp/objs/Cedar/NullLan.o tmp/objs/Cedar/Protocol.o tmp/objs/Cedar/Radius.o tmp/objs/Cedar/Remote.o tmp/objs/Cedar/Sam.o tmp/objs/Cedar/SecureInfo.o tmp/objs/Cedar/SecureNAT.o tmp/objs/Cedar/SeLowUser.o tmp/objs/Cedar/Server.o tmp/objs/Cedar/Session.o tmp/objs/Cedar/SM.o tmp/objs/Cedar/SW.o tmp/objs/Cedar/UdpAccel.o tmp/objs/Cedar/UT.o tmp/objs/Cedar/VG.o tmp/objs/Cedar/Virtual.o tmp/objs/Cedar/VLan.o tmp/objs/Cedar/VLanUnix.o tmp/objs/Cedar/VLanWin32.o tmp/objs/Cedar/WaterMark.o tmp/objs/Cedar/WebUI.o tmp/objs/Cedar/WinUi.o tmp/objs/Cedar/Wpc.o -HAMCORE_FILES=src/bin/hamcore/authors.txt src/bin/hamcore/backup_dir_readme.txt src/bin/hamcore/empty.config src/bin/hamcore/empty_sevpnclient.config src/bin/hamcore/eula.txt src/bin/hamcore/install_src.dat src/bin/hamcore/lang.config src/bin/hamcore/languages.txt src/bin/hamcore/languages_wine.txt src/bin/hamcore/legal.txt src/bin/hamcore/openvpn_readme.pdf src/bin/hamcore/openvpn_readme.txt src/bin/hamcore/openvpn_sample.ovpn src/bin/hamcore/root_certs.dat src/bin/hamcore/SOURCES_OF_BINARY_FILES.TXT src/bin/hamcore/strtable_cn.stb src/bin/hamcore/strtable_en.stb src/bin/hamcore/strtable_ja.stb src/bin/hamcore/vpnweb_sample_cn.htm src/bin/hamcore/vpnweb_sample_en.htm src/bin/hamcore/vpnweb_sample_ja.htm src/bin/hamcore/warning_cn.txt src/bin/hamcore/warning_en.txt src/bin/hamcore/warning_ja.txt src/bin/hamcore/webui/cryptcom.cgi src/bin/hamcore/webui/edituser.cgi src/bin/hamcore/webui/error.cgi src/bin/hamcore/webui/hub.cgi src/bin/hamcore/webui/license.cgi src/bin/hamcore/webui/listener.cgi src/bin/hamcore/webui/localbridge.cgi src/bin/hamcore/webui/login.cgi src/bin/hamcore/webui/newhub.cgi src/bin/hamcore/webui/redirect.cgi src/bin/hamcore/webui/securenat.cgi src/bin/hamcore/webui/server.cgi src/bin/hamcore/webui/session.cgi src/bin/hamcore/webui/user.cgi src/bin/hamcore/webui/webui.css +HAMCORE_FILES=src/bin/hamcore/authors.txt src/bin/hamcore/backup_dir_readme.txt src/bin/hamcore/empty.config src/bin/hamcore/empty_sevpnclient.config src/bin/hamcore/eula.txt src/bin/hamcore/install_src.dat src/bin/hamcore/languages.txt src/bin/hamcore/languages_wine.txt src/bin/hamcore/legal.txt src/bin/hamcore/openvpn_readme.pdf src/bin/hamcore/openvpn_readme.txt src/bin/hamcore/openvpn_sample.ovpn src/bin/hamcore/root_certs.dat src/bin/hamcore/SOURCES_OF_BINARY_FILES.TXT src/bin/hamcore/strtable_cn.stb src/bin/hamcore/strtable_en.stb src/bin/hamcore/strtable_ja.stb src/bin/hamcore/vpnserver_api_doc.html src/bin/hamcore/vpnweb_sample_cn.htm src/bin/hamcore/vpnweb_sample_en.htm src/bin/hamcore/vpnweb_sample_ja.htm src/bin/hamcore/warning_cn.txt src/bin/hamcore/warning_en.txt src/bin/hamcore/warning_ja.txt src/bin/hamcore/webui/cryptcom.cgi src/bin/hamcore/webui/edituser.cgi src/bin/hamcore/webui/error.cgi src/bin/hamcore/webui/hub.cgi src/bin/hamcore/webui/license.cgi src/bin/hamcore/webui/listener.cgi src/bin/hamcore/webui/localbridge.cgi src/bin/hamcore/webui/login.cgi src/bin/hamcore/webui/newhub.cgi src/bin/hamcore/webui/redirect.cgi src/bin/hamcore/webui/securenat.cgi src/bin/hamcore/webui/server.cgi src/bin/hamcore/webui/session.cgi src/bin/hamcore/webui/user.cgi src/bin/hamcore/webui/webui.css src/bin/hamcore/wwwroot/admin/default/.gitignore src/bin/hamcore/wwwroot/admin/default/.vscode/launch.json src/bin/hamcore/wwwroot/admin/default/.vscode/settings.json src/bin/hamcore/wwwroot/admin/default/.vscode/tasks.json src/bin/hamcore/wwwroot/admin/default/hub.html src/bin/hamcore/wwwroot/admin/default/include_footer.html src/bin/hamcore/wwwroot/admin/default/include_head.html src/bin/hamcore/wwwroot/admin/default/include_menu.html src/bin/hamcore/wwwroot/admin/default/index.html src/bin/hamcore/wwwroot/admin/default/out_webpack/bundle.js src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/index.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/index.d.ts.map src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/main.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/main.d.ts.map src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/vpnadmin.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/vpnadmin.d.ts.map src/bin/hamcore/wwwroot/admin/default/package.json src/bin/hamcore/wwwroot/admin/default/package-lock.json src/bin/hamcore/wwwroot/admin/default/src/ts/main.ts src/bin/hamcore/wwwroot/admin/default/theme.css src/bin/hamcore/wwwroot/admin/default/tsconfig.json src/bin/hamcore/wwwroot/admin/default/tsconfig_webpack.json src/bin/hamcore/wwwroot/admin/default/tslint.json src/bin/hamcore/wwwroot/admin/default/webpack.config.js src/bin/hamcore/wwwroot/admin/index.html src/bin/hamcore/wwwroot/admin/README.md src/bin/hamcore/wwwroot/index.html # Build Action default: build diff --git a/src/makefiles/macos_64bit.mak b/src/makefiles/macos_64bit.mak index b5727946..e313ad16 100644 --- a/src/makefiles/macos_64bit.mak +++ b/src/makefiles/macos_64bit.mak @@ -89,7 +89,7 @@ HEADERS_MAYAQUA=src/Mayaqua/Cfg.h src/Mayaqua/cryptoki.h src/Mayaqua/Encrypt.h s HEADERS_CEDAR=src/Cedar/Account.h src/Cedar/Admin.h src/Cedar/AzureClient.h src/Cedar/AzureServer.h src/Cedar/Bridge.h src/Cedar/BridgeUnix.h src/Cedar/BridgeWin32.h src/Cedar/Cedar.h src/Cedar/CedarPch.h src/Cedar/CedarType.h src/Cedar/Client.h src/Cedar/CM.h src/Cedar/CMInner.h src/Cedar/Command.h src/Cedar/Connection.h src/Cedar/Console.h src/Cedar/Database.h src/Cedar/DDNS.h src/Cedar/EM.h src/Cedar/EMInner.h src/Cedar/EtherLog.h src/Cedar/Hub.h src/Cedar/Interop_OpenVPN.h src/Cedar/Interop_SSTP.h src/Cedar/IPsec.h src/Cedar/IPsec_EtherIP.h src/Cedar/IPsec_IKE.h src/Cedar/IPsec_IkePacket.h src/Cedar/IPsec_IPC.h src/Cedar/IPsec_L2TP.h src/Cedar/IPsec_PPP.h src/Cedar/IPsec_Win7.h src/Cedar/IPsec_Win7Inner.h src/Cedar/Layer3.h src/Cedar/Link.h src/Cedar/Listener.h src/Cedar/Logging.h src/Cedar/Nat.h src/Cedar/NativeStack.h src/Cedar/netcfgn.h src/Cedar/netcfgx.h src/Cedar/NM.h src/Cedar/NMInner.h src/Cedar/NullLan.h src/Cedar/Protocol.h src/Cedar/Radius.h src/Cedar/Remote.h src/Cedar/Sam.h src/Cedar/SecureInfo.h src/Cedar/SecureNAT.h src/Cedar/SeLowUser.h src/Cedar/Server.h src/Cedar/Session.h src/Cedar/SM.h src/Cedar/SMInner.h src/Cedar/SW.h src/Cedar/SWInner.h src/Cedar/UdpAccel.h src/Cedar/UT.h src/Cedar/VG.h src/Cedar/Virtual.h src/Cedar/VLan.h src/Cedar/VLanUnix.h src/Cedar/VLanWin32.h src/Cedar/WaterMark.h src/Cedar/WebUI.h src/Cedar/Win32Com.h src/Cedar/winpcap/bittypes.h src/Cedar/winpcap/bucket_lookup.h src/Cedar/winpcap/count_packets.h src/Cedar/winpcap/Devioctl.h src/Cedar/winpcap/Gnuc.h src/Cedar/winpcap/ip6_misc.h src/Cedar/winpcap/memory_t.h src/Cedar/winpcap/normal_lookup.h src/Cedar/winpcap/Ntddndis.h src/Cedar/winpcap/Ntddpack.h src/Cedar/winpcap/Packet32.h src/Cedar/winpcap/pcap.h src/Cedar/winpcap/pcap-bpf.h src/Cedar/winpcap/pcap-int.h src/Cedar/winpcap/pcap-stdinc.h src/Cedar/winpcap/pthread.h src/Cedar/winpcap/remote-ext.h src/Cedar/winpcap/sched.h src/Cedar/winpcap/semaphore.h src/Cedar/winpcap/tcp_session.h src/Cedar/winpcap/time_calls.h src/Cedar/winpcap/tme.h src/Cedar/winpcap/Win32-Extensions.h src/Cedar/WinUi.h src/Cedar/Wpc.h OBJECTS_MAYAQUA=tmp/objs/Mayaqua/Cfg.o tmp/objs/Mayaqua/Encrypt.o tmp/objs/Mayaqua/FileIO.o tmp/objs/Mayaqua/Internat.o tmp/objs/Mayaqua/Kernel.o tmp/objs/Mayaqua/Mayaqua.o tmp/objs/Mayaqua/Memory.o tmp/objs/Mayaqua/Microsoft.o tmp/objs/Mayaqua/Network.o tmp/objs/Mayaqua/Object.o tmp/objs/Mayaqua/OS.o tmp/objs/Mayaqua/Pack.o tmp/objs/Mayaqua/Secure.o tmp/objs/Mayaqua/Str.o tmp/objs/Mayaqua/Table.o tmp/objs/Mayaqua/TcpIp.o tmp/objs/Mayaqua/Tick64.o tmp/objs/Mayaqua/Tracking.o tmp/objs/Mayaqua/Unix.o tmp/objs/Mayaqua/Win32.o OBJECTS_CEDAR=tmp/objs/Cedar/Account.o tmp/objs/Cedar/Admin.o tmp/objs/Cedar/AzureClient.o tmp/objs/Cedar/AzureServer.o tmp/objs/Cedar/Bridge.o tmp/objs/Cedar/BridgeUnix.o tmp/objs/Cedar/BridgeWin32.o tmp/objs/Cedar/Cedar.o tmp/objs/Cedar/CedarPch.o tmp/objs/Cedar/Client.o tmp/objs/Cedar/CM.o tmp/objs/Cedar/Command.o tmp/objs/Cedar/Connection.o tmp/objs/Cedar/Console.o tmp/objs/Cedar/Database.o tmp/objs/Cedar/DDNS.o tmp/objs/Cedar/EM.o tmp/objs/Cedar/EtherLog.o tmp/objs/Cedar/Hub.o tmp/objs/Cedar/Interop_OpenVPN.o tmp/objs/Cedar/Interop_SSTP.o tmp/objs/Cedar/IPsec.o tmp/objs/Cedar/IPsec_EtherIP.o tmp/objs/Cedar/IPsec_IKE.o tmp/objs/Cedar/IPsec_IkePacket.o tmp/objs/Cedar/IPsec_IPC.o tmp/objs/Cedar/IPsec_L2TP.o tmp/objs/Cedar/IPsec_PPP.o tmp/objs/Cedar/IPsec_Win7.o tmp/objs/Cedar/Layer3.o tmp/objs/Cedar/Link.o tmp/objs/Cedar/Listener.o tmp/objs/Cedar/Logging.o tmp/objs/Cedar/Nat.o tmp/objs/Cedar/NativeStack.o tmp/objs/Cedar/NM.o tmp/objs/Cedar/NullLan.o tmp/objs/Cedar/Protocol.o tmp/objs/Cedar/Radius.o tmp/objs/Cedar/Remote.o tmp/objs/Cedar/Sam.o tmp/objs/Cedar/SecureInfo.o tmp/objs/Cedar/SecureNAT.o tmp/objs/Cedar/SeLowUser.o tmp/objs/Cedar/Server.o tmp/objs/Cedar/Session.o tmp/objs/Cedar/SM.o tmp/objs/Cedar/SW.o tmp/objs/Cedar/UdpAccel.o tmp/objs/Cedar/UT.o tmp/objs/Cedar/VG.o tmp/objs/Cedar/Virtual.o tmp/objs/Cedar/VLan.o tmp/objs/Cedar/VLanUnix.o tmp/objs/Cedar/VLanWin32.o tmp/objs/Cedar/WaterMark.o tmp/objs/Cedar/WebUI.o tmp/objs/Cedar/WinUi.o tmp/objs/Cedar/Wpc.o -HAMCORE_FILES=src/bin/hamcore/authors.txt src/bin/hamcore/backup_dir_readme.txt src/bin/hamcore/empty.config src/bin/hamcore/empty_sevpnclient.config src/bin/hamcore/eula.txt src/bin/hamcore/install_src.dat src/bin/hamcore/lang.config src/bin/hamcore/languages.txt src/bin/hamcore/languages_wine.txt src/bin/hamcore/legal.txt src/bin/hamcore/openvpn_readme.pdf src/bin/hamcore/openvpn_readme.txt src/bin/hamcore/openvpn_sample.ovpn src/bin/hamcore/root_certs.dat src/bin/hamcore/SOURCES_OF_BINARY_FILES.TXT src/bin/hamcore/strtable_cn.stb src/bin/hamcore/strtable_en.stb src/bin/hamcore/strtable_ja.stb src/bin/hamcore/vpnweb_sample_cn.htm src/bin/hamcore/vpnweb_sample_en.htm src/bin/hamcore/vpnweb_sample_ja.htm src/bin/hamcore/warning_cn.txt src/bin/hamcore/warning_en.txt src/bin/hamcore/warning_ja.txt src/bin/hamcore/webui/cryptcom.cgi src/bin/hamcore/webui/edituser.cgi src/bin/hamcore/webui/error.cgi src/bin/hamcore/webui/hub.cgi src/bin/hamcore/webui/license.cgi src/bin/hamcore/webui/listener.cgi src/bin/hamcore/webui/localbridge.cgi src/bin/hamcore/webui/login.cgi src/bin/hamcore/webui/newhub.cgi src/bin/hamcore/webui/redirect.cgi src/bin/hamcore/webui/securenat.cgi src/bin/hamcore/webui/server.cgi src/bin/hamcore/webui/session.cgi src/bin/hamcore/webui/user.cgi src/bin/hamcore/webui/webui.css +HAMCORE_FILES=src/bin/hamcore/authors.txt src/bin/hamcore/backup_dir_readme.txt src/bin/hamcore/empty.config src/bin/hamcore/empty_sevpnclient.config src/bin/hamcore/eula.txt src/bin/hamcore/install_src.dat src/bin/hamcore/languages.txt src/bin/hamcore/languages_wine.txt src/bin/hamcore/legal.txt src/bin/hamcore/openvpn_readme.pdf src/bin/hamcore/openvpn_readme.txt src/bin/hamcore/openvpn_sample.ovpn src/bin/hamcore/root_certs.dat src/bin/hamcore/SOURCES_OF_BINARY_FILES.TXT src/bin/hamcore/strtable_cn.stb src/bin/hamcore/strtable_en.stb src/bin/hamcore/strtable_ja.stb src/bin/hamcore/vpnserver_api_doc.html src/bin/hamcore/vpnweb_sample_cn.htm src/bin/hamcore/vpnweb_sample_en.htm src/bin/hamcore/vpnweb_sample_ja.htm src/bin/hamcore/warning_cn.txt src/bin/hamcore/warning_en.txt src/bin/hamcore/warning_ja.txt src/bin/hamcore/webui/cryptcom.cgi src/bin/hamcore/webui/edituser.cgi src/bin/hamcore/webui/error.cgi src/bin/hamcore/webui/hub.cgi src/bin/hamcore/webui/license.cgi src/bin/hamcore/webui/listener.cgi src/bin/hamcore/webui/localbridge.cgi src/bin/hamcore/webui/login.cgi src/bin/hamcore/webui/newhub.cgi src/bin/hamcore/webui/redirect.cgi src/bin/hamcore/webui/securenat.cgi src/bin/hamcore/webui/server.cgi src/bin/hamcore/webui/session.cgi src/bin/hamcore/webui/user.cgi src/bin/hamcore/webui/webui.css src/bin/hamcore/wwwroot/admin/default/.gitignore src/bin/hamcore/wwwroot/admin/default/.vscode/launch.json src/bin/hamcore/wwwroot/admin/default/.vscode/settings.json src/bin/hamcore/wwwroot/admin/default/.vscode/tasks.json src/bin/hamcore/wwwroot/admin/default/hub.html src/bin/hamcore/wwwroot/admin/default/include_footer.html src/bin/hamcore/wwwroot/admin/default/include_head.html src/bin/hamcore/wwwroot/admin/default/include_menu.html src/bin/hamcore/wwwroot/admin/default/index.html src/bin/hamcore/wwwroot/admin/default/out_webpack/bundle.js src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/index.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/index.d.ts.map src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/main.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/main.d.ts.map src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/vpnadmin.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/vpnadmin.d.ts.map src/bin/hamcore/wwwroot/admin/default/package.json src/bin/hamcore/wwwroot/admin/default/package-lock.json src/bin/hamcore/wwwroot/admin/default/src/ts/main.ts src/bin/hamcore/wwwroot/admin/default/theme.css src/bin/hamcore/wwwroot/admin/default/tsconfig.json src/bin/hamcore/wwwroot/admin/default/tsconfig_webpack.json src/bin/hamcore/wwwroot/admin/default/tslint.json src/bin/hamcore/wwwroot/admin/default/webpack.config.js src/bin/hamcore/wwwroot/admin/index.html src/bin/hamcore/wwwroot/admin/README.md src/bin/hamcore/wwwroot/index.html # Build Action default: build diff --git a/src/makefiles/openbsd_32bit.mak b/src/makefiles/openbsd_32bit.mak index b664989b..e5711e1a 100644 --- a/src/makefiles/openbsd_32bit.mak +++ b/src/makefiles/openbsd_32bit.mak @@ -89,7 +89,7 @@ HEADERS_MAYAQUA=src/Mayaqua/Cfg.h src/Mayaqua/cryptoki.h src/Mayaqua/Encrypt.h s HEADERS_CEDAR=src/Cedar/Account.h src/Cedar/Admin.h src/Cedar/AzureClient.h src/Cedar/AzureServer.h src/Cedar/Bridge.h src/Cedar/BridgeUnix.h src/Cedar/BridgeWin32.h src/Cedar/Cedar.h src/Cedar/CedarPch.h src/Cedar/CedarType.h src/Cedar/Client.h src/Cedar/CM.h src/Cedar/CMInner.h src/Cedar/Command.h src/Cedar/Connection.h src/Cedar/Console.h src/Cedar/Database.h src/Cedar/DDNS.h src/Cedar/EM.h src/Cedar/EMInner.h src/Cedar/EtherLog.h src/Cedar/Hub.h src/Cedar/Interop_OpenVPN.h src/Cedar/Interop_SSTP.h src/Cedar/IPsec.h src/Cedar/IPsec_EtherIP.h src/Cedar/IPsec_IKE.h src/Cedar/IPsec_IkePacket.h src/Cedar/IPsec_IPC.h src/Cedar/IPsec_L2TP.h src/Cedar/IPsec_PPP.h src/Cedar/IPsec_Win7.h src/Cedar/IPsec_Win7Inner.h src/Cedar/Layer3.h src/Cedar/Link.h src/Cedar/Listener.h src/Cedar/Logging.h src/Cedar/Nat.h src/Cedar/NativeStack.h src/Cedar/netcfgn.h src/Cedar/netcfgx.h src/Cedar/NM.h src/Cedar/NMInner.h src/Cedar/NullLan.h src/Cedar/Protocol.h src/Cedar/Radius.h src/Cedar/Remote.h src/Cedar/Sam.h src/Cedar/SecureInfo.h src/Cedar/SecureNAT.h src/Cedar/SeLowUser.h src/Cedar/Server.h src/Cedar/Session.h src/Cedar/SM.h src/Cedar/SMInner.h src/Cedar/SW.h src/Cedar/SWInner.h src/Cedar/UdpAccel.h src/Cedar/UT.h src/Cedar/VG.h src/Cedar/Virtual.h src/Cedar/VLan.h src/Cedar/VLanUnix.h src/Cedar/VLanWin32.h src/Cedar/WaterMark.h src/Cedar/WebUI.h src/Cedar/Win32Com.h src/Cedar/winpcap/bittypes.h src/Cedar/winpcap/bucket_lookup.h src/Cedar/winpcap/count_packets.h src/Cedar/winpcap/Devioctl.h src/Cedar/winpcap/Gnuc.h src/Cedar/winpcap/ip6_misc.h src/Cedar/winpcap/memory_t.h src/Cedar/winpcap/normal_lookup.h src/Cedar/winpcap/Ntddndis.h src/Cedar/winpcap/Ntddpack.h src/Cedar/winpcap/Packet32.h src/Cedar/winpcap/pcap.h src/Cedar/winpcap/pcap-bpf.h src/Cedar/winpcap/pcap-int.h src/Cedar/winpcap/pcap-stdinc.h src/Cedar/winpcap/pthread.h src/Cedar/winpcap/remote-ext.h src/Cedar/winpcap/sched.h src/Cedar/winpcap/semaphore.h src/Cedar/winpcap/tcp_session.h src/Cedar/winpcap/time_calls.h src/Cedar/winpcap/tme.h src/Cedar/winpcap/Win32-Extensions.h src/Cedar/WinUi.h src/Cedar/Wpc.h OBJECTS_MAYAQUA=tmp/objs/Mayaqua/Cfg.o tmp/objs/Mayaqua/Encrypt.o tmp/objs/Mayaqua/FileIO.o tmp/objs/Mayaqua/Internat.o tmp/objs/Mayaqua/Kernel.o tmp/objs/Mayaqua/Mayaqua.o tmp/objs/Mayaqua/Memory.o tmp/objs/Mayaqua/Microsoft.o tmp/objs/Mayaqua/Network.o tmp/objs/Mayaqua/Object.o tmp/objs/Mayaqua/OS.o tmp/objs/Mayaqua/Pack.o tmp/objs/Mayaqua/Secure.o tmp/objs/Mayaqua/Str.o tmp/objs/Mayaqua/Table.o tmp/objs/Mayaqua/TcpIp.o tmp/objs/Mayaqua/Tick64.o tmp/objs/Mayaqua/Tracking.o tmp/objs/Mayaqua/Unix.o tmp/objs/Mayaqua/Win32.o OBJECTS_CEDAR=tmp/objs/Cedar/Account.o tmp/objs/Cedar/Admin.o tmp/objs/Cedar/AzureClient.o tmp/objs/Cedar/AzureServer.o tmp/objs/Cedar/Bridge.o tmp/objs/Cedar/BridgeUnix.o tmp/objs/Cedar/BridgeWin32.o tmp/objs/Cedar/Cedar.o tmp/objs/Cedar/CedarPch.o tmp/objs/Cedar/Client.o tmp/objs/Cedar/CM.o tmp/objs/Cedar/Command.o tmp/objs/Cedar/Connection.o tmp/objs/Cedar/Console.o tmp/objs/Cedar/Database.o tmp/objs/Cedar/DDNS.o tmp/objs/Cedar/EM.o tmp/objs/Cedar/EtherLog.o tmp/objs/Cedar/Hub.o tmp/objs/Cedar/Interop_OpenVPN.o tmp/objs/Cedar/Interop_SSTP.o tmp/objs/Cedar/IPsec.o tmp/objs/Cedar/IPsec_EtherIP.o tmp/objs/Cedar/IPsec_IKE.o tmp/objs/Cedar/IPsec_IkePacket.o tmp/objs/Cedar/IPsec_IPC.o tmp/objs/Cedar/IPsec_L2TP.o tmp/objs/Cedar/IPsec_PPP.o tmp/objs/Cedar/IPsec_Win7.o tmp/objs/Cedar/Layer3.o tmp/objs/Cedar/Link.o tmp/objs/Cedar/Listener.o tmp/objs/Cedar/Logging.o tmp/objs/Cedar/Nat.o tmp/objs/Cedar/NativeStack.o tmp/objs/Cedar/NM.o tmp/objs/Cedar/NullLan.o tmp/objs/Cedar/Protocol.o tmp/objs/Cedar/Radius.o tmp/objs/Cedar/Remote.o tmp/objs/Cedar/Sam.o tmp/objs/Cedar/SecureInfo.o tmp/objs/Cedar/SecureNAT.o tmp/objs/Cedar/SeLowUser.o tmp/objs/Cedar/Server.o tmp/objs/Cedar/Session.o tmp/objs/Cedar/SM.o tmp/objs/Cedar/SW.o tmp/objs/Cedar/UdpAccel.o tmp/objs/Cedar/UT.o tmp/objs/Cedar/VG.o tmp/objs/Cedar/Virtual.o tmp/objs/Cedar/VLan.o tmp/objs/Cedar/VLanUnix.o tmp/objs/Cedar/VLanWin32.o tmp/objs/Cedar/WaterMark.o tmp/objs/Cedar/WebUI.o tmp/objs/Cedar/WinUi.o tmp/objs/Cedar/Wpc.o -HAMCORE_FILES=src/bin/hamcore/authors.txt src/bin/hamcore/backup_dir_readme.txt src/bin/hamcore/empty.config src/bin/hamcore/empty_sevpnclient.config src/bin/hamcore/eula.txt src/bin/hamcore/install_src.dat src/bin/hamcore/lang.config src/bin/hamcore/languages.txt src/bin/hamcore/languages_wine.txt src/bin/hamcore/legal.txt src/bin/hamcore/openvpn_readme.pdf src/bin/hamcore/openvpn_readme.txt src/bin/hamcore/openvpn_sample.ovpn src/bin/hamcore/root_certs.dat src/bin/hamcore/SOURCES_OF_BINARY_FILES.TXT src/bin/hamcore/strtable_cn.stb src/bin/hamcore/strtable_en.stb src/bin/hamcore/strtable_ja.stb src/bin/hamcore/vpnweb_sample_cn.htm src/bin/hamcore/vpnweb_sample_en.htm src/bin/hamcore/vpnweb_sample_ja.htm src/bin/hamcore/warning_cn.txt src/bin/hamcore/warning_en.txt src/bin/hamcore/warning_ja.txt src/bin/hamcore/webui/cryptcom.cgi src/bin/hamcore/webui/edituser.cgi src/bin/hamcore/webui/error.cgi src/bin/hamcore/webui/hub.cgi src/bin/hamcore/webui/license.cgi src/bin/hamcore/webui/listener.cgi src/bin/hamcore/webui/localbridge.cgi src/bin/hamcore/webui/login.cgi src/bin/hamcore/webui/newhub.cgi src/bin/hamcore/webui/redirect.cgi src/bin/hamcore/webui/securenat.cgi src/bin/hamcore/webui/server.cgi src/bin/hamcore/webui/session.cgi src/bin/hamcore/webui/user.cgi src/bin/hamcore/webui/webui.css +HAMCORE_FILES=src/bin/hamcore/authors.txt src/bin/hamcore/backup_dir_readme.txt src/bin/hamcore/empty.config src/bin/hamcore/empty_sevpnclient.config src/bin/hamcore/eula.txt src/bin/hamcore/install_src.dat src/bin/hamcore/languages.txt src/bin/hamcore/languages_wine.txt src/bin/hamcore/legal.txt src/bin/hamcore/openvpn_readme.pdf src/bin/hamcore/openvpn_readme.txt src/bin/hamcore/openvpn_sample.ovpn src/bin/hamcore/root_certs.dat src/bin/hamcore/SOURCES_OF_BINARY_FILES.TXT src/bin/hamcore/strtable_cn.stb src/bin/hamcore/strtable_en.stb src/bin/hamcore/strtable_ja.stb src/bin/hamcore/vpnserver_api_doc.html src/bin/hamcore/vpnweb_sample_cn.htm src/bin/hamcore/vpnweb_sample_en.htm src/bin/hamcore/vpnweb_sample_ja.htm src/bin/hamcore/warning_cn.txt src/bin/hamcore/warning_en.txt src/bin/hamcore/warning_ja.txt src/bin/hamcore/webui/cryptcom.cgi src/bin/hamcore/webui/edituser.cgi src/bin/hamcore/webui/error.cgi src/bin/hamcore/webui/hub.cgi src/bin/hamcore/webui/license.cgi src/bin/hamcore/webui/listener.cgi src/bin/hamcore/webui/localbridge.cgi src/bin/hamcore/webui/login.cgi src/bin/hamcore/webui/newhub.cgi src/bin/hamcore/webui/redirect.cgi src/bin/hamcore/webui/securenat.cgi src/bin/hamcore/webui/server.cgi src/bin/hamcore/webui/session.cgi src/bin/hamcore/webui/user.cgi src/bin/hamcore/webui/webui.css src/bin/hamcore/wwwroot/admin/default/.gitignore src/bin/hamcore/wwwroot/admin/default/.vscode/launch.json src/bin/hamcore/wwwroot/admin/default/.vscode/settings.json src/bin/hamcore/wwwroot/admin/default/.vscode/tasks.json src/bin/hamcore/wwwroot/admin/default/hub.html src/bin/hamcore/wwwroot/admin/default/include_footer.html src/bin/hamcore/wwwroot/admin/default/include_head.html src/bin/hamcore/wwwroot/admin/default/include_menu.html src/bin/hamcore/wwwroot/admin/default/index.html src/bin/hamcore/wwwroot/admin/default/out_webpack/bundle.js src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/index.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/index.d.ts.map src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/main.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/main.d.ts.map src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/vpnadmin.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/vpnadmin.d.ts.map src/bin/hamcore/wwwroot/admin/default/package.json src/bin/hamcore/wwwroot/admin/default/package-lock.json src/bin/hamcore/wwwroot/admin/default/src/ts/main.ts src/bin/hamcore/wwwroot/admin/default/theme.css src/bin/hamcore/wwwroot/admin/default/tsconfig.json src/bin/hamcore/wwwroot/admin/default/tsconfig_webpack.json src/bin/hamcore/wwwroot/admin/default/tslint.json src/bin/hamcore/wwwroot/admin/default/webpack.config.js src/bin/hamcore/wwwroot/admin/index.html src/bin/hamcore/wwwroot/admin/README.md src/bin/hamcore/wwwroot/index.html # Build Action default: build diff --git a/src/makefiles/openbsd_64bit.mak b/src/makefiles/openbsd_64bit.mak index 28a02f3e..80f65701 100644 --- a/src/makefiles/openbsd_64bit.mak +++ b/src/makefiles/openbsd_64bit.mak @@ -89,7 +89,7 @@ HEADERS_MAYAQUA=src/Mayaqua/Cfg.h src/Mayaqua/cryptoki.h src/Mayaqua/Encrypt.h s HEADERS_CEDAR=src/Cedar/Account.h src/Cedar/Admin.h src/Cedar/AzureClient.h src/Cedar/AzureServer.h src/Cedar/Bridge.h src/Cedar/BridgeUnix.h src/Cedar/BridgeWin32.h src/Cedar/Cedar.h src/Cedar/CedarPch.h src/Cedar/CedarType.h src/Cedar/Client.h src/Cedar/CM.h src/Cedar/CMInner.h src/Cedar/Command.h src/Cedar/Connection.h src/Cedar/Console.h src/Cedar/Database.h src/Cedar/DDNS.h src/Cedar/EM.h src/Cedar/EMInner.h src/Cedar/EtherLog.h src/Cedar/Hub.h src/Cedar/Interop_OpenVPN.h src/Cedar/Interop_SSTP.h src/Cedar/IPsec.h src/Cedar/IPsec_EtherIP.h src/Cedar/IPsec_IKE.h src/Cedar/IPsec_IkePacket.h src/Cedar/IPsec_IPC.h src/Cedar/IPsec_L2TP.h src/Cedar/IPsec_PPP.h src/Cedar/IPsec_Win7.h src/Cedar/IPsec_Win7Inner.h src/Cedar/Layer3.h src/Cedar/Link.h src/Cedar/Listener.h src/Cedar/Logging.h src/Cedar/Nat.h src/Cedar/NativeStack.h src/Cedar/netcfgn.h src/Cedar/netcfgx.h src/Cedar/NM.h src/Cedar/NMInner.h src/Cedar/NullLan.h src/Cedar/Protocol.h src/Cedar/Radius.h src/Cedar/Remote.h src/Cedar/Sam.h src/Cedar/SecureInfo.h src/Cedar/SecureNAT.h src/Cedar/SeLowUser.h src/Cedar/Server.h src/Cedar/Session.h src/Cedar/SM.h src/Cedar/SMInner.h src/Cedar/SW.h src/Cedar/SWInner.h src/Cedar/UdpAccel.h src/Cedar/UT.h src/Cedar/VG.h src/Cedar/Virtual.h src/Cedar/VLan.h src/Cedar/VLanUnix.h src/Cedar/VLanWin32.h src/Cedar/WaterMark.h src/Cedar/WebUI.h src/Cedar/Win32Com.h src/Cedar/winpcap/bittypes.h src/Cedar/winpcap/bucket_lookup.h src/Cedar/winpcap/count_packets.h src/Cedar/winpcap/Devioctl.h src/Cedar/winpcap/Gnuc.h src/Cedar/winpcap/ip6_misc.h src/Cedar/winpcap/memory_t.h src/Cedar/winpcap/normal_lookup.h src/Cedar/winpcap/Ntddndis.h src/Cedar/winpcap/Ntddpack.h src/Cedar/winpcap/Packet32.h src/Cedar/winpcap/pcap.h src/Cedar/winpcap/pcap-bpf.h src/Cedar/winpcap/pcap-int.h src/Cedar/winpcap/pcap-stdinc.h src/Cedar/winpcap/pthread.h src/Cedar/winpcap/remote-ext.h src/Cedar/winpcap/sched.h src/Cedar/winpcap/semaphore.h src/Cedar/winpcap/tcp_session.h src/Cedar/winpcap/time_calls.h src/Cedar/winpcap/tme.h src/Cedar/winpcap/Win32-Extensions.h src/Cedar/WinUi.h src/Cedar/Wpc.h OBJECTS_MAYAQUA=tmp/objs/Mayaqua/Cfg.o tmp/objs/Mayaqua/Encrypt.o tmp/objs/Mayaqua/FileIO.o tmp/objs/Mayaqua/Internat.o tmp/objs/Mayaqua/Kernel.o tmp/objs/Mayaqua/Mayaqua.o tmp/objs/Mayaqua/Memory.o tmp/objs/Mayaqua/Microsoft.o tmp/objs/Mayaqua/Network.o tmp/objs/Mayaqua/Object.o tmp/objs/Mayaqua/OS.o tmp/objs/Mayaqua/Pack.o tmp/objs/Mayaqua/Secure.o tmp/objs/Mayaqua/Str.o tmp/objs/Mayaqua/Table.o tmp/objs/Mayaqua/TcpIp.o tmp/objs/Mayaqua/Tick64.o tmp/objs/Mayaqua/Tracking.o tmp/objs/Mayaqua/Unix.o tmp/objs/Mayaqua/Win32.o OBJECTS_CEDAR=tmp/objs/Cedar/Account.o tmp/objs/Cedar/Admin.o tmp/objs/Cedar/AzureClient.o tmp/objs/Cedar/AzureServer.o tmp/objs/Cedar/Bridge.o tmp/objs/Cedar/BridgeUnix.o tmp/objs/Cedar/BridgeWin32.o tmp/objs/Cedar/Cedar.o tmp/objs/Cedar/CedarPch.o tmp/objs/Cedar/Client.o tmp/objs/Cedar/CM.o tmp/objs/Cedar/Command.o tmp/objs/Cedar/Connection.o tmp/objs/Cedar/Console.o tmp/objs/Cedar/Database.o tmp/objs/Cedar/DDNS.o tmp/objs/Cedar/EM.o tmp/objs/Cedar/EtherLog.o tmp/objs/Cedar/Hub.o tmp/objs/Cedar/Interop_OpenVPN.o tmp/objs/Cedar/Interop_SSTP.o tmp/objs/Cedar/IPsec.o tmp/objs/Cedar/IPsec_EtherIP.o tmp/objs/Cedar/IPsec_IKE.o tmp/objs/Cedar/IPsec_IkePacket.o tmp/objs/Cedar/IPsec_IPC.o tmp/objs/Cedar/IPsec_L2TP.o tmp/objs/Cedar/IPsec_PPP.o tmp/objs/Cedar/IPsec_Win7.o tmp/objs/Cedar/Layer3.o tmp/objs/Cedar/Link.o tmp/objs/Cedar/Listener.o tmp/objs/Cedar/Logging.o tmp/objs/Cedar/Nat.o tmp/objs/Cedar/NativeStack.o tmp/objs/Cedar/NM.o tmp/objs/Cedar/NullLan.o tmp/objs/Cedar/Protocol.o tmp/objs/Cedar/Radius.o tmp/objs/Cedar/Remote.o tmp/objs/Cedar/Sam.o tmp/objs/Cedar/SecureInfo.o tmp/objs/Cedar/SecureNAT.o tmp/objs/Cedar/SeLowUser.o tmp/objs/Cedar/Server.o tmp/objs/Cedar/Session.o tmp/objs/Cedar/SM.o tmp/objs/Cedar/SW.o tmp/objs/Cedar/UdpAccel.o tmp/objs/Cedar/UT.o tmp/objs/Cedar/VG.o tmp/objs/Cedar/Virtual.o tmp/objs/Cedar/VLan.o tmp/objs/Cedar/VLanUnix.o tmp/objs/Cedar/VLanWin32.o tmp/objs/Cedar/WaterMark.o tmp/objs/Cedar/WebUI.o tmp/objs/Cedar/WinUi.o tmp/objs/Cedar/Wpc.o -HAMCORE_FILES=src/bin/hamcore/authors.txt src/bin/hamcore/backup_dir_readme.txt src/bin/hamcore/empty.config src/bin/hamcore/empty_sevpnclient.config src/bin/hamcore/eula.txt src/bin/hamcore/install_src.dat src/bin/hamcore/lang.config src/bin/hamcore/languages.txt src/bin/hamcore/languages_wine.txt src/bin/hamcore/legal.txt src/bin/hamcore/openvpn_readme.pdf src/bin/hamcore/openvpn_readme.txt src/bin/hamcore/openvpn_sample.ovpn src/bin/hamcore/root_certs.dat src/bin/hamcore/SOURCES_OF_BINARY_FILES.TXT src/bin/hamcore/strtable_cn.stb src/bin/hamcore/strtable_en.stb src/bin/hamcore/strtable_ja.stb src/bin/hamcore/vpnweb_sample_cn.htm src/bin/hamcore/vpnweb_sample_en.htm src/bin/hamcore/vpnweb_sample_ja.htm src/bin/hamcore/warning_cn.txt src/bin/hamcore/warning_en.txt src/bin/hamcore/warning_ja.txt src/bin/hamcore/webui/cryptcom.cgi src/bin/hamcore/webui/edituser.cgi src/bin/hamcore/webui/error.cgi src/bin/hamcore/webui/hub.cgi src/bin/hamcore/webui/license.cgi src/bin/hamcore/webui/listener.cgi src/bin/hamcore/webui/localbridge.cgi src/bin/hamcore/webui/login.cgi src/bin/hamcore/webui/newhub.cgi src/bin/hamcore/webui/redirect.cgi src/bin/hamcore/webui/securenat.cgi src/bin/hamcore/webui/server.cgi src/bin/hamcore/webui/session.cgi src/bin/hamcore/webui/user.cgi src/bin/hamcore/webui/webui.css +HAMCORE_FILES=src/bin/hamcore/authors.txt src/bin/hamcore/backup_dir_readme.txt src/bin/hamcore/empty.config src/bin/hamcore/empty_sevpnclient.config src/bin/hamcore/eula.txt src/bin/hamcore/install_src.dat src/bin/hamcore/languages.txt src/bin/hamcore/languages_wine.txt src/bin/hamcore/legal.txt src/bin/hamcore/openvpn_readme.pdf src/bin/hamcore/openvpn_readme.txt src/bin/hamcore/openvpn_sample.ovpn src/bin/hamcore/root_certs.dat src/bin/hamcore/SOURCES_OF_BINARY_FILES.TXT src/bin/hamcore/strtable_cn.stb src/bin/hamcore/strtable_en.stb src/bin/hamcore/strtable_ja.stb src/bin/hamcore/vpnserver_api_doc.html src/bin/hamcore/vpnweb_sample_cn.htm src/bin/hamcore/vpnweb_sample_en.htm src/bin/hamcore/vpnweb_sample_ja.htm src/bin/hamcore/warning_cn.txt src/bin/hamcore/warning_en.txt src/bin/hamcore/warning_ja.txt src/bin/hamcore/webui/cryptcom.cgi src/bin/hamcore/webui/edituser.cgi src/bin/hamcore/webui/error.cgi src/bin/hamcore/webui/hub.cgi src/bin/hamcore/webui/license.cgi src/bin/hamcore/webui/listener.cgi src/bin/hamcore/webui/localbridge.cgi src/bin/hamcore/webui/login.cgi src/bin/hamcore/webui/newhub.cgi src/bin/hamcore/webui/redirect.cgi src/bin/hamcore/webui/securenat.cgi src/bin/hamcore/webui/server.cgi src/bin/hamcore/webui/session.cgi src/bin/hamcore/webui/user.cgi src/bin/hamcore/webui/webui.css src/bin/hamcore/wwwroot/admin/default/.gitignore src/bin/hamcore/wwwroot/admin/default/.vscode/launch.json src/bin/hamcore/wwwroot/admin/default/.vscode/settings.json src/bin/hamcore/wwwroot/admin/default/.vscode/tasks.json src/bin/hamcore/wwwroot/admin/default/hub.html src/bin/hamcore/wwwroot/admin/default/include_footer.html src/bin/hamcore/wwwroot/admin/default/include_head.html src/bin/hamcore/wwwroot/admin/default/include_menu.html src/bin/hamcore/wwwroot/admin/default/index.html src/bin/hamcore/wwwroot/admin/default/out_webpack/bundle.js src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/index.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/index.d.ts.map src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/main.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/main.d.ts.map src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/vpnadmin.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/vpnadmin.d.ts.map src/bin/hamcore/wwwroot/admin/default/package.json src/bin/hamcore/wwwroot/admin/default/package-lock.json src/bin/hamcore/wwwroot/admin/default/src/ts/main.ts src/bin/hamcore/wwwroot/admin/default/theme.css src/bin/hamcore/wwwroot/admin/default/tsconfig.json src/bin/hamcore/wwwroot/admin/default/tsconfig_webpack.json src/bin/hamcore/wwwroot/admin/default/tslint.json src/bin/hamcore/wwwroot/admin/default/webpack.config.js src/bin/hamcore/wwwroot/admin/index.html src/bin/hamcore/wwwroot/admin/README.md src/bin/hamcore/wwwroot/index.html # Build Action default: build diff --git a/src/makefiles/solaris_32bit.mak b/src/makefiles/solaris_32bit.mak index 6085c9f0..40b163f3 100644 --- a/src/makefiles/solaris_32bit.mak +++ b/src/makefiles/solaris_32bit.mak @@ -89,7 +89,7 @@ HEADERS_MAYAQUA=src/Mayaqua/Cfg.h src/Mayaqua/cryptoki.h src/Mayaqua/Encrypt.h s HEADERS_CEDAR=src/Cedar/Account.h src/Cedar/Admin.h src/Cedar/AzureClient.h src/Cedar/AzureServer.h src/Cedar/Bridge.h src/Cedar/BridgeUnix.h src/Cedar/BridgeWin32.h src/Cedar/Cedar.h src/Cedar/CedarPch.h src/Cedar/CedarType.h src/Cedar/Client.h src/Cedar/CM.h src/Cedar/CMInner.h src/Cedar/Command.h src/Cedar/Connection.h src/Cedar/Console.h src/Cedar/Database.h src/Cedar/DDNS.h src/Cedar/EM.h src/Cedar/EMInner.h src/Cedar/EtherLog.h src/Cedar/Hub.h src/Cedar/Interop_OpenVPN.h src/Cedar/Interop_SSTP.h src/Cedar/IPsec.h src/Cedar/IPsec_EtherIP.h src/Cedar/IPsec_IKE.h src/Cedar/IPsec_IkePacket.h src/Cedar/IPsec_IPC.h src/Cedar/IPsec_L2TP.h src/Cedar/IPsec_PPP.h src/Cedar/IPsec_Win7.h src/Cedar/IPsec_Win7Inner.h src/Cedar/Layer3.h src/Cedar/Link.h src/Cedar/Listener.h src/Cedar/Logging.h src/Cedar/Nat.h src/Cedar/NativeStack.h src/Cedar/netcfgn.h src/Cedar/netcfgx.h src/Cedar/NM.h src/Cedar/NMInner.h src/Cedar/NullLan.h src/Cedar/Protocol.h src/Cedar/Radius.h src/Cedar/Remote.h src/Cedar/Sam.h src/Cedar/SecureInfo.h src/Cedar/SecureNAT.h src/Cedar/SeLowUser.h src/Cedar/Server.h src/Cedar/Session.h src/Cedar/SM.h src/Cedar/SMInner.h src/Cedar/SW.h src/Cedar/SWInner.h src/Cedar/UdpAccel.h src/Cedar/UT.h src/Cedar/VG.h src/Cedar/Virtual.h src/Cedar/VLan.h src/Cedar/VLanUnix.h src/Cedar/VLanWin32.h src/Cedar/WaterMark.h src/Cedar/WebUI.h src/Cedar/Win32Com.h src/Cedar/winpcap/bittypes.h src/Cedar/winpcap/bucket_lookup.h src/Cedar/winpcap/count_packets.h src/Cedar/winpcap/Devioctl.h src/Cedar/winpcap/Gnuc.h src/Cedar/winpcap/ip6_misc.h src/Cedar/winpcap/memory_t.h src/Cedar/winpcap/normal_lookup.h src/Cedar/winpcap/Ntddndis.h src/Cedar/winpcap/Ntddpack.h src/Cedar/winpcap/Packet32.h src/Cedar/winpcap/pcap.h src/Cedar/winpcap/pcap-bpf.h src/Cedar/winpcap/pcap-int.h src/Cedar/winpcap/pcap-stdinc.h src/Cedar/winpcap/pthread.h src/Cedar/winpcap/remote-ext.h src/Cedar/winpcap/sched.h src/Cedar/winpcap/semaphore.h src/Cedar/winpcap/tcp_session.h src/Cedar/winpcap/time_calls.h src/Cedar/winpcap/tme.h src/Cedar/winpcap/Win32-Extensions.h src/Cedar/WinUi.h src/Cedar/Wpc.h OBJECTS_MAYAQUA=tmp/objs/Mayaqua/Cfg.o tmp/objs/Mayaqua/Encrypt.o tmp/objs/Mayaqua/FileIO.o tmp/objs/Mayaqua/Internat.o tmp/objs/Mayaqua/Kernel.o tmp/objs/Mayaqua/Mayaqua.o tmp/objs/Mayaqua/Memory.o tmp/objs/Mayaqua/Microsoft.o tmp/objs/Mayaqua/Network.o tmp/objs/Mayaqua/Object.o tmp/objs/Mayaqua/OS.o tmp/objs/Mayaqua/Pack.o tmp/objs/Mayaqua/Secure.o tmp/objs/Mayaqua/Str.o tmp/objs/Mayaqua/Table.o tmp/objs/Mayaqua/TcpIp.o tmp/objs/Mayaqua/Tick64.o tmp/objs/Mayaqua/Tracking.o tmp/objs/Mayaqua/Unix.o tmp/objs/Mayaqua/Win32.o OBJECTS_CEDAR=tmp/objs/Cedar/Account.o tmp/objs/Cedar/Admin.o tmp/objs/Cedar/AzureClient.o tmp/objs/Cedar/AzureServer.o tmp/objs/Cedar/Bridge.o tmp/objs/Cedar/BridgeUnix.o tmp/objs/Cedar/BridgeWin32.o tmp/objs/Cedar/Cedar.o tmp/objs/Cedar/CedarPch.o tmp/objs/Cedar/Client.o tmp/objs/Cedar/CM.o tmp/objs/Cedar/Command.o tmp/objs/Cedar/Connection.o tmp/objs/Cedar/Console.o tmp/objs/Cedar/Database.o tmp/objs/Cedar/DDNS.o tmp/objs/Cedar/EM.o tmp/objs/Cedar/EtherLog.o tmp/objs/Cedar/Hub.o tmp/objs/Cedar/Interop_OpenVPN.o tmp/objs/Cedar/Interop_SSTP.o tmp/objs/Cedar/IPsec.o tmp/objs/Cedar/IPsec_EtherIP.o tmp/objs/Cedar/IPsec_IKE.o tmp/objs/Cedar/IPsec_IkePacket.o tmp/objs/Cedar/IPsec_IPC.o tmp/objs/Cedar/IPsec_L2TP.o tmp/objs/Cedar/IPsec_PPP.o tmp/objs/Cedar/IPsec_Win7.o tmp/objs/Cedar/Layer3.o tmp/objs/Cedar/Link.o tmp/objs/Cedar/Listener.o tmp/objs/Cedar/Logging.o tmp/objs/Cedar/Nat.o tmp/objs/Cedar/NativeStack.o tmp/objs/Cedar/NM.o tmp/objs/Cedar/NullLan.o tmp/objs/Cedar/Protocol.o tmp/objs/Cedar/Radius.o tmp/objs/Cedar/Remote.o tmp/objs/Cedar/Sam.o tmp/objs/Cedar/SecureInfo.o tmp/objs/Cedar/SecureNAT.o tmp/objs/Cedar/SeLowUser.o tmp/objs/Cedar/Server.o tmp/objs/Cedar/Session.o tmp/objs/Cedar/SM.o tmp/objs/Cedar/SW.o tmp/objs/Cedar/UdpAccel.o tmp/objs/Cedar/UT.o tmp/objs/Cedar/VG.o tmp/objs/Cedar/Virtual.o tmp/objs/Cedar/VLan.o tmp/objs/Cedar/VLanUnix.o tmp/objs/Cedar/VLanWin32.o tmp/objs/Cedar/WaterMark.o tmp/objs/Cedar/WebUI.o tmp/objs/Cedar/WinUi.o tmp/objs/Cedar/Wpc.o -HAMCORE_FILES=src/bin/hamcore/authors.txt src/bin/hamcore/backup_dir_readme.txt src/bin/hamcore/empty.config src/bin/hamcore/empty_sevpnclient.config src/bin/hamcore/eula.txt src/bin/hamcore/install_src.dat src/bin/hamcore/lang.config src/bin/hamcore/languages.txt src/bin/hamcore/languages_wine.txt src/bin/hamcore/legal.txt src/bin/hamcore/openvpn_readme.pdf src/bin/hamcore/openvpn_readme.txt src/bin/hamcore/openvpn_sample.ovpn src/bin/hamcore/root_certs.dat src/bin/hamcore/SOURCES_OF_BINARY_FILES.TXT src/bin/hamcore/strtable_cn.stb src/bin/hamcore/strtable_en.stb src/bin/hamcore/strtable_ja.stb src/bin/hamcore/vpnweb_sample_cn.htm src/bin/hamcore/vpnweb_sample_en.htm src/bin/hamcore/vpnweb_sample_ja.htm src/bin/hamcore/warning_cn.txt src/bin/hamcore/warning_en.txt src/bin/hamcore/warning_ja.txt src/bin/hamcore/webui/cryptcom.cgi src/bin/hamcore/webui/edituser.cgi src/bin/hamcore/webui/error.cgi src/bin/hamcore/webui/hub.cgi src/bin/hamcore/webui/license.cgi src/bin/hamcore/webui/listener.cgi src/bin/hamcore/webui/localbridge.cgi src/bin/hamcore/webui/login.cgi src/bin/hamcore/webui/newhub.cgi src/bin/hamcore/webui/redirect.cgi src/bin/hamcore/webui/securenat.cgi src/bin/hamcore/webui/server.cgi src/bin/hamcore/webui/session.cgi src/bin/hamcore/webui/user.cgi src/bin/hamcore/webui/webui.css +HAMCORE_FILES=src/bin/hamcore/authors.txt src/bin/hamcore/backup_dir_readme.txt src/bin/hamcore/empty.config src/bin/hamcore/empty_sevpnclient.config src/bin/hamcore/eula.txt src/bin/hamcore/install_src.dat src/bin/hamcore/languages.txt src/bin/hamcore/languages_wine.txt src/bin/hamcore/legal.txt src/bin/hamcore/openvpn_readme.pdf src/bin/hamcore/openvpn_readme.txt src/bin/hamcore/openvpn_sample.ovpn src/bin/hamcore/root_certs.dat src/bin/hamcore/SOURCES_OF_BINARY_FILES.TXT src/bin/hamcore/strtable_cn.stb src/bin/hamcore/strtable_en.stb src/bin/hamcore/strtable_ja.stb src/bin/hamcore/vpnserver_api_doc.html src/bin/hamcore/vpnweb_sample_cn.htm src/bin/hamcore/vpnweb_sample_en.htm src/bin/hamcore/vpnweb_sample_ja.htm src/bin/hamcore/warning_cn.txt src/bin/hamcore/warning_en.txt src/bin/hamcore/warning_ja.txt src/bin/hamcore/webui/cryptcom.cgi src/bin/hamcore/webui/edituser.cgi src/bin/hamcore/webui/error.cgi src/bin/hamcore/webui/hub.cgi src/bin/hamcore/webui/license.cgi src/bin/hamcore/webui/listener.cgi src/bin/hamcore/webui/localbridge.cgi src/bin/hamcore/webui/login.cgi src/bin/hamcore/webui/newhub.cgi src/bin/hamcore/webui/redirect.cgi src/bin/hamcore/webui/securenat.cgi src/bin/hamcore/webui/server.cgi src/bin/hamcore/webui/session.cgi src/bin/hamcore/webui/user.cgi src/bin/hamcore/webui/webui.css src/bin/hamcore/wwwroot/admin/default/.gitignore src/bin/hamcore/wwwroot/admin/default/.vscode/launch.json src/bin/hamcore/wwwroot/admin/default/.vscode/settings.json src/bin/hamcore/wwwroot/admin/default/.vscode/tasks.json src/bin/hamcore/wwwroot/admin/default/hub.html src/bin/hamcore/wwwroot/admin/default/include_footer.html src/bin/hamcore/wwwroot/admin/default/include_head.html src/bin/hamcore/wwwroot/admin/default/include_menu.html src/bin/hamcore/wwwroot/admin/default/index.html src/bin/hamcore/wwwroot/admin/default/out_webpack/bundle.js src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/index.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/index.d.ts.map src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/main.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/main.d.ts.map src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/vpnadmin.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/vpnadmin.d.ts.map src/bin/hamcore/wwwroot/admin/default/package.json src/bin/hamcore/wwwroot/admin/default/package-lock.json src/bin/hamcore/wwwroot/admin/default/src/ts/main.ts src/bin/hamcore/wwwroot/admin/default/theme.css src/bin/hamcore/wwwroot/admin/default/tsconfig.json src/bin/hamcore/wwwroot/admin/default/tsconfig_webpack.json src/bin/hamcore/wwwroot/admin/default/tslint.json src/bin/hamcore/wwwroot/admin/default/webpack.config.js src/bin/hamcore/wwwroot/admin/index.html src/bin/hamcore/wwwroot/admin/README.md src/bin/hamcore/wwwroot/index.html # Build Action default: build diff --git a/src/makefiles/solaris_64bit.mak b/src/makefiles/solaris_64bit.mak index 94427037..faea5f69 100644 --- a/src/makefiles/solaris_64bit.mak +++ b/src/makefiles/solaris_64bit.mak @@ -89,7 +89,7 @@ HEADERS_MAYAQUA=src/Mayaqua/Cfg.h src/Mayaqua/cryptoki.h src/Mayaqua/Encrypt.h s HEADERS_CEDAR=src/Cedar/Account.h src/Cedar/Admin.h src/Cedar/AzureClient.h src/Cedar/AzureServer.h src/Cedar/Bridge.h src/Cedar/BridgeUnix.h src/Cedar/BridgeWin32.h src/Cedar/Cedar.h src/Cedar/CedarPch.h src/Cedar/CedarType.h src/Cedar/Client.h src/Cedar/CM.h src/Cedar/CMInner.h src/Cedar/Command.h src/Cedar/Connection.h src/Cedar/Console.h src/Cedar/Database.h src/Cedar/DDNS.h src/Cedar/EM.h src/Cedar/EMInner.h src/Cedar/EtherLog.h src/Cedar/Hub.h src/Cedar/Interop_OpenVPN.h src/Cedar/Interop_SSTP.h src/Cedar/IPsec.h src/Cedar/IPsec_EtherIP.h src/Cedar/IPsec_IKE.h src/Cedar/IPsec_IkePacket.h src/Cedar/IPsec_IPC.h src/Cedar/IPsec_L2TP.h src/Cedar/IPsec_PPP.h src/Cedar/IPsec_Win7.h src/Cedar/IPsec_Win7Inner.h src/Cedar/Layer3.h src/Cedar/Link.h src/Cedar/Listener.h src/Cedar/Logging.h src/Cedar/Nat.h src/Cedar/NativeStack.h src/Cedar/netcfgn.h src/Cedar/netcfgx.h src/Cedar/NM.h src/Cedar/NMInner.h src/Cedar/NullLan.h src/Cedar/Protocol.h src/Cedar/Radius.h src/Cedar/Remote.h src/Cedar/Sam.h src/Cedar/SecureInfo.h src/Cedar/SecureNAT.h src/Cedar/SeLowUser.h src/Cedar/Server.h src/Cedar/Session.h src/Cedar/SM.h src/Cedar/SMInner.h src/Cedar/SW.h src/Cedar/SWInner.h src/Cedar/UdpAccel.h src/Cedar/UT.h src/Cedar/VG.h src/Cedar/Virtual.h src/Cedar/VLan.h src/Cedar/VLanUnix.h src/Cedar/VLanWin32.h src/Cedar/WaterMark.h src/Cedar/WebUI.h src/Cedar/Win32Com.h src/Cedar/winpcap/bittypes.h src/Cedar/winpcap/bucket_lookup.h src/Cedar/winpcap/count_packets.h src/Cedar/winpcap/Devioctl.h src/Cedar/winpcap/Gnuc.h src/Cedar/winpcap/ip6_misc.h src/Cedar/winpcap/memory_t.h src/Cedar/winpcap/normal_lookup.h src/Cedar/winpcap/Ntddndis.h src/Cedar/winpcap/Ntddpack.h src/Cedar/winpcap/Packet32.h src/Cedar/winpcap/pcap.h src/Cedar/winpcap/pcap-bpf.h src/Cedar/winpcap/pcap-int.h src/Cedar/winpcap/pcap-stdinc.h src/Cedar/winpcap/pthread.h src/Cedar/winpcap/remote-ext.h src/Cedar/winpcap/sched.h src/Cedar/winpcap/semaphore.h src/Cedar/winpcap/tcp_session.h src/Cedar/winpcap/time_calls.h src/Cedar/winpcap/tme.h src/Cedar/winpcap/Win32-Extensions.h src/Cedar/WinUi.h src/Cedar/Wpc.h OBJECTS_MAYAQUA=tmp/objs/Mayaqua/Cfg.o tmp/objs/Mayaqua/Encrypt.o tmp/objs/Mayaqua/FileIO.o tmp/objs/Mayaqua/Internat.o tmp/objs/Mayaqua/Kernel.o tmp/objs/Mayaqua/Mayaqua.o tmp/objs/Mayaqua/Memory.o tmp/objs/Mayaqua/Microsoft.o tmp/objs/Mayaqua/Network.o tmp/objs/Mayaqua/Object.o tmp/objs/Mayaqua/OS.o tmp/objs/Mayaqua/Pack.o tmp/objs/Mayaqua/Secure.o tmp/objs/Mayaqua/Str.o tmp/objs/Mayaqua/Table.o tmp/objs/Mayaqua/TcpIp.o tmp/objs/Mayaqua/Tick64.o tmp/objs/Mayaqua/Tracking.o tmp/objs/Mayaqua/Unix.o tmp/objs/Mayaqua/Win32.o OBJECTS_CEDAR=tmp/objs/Cedar/Account.o tmp/objs/Cedar/Admin.o tmp/objs/Cedar/AzureClient.o tmp/objs/Cedar/AzureServer.o tmp/objs/Cedar/Bridge.o tmp/objs/Cedar/BridgeUnix.o tmp/objs/Cedar/BridgeWin32.o tmp/objs/Cedar/Cedar.o tmp/objs/Cedar/CedarPch.o tmp/objs/Cedar/Client.o tmp/objs/Cedar/CM.o tmp/objs/Cedar/Command.o tmp/objs/Cedar/Connection.o tmp/objs/Cedar/Console.o tmp/objs/Cedar/Database.o tmp/objs/Cedar/DDNS.o tmp/objs/Cedar/EM.o tmp/objs/Cedar/EtherLog.o tmp/objs/Cedar/Hub.o tmp/objs/Cedar/Interop_OpenVPN.o tmp/objs/Cedar/Interop_SSTP.o tmp/objs/Cedar/IPsec.o tmp/objs/Cedar/IPsec_EtherIP.o tmp/objs/Cedar/IPsec_IKE.o tmp/objs/Cedar/IPsec_IkePacket.o tmp/objs/Cedar/IPsec_IPC.o tmp/objs/Cedar/IPsec_L2TP.o tmp/objs/Cedar/IPsec_PPP.o tmp/objs/Cedar/IPsec_Win7.o tmp/objs/Cedar/Layer3.o tmp/objs/Cedar/Link.o tmp/objs/Cedar/Listener.o tmp/objs/Cedar/Logging.o tmp/objs/Cedar/Nat.o tmp/objs/Cedar/NativeStack.o tmp/objs/Cedar/NM.o tmp/objs/Cedar/NullLan.o tmp/objs/Cedar/Protocol.o tmp/objs/Cedar/Radius.o tmp/objs/Cedar/Remote.o tmp/objs/Cedar/Sam.o tmp/objs/Cedar/SecureInfo.o tmp/objs/Cedar/SecureNAT.o tmp/objs/Cedar/SeLowUser.o tmp/objs/Cedar/Server.o tmp/objs/Cedar/Session.o tmp/objs/Cedar/SM.o tmp/objs/Cedar/SW.o tmp/objs/Cedar/UdpAccel.o tmp/objs/Cedar/UT.o tmp/objs/Cedar/VG.o tmp/objs/Cedar/Virtual.o tmp/objs/Cedar/VLan.o tmp/objs/Cedar/VLanUnix.o tmp/objs/Cedar/VLanWin32.o tmp/objs/Cedar/WaterMark.o tmp/objs/Cedar/WebUI.o tmp/objs/Cedar/WinUi.o tmp/objs/Cedar/Wpc.o -HAMCORE_FILES=src/bin/hamcore/authors.txt src/bin/hamcore/backup_dir_readme.txt src/bin/hamcore/empty.config src/bin/hamcore/empty_sevpnclient.config src/bin/hamcore/eula.txt src/bin/hamcore/install_src.dat src/bin/hamcore/lang.config src/bin/hamcore/languages.txt src/bin/hamcore/languages_wine.txt src/bin/hamcore/legal.txt src/bin/hamcore/openvpn_readme.pdf src/bin/hamcore/openvpn_readme.txt src/bin/hamcore/openvpn_sample.ovpn src/bin/hamcore/root_certs.dat src/bin/hamcore/SOURCES_OF_BINARY_FILES.TXT src/bin/hamcore/strtable_cn.stb src/bin/hamcore/strtable_en.stb src/bin/hamcore/strtable_ja.stb src/bin/hamcore/vpnweb_sample_cn.htm src/bin/hamcore/vpnweb_sample_en.htm src/bin/hamcore/vpnweb_sample_ja.htm src/bin/hamcore/warning_cn.txt src/bin/hamcore/warning_en.txt src/bin/hamcore/warning_ja.txt src/bin/hamcore/webui/cryptcom.cgi src/bin/hamcore/webui/edituser.cgi src/bin/hamcore/webui/error.cgi src/bin/hamcore/webui/hub.cgi src/bin/hamcore/webui/license.cgi src/bin/hamcore/webui/listener.cgi src/bin/hamcore/webui/localbridge.cgi src/bin/hamcore/webui/login.cgi src/bin/hamcore/webui/newhub.cgi src/bin/hamcore/webui/redirect.cgi src/bin/hamcore/webui/securenat.cgi src/bin/hamcore/webui/server.cgi src/bin/hamcore/webui/session.cgi src/bin/hamcore/webui/user.cgi src/bin/hamcore/webui/webui.css +HAMCORE_FILES=src/bin/hamcore/authors.txt src/bin/hamcore/backup_dir_readme.txt src/bin/hamcore/empty.config src/bin/hamcore/empty_sevpnclient.config src/bin/hamcore/eula.txt src/bin/hamcore/install_src.dat src/bin/hamcore/languages.txt src/bin/hamcore/languages_wine.txt src/bin/hamcore/legal.txt src/bin/hamcore/openvpn_readme.pdf src/bin/hamcore/openvpn_readme.txt src/bin/hamcore/openvpn_sample.ovpn src/bin/hamcore/root_certs.dat src/bin/hamcore/SOURCES_OF_BINARY_FILES.TXT src/bin/hamcore/strtable_cn.stb src/bin/hamcore/strtable_en.stb src/bin/hamcore/strtable_ja.stb src/bin/hamcore/vpnserver_api_doc.html src/bin/hamcore/vpnweb_sample_cn.htm src/bin/hamcore/vpnweb_sample_en.htm src/bin/hamcore/vpnweb_sample_ja.htm src/bin/hamcore/warning_cn.txt src/bin/hamcore/warning_en.txt src/bin/hamcore/warning_ja.txt src/bin/hamcore/webui/cryptcom.cgi src/bin/hamcore/webui/edituser.cgi src/bin/hamcore/webui/error.cgi src/bin/hamcore/webui/hub.cgi src/bin/hamcore/webui/license.cgi src/bin/hamcore/webui/listener.cgi src/bin/hamcore/webui/localbridge.cgi src/bin/hamcore/webui/login.cgi src/bin/hamcore/webui/newhub.cgi src/bin/hamcore/webui/redirect.cgi src/bin/hamcore/webui/securenat.cgi src/bin/hamcore/webui/server.cgi src/bin/hamcore/webui/session.cgi src/bin/hamcore/webui/user.cgi src/bin/hamcore/webui/webui.css src/bin/hamcore/wwwroot/admin/default/.gitignore src/bin/hamcore/wwwroot/admin/default/.vscode/launch.json src/bin/hamcore/wwwroot/admin/default/.vscode/settings.json src/bin/hamcore/wwwroot/admin/default/.vscode/tasks.json src/bin/hamcore/wwwroot/admin/default/hub.html src/bin/hamcore/wwwroot/admin/default/include_footer.html src/bin/hamcore/wwwroot/admin/default/include_head.html src/bin/hamcore/wwwroot/admin/default/include_menu.html src/bin/hamcore/wwwroot/admin/default/index.html src/bin/hamcore/wwwroot/admin/default/out_webpack/bundle.js src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/index.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/index.d.ts.map src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/main.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/main.d.ts.map src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/vpnadmin.d.ts src/bin/hamcore/wwwroot/admin/default/out_webpack/ts/vpnadmin.d.ts.map src/bin/hamcore/wwwroot/admin/default/package.json src/bin/hamcore/wwwroot/admin/default/package-lock.json src/bin/hamcore/wwwroot/admin/default/src/ts/main.ts src/bin/hamcore/wwwroot/admin/default/theme.css src/bin/hamcore/wwwroot/admin/default/tsconfig.json src/bin/hamcore/wwwroot/admin/default/tsconfig_webpack.json src/bin/hamcore/wwwroot/admin/default/tslint.json src/bin/hamcore/wwwroot/admin/default/webpack.config.js src/bin/hamcore/wwwroot/admin/index.html src/bin/hamcore/wwwroot/admin/README.md src/bin/hamcore/wwwroot/index.html # Build Action default: build diff --git a/src/vpnweb/vpnweb.h b/src/vpnweb/vpnweb.h index b2b4f269..a3f890d9 100644 --- a/src/vpnweb/vpnweb.h +++ b/src/vpnweb/vpnweb.h @@ -4,7 +4,7 @@ /* File created by MIDL compiler version 7.00.0500 */ -/* at Thu Feb 28 18:40:10 2019 +/* at Sun Jul 07 19:58:30 2019 */ /* Compiler settings for .\vpnweb.idl: Oicf, W1, Zp8, env=Win32 (32b run) diff --git a/src/vpnweb/vpnweb_i.c b/src/vpnweb/vpnweb_i.c index 8747f44c..ca3c4a3f 100644 --- a/src/vpnweb/vpnweb_i.c +++ b/src/vpnweb/vpnweb_i.c @@ -6,7 +6,7 @@ /* File created by MIDL compiler version 7.00.0500 */ -/* at Thu Feb 28 18:40:10 2019 +/* at Sun Jul 07 19:58:30 2019 */ /* Compiler settings for .\vpnweb.idl: Oicf, W1, Zp8, env=Win32 (32b run) diff --git a/src/vpnweb/vpnweb_p.c b/src/vpnweb/vpnweb_p.c index ebc5b8ff..824006cc 100644 --- a/src/vpnweb/vpnweb_p.c +++ b/src/vpnweb/vpnweb_p.c @@ -4,7 +4,7 @@ /* File created by MIDL compiler version 7.00.0500 */ -/* at Thu Feb 28 18:40:10 2019 +/* at Sun Jul 07 19:58:30 2019 */ /* Compiler settings for .\vpnweb.idl: Oicf, W1, Zp8, env=Win32 (32b run)