<!doctype html>
<html lang="zh">
	<head>
		<meta charset="UTF-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>{{g.title}}</title>
		<link rel="shortcut icon" href="/static/vite/favicon.ico" type="image/x-icon" />
		<style type="text/css">
			* {
			  margin: 0;
			  padding: 0;
			}

			html,
			body {
			  width: 100%;
			  height: 100%;
			}

			body {
			  line-height: 1.4;
			  background-color: var(--page-bg);
			  font-family: "微软雅黑", Arial, Helvetica, sans-serif;
			  font-size: 12px;
			  color: var(--login-body-color);
			}

			input {
			  background: none;
			  box-sizing: border-box;
			  -webkit-appearance: none;
			}

			button {
			  outline: none;
			  background: none;
			  box-sizing: border-box;
			}

			::-webkit-scrollbar {
			  width: 10px;
			  height: 1px;
			}

			::-webkit-scrollbar-thumb {
			  border-radius: 10px;
			  box-shadow: inset 0 0 5px rgb(0 0 0 / 20%);
			  background: #999;
			}

			::-webkit-scrollbar-track {
			  box-shadow: inset 0 0 5px rgb(0 0 0 / 20%);
			  border-radius: 10px;
			  background: #ededed;
			}

			.hide {
			  display: none !important;
			}

			.bt_link {
			  text-decoration: none;
			  color: #20a53a;
			}

			.main {
			  position: relative;
			  display: flex;
			  align-items: center;
			  justify-content: center;
			  flex-direction: column;
			  height: 100%;
			}
			.login-bg {
				width: 100%;
				height: 100%;
				background-position: center center;
				background-repeat: no-repeat;
				background-size: cover;
				position: absolute;
				top: 0;
				left: 0;
			}
			.login-bg.active {
				background-image: url('{{ g['panel_theme']['login']['bg_image'] }}');
				opacity: {{ g['panel_theme']['login']['bg_image_opacity'] / 100 }};
			}
			.login {
			  position: relative;
			  width: 360px;
			  height: 270px;
			  padding: 80px 40px 90px;
			  background: var(--login-bg);
			  border-radius: var(--login-box-radius);
			  box-shadow: var(--login-box-shadow);
			}

			.login.code {
			  height: 345px;
			}

			.entrance {
			  position: absolute;
			  top: 5px;
			  right: 5px;
			}

			.entrance .bg_img {
			  width: 60px;
			  height: 60px;
			  background-image: var(--login-qr-code-img);
			  background-size: 120px 120px;
			  background-repeat: no-repeat;
			  background-position: 0 0;
			  cursor: pointer;
			}

			.entrance .bg_img:hover {
			  background-position: -60px 0;
			}

			.entrance .bg_img.pc {
			  background-position: 0 -60px;
			}

			.entrance .bg_img.pc:hover {
			  background-position: -60px -60px;
			}

			.entrance .tips {
			  position: absolute;
			  display: flex;
			  align-items: center;
			  top: 15px;
			  right: 55px;
			  max-width: 380px;
			  padding: 8px 10px;
			  background-color: var(--login-tips-bg);
			  border-radius: 4px;
			  text-align: center;
			  white-space: nowrap;
			}

			.entrance .tips::before {
			  content: "";
			  position: absolute;
			  top: 8px;
			  right: -11px;
			  width: 0;
			  height: 0;
			  margin-left: -6px;
			  border: 6px solid var(--login-tips-bg);
			  border-color: transparent transparent transparent var(--login-tips-bg);
			}

			.entrance .tips .icon {
			  display: inline-flex;
			}

			.entrance .tips .text {
			  display: inline-flex;
			  white-space: nowrap;
			}

			.icon {
			  width: 16px;
			  height: 16px;
			  background-size: cover;
			  background-position: center;
			  background-repeat: no-repeat;
			}

			.icon.scan {
			  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAgCAYAAACYTcH3AAAAAXNSR0IArs4c6QAAAdFJREFUWEdjZIACuSUW1kyMTKUMDAyODAwMfDBxLHTDg+hjjXjkGUSnOvBwC/7czPCf0QGPugcMDAy7HkQfS4epYQQxoA45gs8CJLkHD6KPKeJTK7/MKovxP8NUIs2Dew7sGIWlVhMYGBjyoZqvMjD+f43LIKZ/DL33Yo5vIWSR/BKrYkam/z441SGF2h/W/zJPwo4/hThmmeV+WJD++8+s/Sjm8DVCllEqr7jUMvQ/A+MqsDn//jk+iD1xAMMxD6KPgcVoDRQWWzgwMDHtH3UMekiPhgyutDdUQsa6n+H//4L//xnuPIw5pkrrnAQyX3aBlTIzK8MdEJuJmUn9XsSRW/BsrLDMMpKB8f/xB5EnQMU0XQA4qhgYGEBlDIimS5lCrM8Gl2MUl1i5/Wf6X0ms62mi7j/T6wfRR8MYFZZaXWFgYNCmiSWkGZoFcsx8BgaGBNL0UV316/+MDBGDK81Q3Y8UGAgPGbmlNsb/WP++ADVyKDCPJK1yS2y1WNn+/Lobdhxc+MFaevUMDAwNDAwMVx9EH9MhyUQyFSuvslT5+5vxNrhtBW3QjTauQKExVGptRIN8tA082jtAKgaISsAD34kbTN3bQdXxB0XlYBgSAQBVv1HZQYwH1wAAAABJRU5ErkJggg==");
			  background-size: 14px;
			}

			.icon.safe {
			  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAADAElEQVRYR8VWS1LbQBTs51Sogo3NCTKcAC+xN5gTxCyDSGFOgHOCJCeIOQGmgpIl5gSYjcTSOQGTE8TeOJSp6KVmRvJHGlljXAWzorDmdc/rfh/CKx96ZXw4ERDf9xoolfbBXAFQ1aSJZn8DAzAP48cMQDQEcV8ehXdFD8wlEIOegNEEQYGlDv8GION/CoDeZT/BEIQeouhSfrzv28hkCAi/XgX4GiBhLmigHgh9MEnpBYNlr9L3iQUYDQDNGTGWAB2m71sI1PoAqXRfgqhTBFiUYk2IuQ2iE4DvpBcqYtOTS0B6gZM/iggkvwu/zisQQFV6oUV3V7jsdysQsDN9PrS5Kfya8tCuPA62CyRYn4D4uSfw+DiUp4OkNA0B0H5aWlsVWLVyzYAxHW5BuJNe0Jx54AUIzIFXQHwoj8LeixFYAEd0Kr377nzW1pZAXFQr85ouBp+mvQIL+NSEz/WA8Os9MPZBOEg3pqKXL0qQLW97I0qVi/hRa4LpGqx7+5SEK7jJwEqNKFsuwt9rAaWLhIQZE9rtuWlPyeTaCevKue8xGW+nNV8goaK7gl9UK9jY+gPgZr40TYjUEX79C4DPiKID2widktD3sm639Yt4tN8C+Cq9QMVfNoySVPMneRx2cgOqZSBnxmcedVVT0/CbjXA2A6qNRqUHW7pcu6Elq0bWUrQjP9wnS4z+zDpyhV+TYCrjabyTV/uuZFT/wNutBxCPpBfGS84SCeKSMT4AutILTl3BrHJd1bp6GWG7pPk74VV9AMKuq9Gs4LPS/SWPA7PMpk4+Ae0FGgBUBrgtvfB8lUyIqfF4hBJX09onsZauXfGCquZ4Gcx9PP09LPKE0XzzGkQNgEcANZbtlYV7nw64sdkzi6puxR1MxueZJmWazRkY7XiNv8Fk3CoiXEggSZVpQNQx2cAQ4C7esJHlH50B1DLA6tVKssVxnCefMwFdHeaVbQVgvDF/dLpVdjpFr17aCV2NFk/Ilukm3J3fflxj5DaiVQKs++1KEqwLZrv/HyI/ujC8s0y6AAAAAElFTkSuQmCC");
			}

			.tips .text {
			  margin-left: 4px;
			  color: #20a53a;
			}

			.account .form_title {
			  height: 40px;
			  margin-bottom: 25px;
			  padding: 0 25px;
			  cursor: pointer;
			  overflow: hidden;
			  text-align: center;
			  font-size: 26px;
			  color: var(--login-text-color);
			}

			.account .form_item {
			  position: relative;
			  margin-bottom: 20px;
			  padding: 5px 0;
			}

			.account .error_tips {
			  position: relative;
			  top: -14px;
			  color: red;
			}

			.form_input {
			  width: 100%;
			  height: 42px;
			  padding: 5px 10px;
			  border: var(--login-input-border);
			  border-radius: var(--login-input-radius);
			  box-shadow: 0 3px 5px -4px rgb(0 0 0 / 40%) inset,
			    -1px 0 3px -2px rgb(0 0 0 / 10%) inset;
			  z-index: 1;
			  color: var(--login-input-color);
			}

			.form_input.validform_error {
			  border: 1px solid #e53451;
			  box-shadow: 0 0 2px #ea5d74;
			}

			.validform_checktip {
			  position: absolute;
			  top: 14px;
			  right: 10px;
			  height: 24px;
			  padding: 0 6px;
			  line-height: 24px;
			  overflow: hidden;
			  z-index: 1;
			  text-align: right;
			  font-size: 12px;
			}

			.validform_checktip.validform_wrong {
			  background: #e53451;
			  border-radius: 3px;
			  color: #fff;
			}

			.validform_checktip.validform_right {
			  padding: 0 10px;
			  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAAIaSURBVEiJvZY9i1NBFIafvYrEwg12fjTWcbbZYGEzjdNoBGs/wdrapFhMkRAk6bfeHxBshAWFkSzTLLgmohlT+xey+LHKaizmZPcy5t6YgHuawMyc5z3n3DNnsjKZTJhn2qoCsAasy9IAGDrjD+b5rmQJCLQOVIASMAb6sl0GisAI2AYaWWIzBbRV14EtYB9oA31n/OfozBURqgGrwGNn/G6ugLbqDNACngBNoOOM/zUzxWOfU0AVeAZsAhvO+J/T/dPR+RahJNec8Z/ywFOTAJ5rq14CXVl++lcGUpY3i8BnZHMV2ANuTMuVyEaBUPPmsnAA8W0CW8IMAoRu2Qc6y8JT1hFWPS1QAdrzPmiWaasuaKteaKvOC6MtTBJJpcRxjy8KvwjsAL8lcoRV0lYVEsINHcd9vgC8B3wE7k4rIKwxsJYQrn8/cjyrrYpbOIZfksg/APec8YfRkT6wnsSOYnVgR1t1LgfeA95nwI8sIQyucrTeItT0VSyirboskQ+A+zmNUQYGCTAEijJbAHDGfwFuAofAa23VagreI6T/IAsurCIwTGQKjuIsnPFfgVvADxEpSeTv8uCp6EfO+IPpN9gGajK4YpEK8F0yfQs8zIMLoybMo4vWIIzcauzgjP8G3AbuAI/+4TJWhdWAkxp2EukuYZ535eAy8C6wmX544su0Ib972qqlH5z0/sk+mRHg/z36GWJL/W35AyvRFdMiDyNOAAAAAElFTkSuQmCC");
			  background-repeat: no-repeat;
			  background-position: right center;
			  background-size: 16px;
			}

			.form_item.check_code {
			  display: flex;
			  align-items: center;
			}

			.form_item.check_code .form_input {
			  flex: 1;
			  width: auto;
			}

			.form_item.check_code .validform_checktip {
			  right: 127px;
			}

			.form_item.check_code .check_img {
			  width: 100px;
			  height: 40px;
			  margin-left: 16px;
			  border: 1px solid #ccc;
			  cursor: pointer;
			}

			.login_btn {
			  width: 100%;
			  height: 44px;
			  background: linear-gradient(#20a53a, #189d32);
			  border: 1px solid #20a53a;
			  border-radius: var(--login-btn-radius);
			  cursor: pointer;
			  text-align: center;
			  font-size: 16px;
			  color: #fff;
			  box-shadow: inset 0 1px 2px #30ad42;
			  text-shadow: #00851a 0 -1px 0;
			}

			.login_btn:hover {
			  background: linear-gradient(#10952a, #088d22);
			  border: 1px solid #10952a;
			}

			.account .forget_pwd {
			  position: absolute;
			  right: 40px;
			  bottom: 20px;
			  color: #20a53a;
			}

			.static_cdn {
			  position: absolute;
			  left: 0;
			  bottom: 0;
			  height: 40px;
			  opacity: 0.8;
			}

			.static_cdn .cont {
			  display: flex;
			  margin-left: 40px;
			}

			.static_cdn .name {
			  height: 22px;
			  padding: 0 5px;
			  line-height: 22px;
			  border: 1px solid #ddd;
			  background-color: #eee;
			  color: #777;
			  font-size: 12px;
			}

			.account select {
			  height: 24px;
			  line-height: 22px;
			  margin-left: -1px;
			  padding-left: 5px;
			  border: var(--login-select-border);
			  background-color: var(--login-select-bg);
			  color: #777;
			  font-size: 12px;
			  border-radius: var(--login-select-radius);
			}

			.scan_code {
			  display: flex;
			  flex-direction: column;
			  align-items: center;
			  justify-content: center;
			  width: 100%;
			  height: 100%;
			}

			.scan_code .scan_title {
			  margin-bottom: 20px;
			  font-size: 23px;
			  color: var(--login-scan-title-color);
			  text-align: center;
			}

			.scan_code .qrcode {
			  width: 150px;
			  height: 150px;
			}

			.scan_code .scan_tip {
			  margin-top: 15px;
			  text-align: center;
			}

			.scan_tip .link {
			  font-size: 0;
			}

			.scan_tip .link a,
			.scan_tip .link span {
			  font-size: 13px;
			}

			.scan_tip .desc {
			  display: flex;
			  align-items: center;
			  justify-content: center;
			  margin-top: 10px;
			}

			.scan_tip .desc .icon {
			  width: 25px;
			  height: 25px;
			  background-size: 23px;
			}

			.scan_tip .desc .text {
			  margin-left: 10px;
			  font-size: 18px;
			  font-weight: 600;
			  color: var(--login-scan-text-color);
			}

			.verification_view {
			  padding: 30px 40px;
			}

			.verification_view .v_title {
			  height: 40px;
			  margin-bottom: 15px;
			  overflow: hidden;
			  text-align: center;
			  font-size: 21px;
			  color: var(--login-text-color);
			}

			.verification_view .v_input {
			  margin-bottom: 15px;
			}

			.verification_view .v_input input {
			  width: 100%;
			  height: 40px;
			  padding: 4px 10px;
			  line-height: 30px;
			  outline: none;
			  border-radius: var(--login-input-radius);
			  box-sizing: border-box;
			  border: var(--login-input-border);
			  box-shadow: 0 3px 5px -4px rgb(0 0 0 / 40%) inset,
			    -1px 0 3px -2px rgb(0 0 0 / 10%) inset;
			  z-index: 1;
			  color: var(--login-input-color);
			}

			.verification_view .v_btn button {
			  width: 100%;
			  height: 40px;
			  border-radius: var(--login-btn-radius);
			  border: 1px solid #20a53a;
			  background: linear-gradient(#20a53a, #189d32);
			  text-shadow: #00851a 0 -1px 0;
			  box-shadow: inset 0 1px 2px #30ad42;
			  cursor: pointer;
			  text-align: center;
			  font-size: 15px;
			  color: #fff;
			}

			.verification_view .v_tips {
			  margin-top: 13px;
			  font-size: 13px;
			  color: #777;
			}

			.layui-layer-msg {
			  position: fixed;
			  min-width: 180px;
			  margin: 0;
			  padding: 0;
			  border-radius: 2px;
			  background-color: #fff;
			  border: 1px solid #d3d4d3;
			  box-shadow: none;
			}

			.layui-layer-msg .layui-layer-content {
			  position: relative;
			  padding: 20px 20px 20px 55px;
			  line-height: 24px;
			  word-break: break-all;
			  overflow: hidden;
			  overflow-x: hidden;
			  overflow-y: auto;
			  font-size: 14px;
			  text-align: left;
			}

			.layui-layer-msg .layui-layer-ico {
			  position: absolute;
			  top: 16px;
			  left: 15px;
			  display: inline-block;
			  width: 30px;
			  height: 30px;
			  vertical-align: top;
			  background-image: url("data:image/png;base64,[encoded data, 15716 characters]");
			  background-repeat: no-repeat;
			}

			.layui-layer-msg .layui-layer-ico1 {
			  background-position: -30px 0;
			}

			.layui-layer-msg .layui-layer-ico2 {
			  background-position: -60px 0;
			}

			.layui-layer-msg .layui-layer-ico16 {
			  background-image: url("data:image/gif;base64,R0lGODlhIAAgALMAAP///7Ozs/v7+9bW1uHh4fLy8rq6uoGBgTQ0NAEBARsbG8TExJeXl/39/VRUVAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQFBQAAACwAAAAAIAAgAAAE5xDISSlLrOrNp0pKNRCdFhxVolJLEJQUoSgOpSYT4RowNSsvyW1icA16k8MMMRkCBjskBTFDAZyuAEkqCfxIQ2hgQRFvAQEEIjNxVDW6XNE4YagRjuBCwe60smQUDnd4Rz1ZAQZnFAGDd0hihh12CEE9kjAEVlycXIg7BAsMB6SlnJ87paqbSKiKoqusnbMdmDC2tXQlkUhziYtyWTxIfy6BE8WJt5YEvpJivxNaGmLHT0VnOgGYf0dZXS7APdpB309RnHOG5gDqXGLDaC457D1zZ/V/nmOM82XiHQjYKhKP1oZmADdEAAAh+QQFBQAAACwAAAAAGAAXAAAEchDISasKNeuJFKoHs4mUYlJIkmjIV54Soypsa0wmLSnqoTEtBw52mG0AjhYpBxioEqRNy8V0qFzNw+GGwlJki4lBqx1IBgjMkRIghwjrzcDti2/Gh7D9qN774wQGAYOEfwCChIV/gYmDho+QkZKTR3p7EQAh+QQFBQAAACwBAAAAHQAOAAAEchDISWdANesNHHJZwE2DUSEo5SjKKB2HOKGYFLD1CB/DnEoIlkti2PlyuKGEATMBaAACSyGbEDYD4zN1YIEmh0SCQQgYehNmTNNaKsQJXmBuuEYPi9ECAU/UFnNzeUp9VBQEBoFOLmFxWHNoQw6RWEocEQAh+QQFBQAAACwHAAAAGQARAAAEaRDICdZZNOvNDsvfBhBDdpwZgohBgE3nQaki0AYEjEqOGmqDlkEnAzBUjhrA0CoBYhLVSkm4SaAAWkahCFAWTU0A4RxzFWJnzXFWJJWb9pTihRu5dvghl+/7NQmBggo/fYKHCX8AiAmEEQAh+QQFBQAAACwOAAAAEgAYAAAEZXCwAaq9ODAMDOUAI17McYDhWA3mCYpb1RooXBktmsbt944BU6zCQCBQiwPB4jAihiCK86irTB20qvWp7Xq/FYV4TNWNz4oqWoEIgL0HX/eQSLi69boCikTkE2VVDAp5d1p0CW4RACH5BAUFAAAALA4AAAASAB4AAASAkBgCqr3YBIMXvkEIMsxXhcFFpiZqBaTXisBClibgAnd+ijYGq2I4HAamwXBgNHJ8BEbzgPNNjz7LwpnFDLvgLGJMdnw/5DRCrHaE3xbKm6FQwOt1xDnpwCvcJgcJMgEIeCYOCQlrF4YmBIoJVV2CCXZvCooHbwGRcAiKcmFUJhEAIfkEBQUAAAAsDwABABEAHwAABHsQyAkGoRivELInnOFlBjeM1BCiFBdcbMUtKQdTN0CUJru5NJQrYMh5VIFTTKJcOj2HqJQRhEqvqGuU+uw6AwgEwxkOO55lxIihoDjKY8pBoThPxmpAYi+hKzoeewkTdHkZghMIdCOIhIuHfBMOjxiNLR4KCW1ODAlxSxEAIfkEBQUAAAAsCAAOABgAEgAABGwQyEkrCDgbYvvMoOF5ILaNaIoGKroch9hacD3MFMHUBzMHiBtgwJMBFolDB4GoGGBCACKRcAAUWAmzOWJQExysQsJgWj0KqvKalTiYPhp1LBFTtp10Is6mT5gdVFx1bRN8FTsVCAqDOB9+KhEAIfkEBQUAAAAsAgASAB0ADgAABHgQyEmrBePS4bQdQZBdR5IcHmWEgUFQgWKaKbWwwSIhc4LonsXhBSCsQoOSScGQDJiWwOHQnAxWBIYJNXEoFCiEWDI9jCzESey7GwMM5doEwW4jJoypQQ743u1WcTV0CgFzbhJ5XClfHYd/EwZnHoYVDgiOfHKQNREAIfkEBQUAAAAsAAAPABkAEQAABGeQqUQruDjrW3vaYCZ5X2ie6EkcKaooTAsi7ytnTq046BBsNcTvItz4AotMwKZBIC6H6CVAJaCcT0CUBTgaTg5nTCu9GKiDEMPJg5YBBOpwlnVzLwtqyKnZagZWahoMB2M3GgsHSRsRACH5BAUFAAAALAEACAARABgAAARcMKR0gL34npkUyyCAcAmyhBijkGi2UW02VHFt33iu7yiDIDaD4/erEYGDlu/nuBAOJ9Dvc2EcDgFAYIuaXS3bbOh6MIC5IAP5Eh5fk2exC4tpgwZyiyFgvhEMBBEAIfkEBQUAAAAsAAACAA4AHQAABHMQyAnYoViSlFDGXBJ808Ep5KRwV8qEg+pRCOeoioKMwJK0Ekcu54h9AoghKgXIMZgAApQZcCCu2Ax2O6NUud2pmJcyHA4L0uDM/ljYDCnGfGakJQE5YH0wUBYBAUYfBIFkHwaBgxkDgX5lgXpHAXcpBIsRADs=");
			}

			.layui-layer-shade {
			  position: fixed;
			  top: 0;
			  left: 0;
			  width: 100%;
			  height: 100%;
			}

			.layui-layer {
			  position: fixed;
			  border-radius: 2px;
			  background-color: var(--layui-layer-bg);
			  box-shadow: var(--layui-layer-shadow);
			}

			.layui-layer-content {
			  position: relative;
			  height: 100%;
			  overflow: auto;
			}

			.layui-layer-setwin {
			  position: absolute;
			  top: 15px;
			  right: 15px;
			  font-size: 0;
			  line-height: initial;
			}

			.layui-layer-setwin .layui-layer-close {
			  position: absolute;
			  top: -28px;
			  right: -28px;
			  display: inline-block;
			  vertical-align: top;
			  width: 30px;
			  height: 30px;
			  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAKwwAACsMBNCkkqwAAABZ0RVh0Q3JlYXRpb24gVGltZQAwMy8xNC8xNxpI5/gAAAAcdEVYdFNvZnR3YXJlAEFkb2JlIEZpcmV3b3JrcyBDUzbovLKMAAAEN0lEQVRIiaWXTUhjVxTH/+diAmNMDGpCSCBNtWFEIQ0MFAYGZlNt6aKbUhpxYeAZxY0MlGy7K67LLIraYA26sd2UblrUEYp0oIKIgviBaaqNlYRIJgkulDm3i+Q9XvJenjoeCLxz7j3nd9595957QlJKqEJEsBJmfg7gGYAgAB+AtwAKRPQ3gE0i2rQMoBcppfZrMR5l5llmzstbhJn/ZeaXzDxw5wRMgEFmnrkNZpHEN8zsaRXfdG2llB9LKX8iIrfeXigUsLe3h1KphGq1CiKCw+FAV1cXIpEIurq6muP8ByAmhPjjVjAzjxHRj3rb7u4u1tbWkM/nLVfJ7/djeHgY/f39zQl8LoT4tSWYmT8hot9UvVKpYHl5Gdls1hLYLOFwGCMjI2hvb9fDn+vfXAMz8/sA9ojIAQC5XA6Li4sol8v3gqrS3d0NRVG05ZdS/kNEHxLRGwAQurlTKrRcLj8ICgDFYhGpVApXV1cAACJ6D8CUOi7q2TwhoqRqXFpaehBUD19ZWdGbZpj5Az1Yy2RnZwenp6eGIH6/3xJit9vhdrsN9oODAxwdHelNUxqYiBTVur6+bnCORqOYnp5GIpGAzWYzjPt8PiSTSSSTSdjtdsP46uqq9qyyBDMPqcZsNotCoWBwPDk5QblcRl9fH+LxeAPc6/UikUjA6XQik8ng+vra4H92doaLiwtV7WTmjwRqZy8A4Pj42OAE1LbV7OysAe71ejE5OQmHw4FMJoN0Om3qbxL7mQDwWNXM3laVYrHYAFcUpQG6sLCAm5ublv5NsR8LIvKpWrVabemowufn51EulxEKhe4MNYntE60mthIiarg+hbh3iJqflFL76h0dHZaTPR6PVkjZbBaVSgWhUAiKophWu16aYl8IAIf6wFbQiYkJrXpTqRTm5uYa4GZbqUXsQwFA6xrC4bCpk9vtboCq37RQKDTAx8bGWi59U+xNQUSvVC0YDBruVAAIBAJwOp04OTkxFJIKVwuura3N1N/n02r4jRDiLwIAZv6TiJ4CwPb2dvP5CqB2UFjdxzabDY8ePTI94+PxuHZHSym/E0K8UNfla3VSNBpFIBAwON/WBNzc3JhCe3t7mxuD74H6WS2EeC2lfF1/RiwWa7jE31VcLhdisZimSym/FUIcauC6TEkpr4FaBSqKAqfT+c5Qt9uN8fFxuFwuFVpE/W0BY+vzBRH9rOqlUgnpdBrn5+f3goZCIYyOjjYkLqX8VAjxuym4Djc0e1tbW9jY2MDl5aUl0OPxYGhoCJFIpMEupfxKCNFQsabtLTN/BuAXImrYG7lcDvv7+6hUKsjn8xBCoKenB52dnRgcHNRvGRVYIqIviWjNMuMm+AAzv3xAQz8jpQzeGWiSwFNmTjPz1R14JWb+QUr55La41v/SjEkModY4+AAMENFbKeUhgByATSHEK8sAOvkfU5us3WE/neAAAAAASUVORK5CYII=");
			  background-repeat: no-repeat;
			  cursor: pointer;
			  transition: all 0.4s ease-in-out;
			}

			.layui-layer-setwin .layui-layer-close:hover {
			  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAKwwAACsMBNCkkqwAAABZ0RVh0Q3JlYXRpb24gVGltZQAwMy8xNC8xNxpI5/gAAAAcdEVYdFNvZnR3YXJlAEFkb2JlIEZpcmV3b3JrcyBDUzbovLKMAAAEXUlEQVRIiaWXf2iVZRTHv8957t3d3ruSja0mA82NLTMl7gZzjJH0A0RLCKIiskDTzFhmhFrLqKDAMtHMGvvRVn8lSFFS2i/s19rWmC2DVlKbiRtzc2Ngce1u95ynP+7e1/e97/2x6fnvnOf5ns95fr3P8yrMw0RkFYB6AIsAlABgABeUUmcAdCqlOueTL6MZYx5g4QEWZpPFWDjOwqdYeN3VAGtZuDsbLEMRJ1h4abr8Kg10pxjZQ4o87dOjo+CeXtDkFGR4GABAlRUwxUUI1K1EIJzvySNGBMB2TfqtrGAWbiVFmzzArh7EWzsQ/6k37Qwpy0LgztsR2LwBwfKy5AJe0aRfSAtm4UZS9KrjT0witvtlxL//IS3QZ8EchDY+guATj4GCQTd8m3vkDpiFbwXwrT29M4NDiDVsh5w9N3eoywL1dQgd2AttWTY4TorKlFLnAIBcfffaUJ6YQOzxbVcMBYB4ZxemdzTCxOMAAFIUANBqtxMAGGPWk6IaOxjb8TxkZOSKobbNfPMdplva3aHVLHyHAxYjzsLPfPFVyk1ES2/MCFGWBVpY4otPt7ZDxsbdodccMCmqtKOxg2/7xMG71iD/o8Ow2puhQiF/UZUVCB//BPmfH4WaXVPbTCyGWFPL5b6KqgCAWHiXHeT+XyFnzvoS88/9kAsTCNTWIK/poAdO5WUItzeDiosQ7+2DiUZ9+vixL2H+i9muYuENBGCt06G7xycCABk9j+jGLT44lZch/H4bVGEBuLcPlxqeTqk3//4D+W3AHbqHANzgAP4aSikEABkc8sCttiYPNLqlASYWS6vn30+73QoiRdc6yScn0gqT4bo6MmcoAJipKbdbQJ5WlozilKb1/DUASIxcdJyiosydlyyGNbuR+GS/M3KrrSnlbnebKihwu1ME4G8ncfmSzND32hLQ3j5EN231TLvV1uQ7Ssl6l/1JAI7ZXqCuNrVoYYkXOrumyWued2g/QOTTq1AIurrKHfqYSNF+29ORW0ClpT6hXnZT4pz29Po2kgMfG0egOgKVm+vTB+5eA5XrLIXRpDsSl4LwRVJ0DQDMfHocl3Y2+kddXgYZTH/cVCgEtWABZHzc2xDMQfjoEejFixKFGvlFk47Y8/KM02/taugVy32JM0GBxKfRBwWQ8/CDDnTWngO897EzahkbR/S+hyATmc91NgusrIHVcgiYfRCIkR816XrAex8/KiZxjun665D3zptZj1cm01UR5O3b44YaAE/Z7Q5Ykz4C4A3HX74M1ocfQFdF5g0N3n8vwh3NUIWes7tbkz5pO3N67M18fQLTze+CvR96P/C2Vch5cit00t0tRg5o0p4bJOXzloVfBPASqaQv6vAIuKsbPPDH5QR5eaAVN0PX1kAXFiYDDSl6Vin1esaKk+DrWPjUVTzou40xqb9IcyxgMwsPsmT9gzHGGGHh08aY9dnyppzqDEXsQuLhUAyglBSJGBkFcB7AZ5r0vrnm+h+4JqLbk005nAAAAABJRU5ErkJggg==");
			  transform: rotate(180deg);
			}

			.login-images img {
			  height: 85px;
			}

			.login-images {
			  width: 440px;
			  display: flex;
			  margin-bottom: 25px;
			  justify-content: center;
			}

			.login_lang {
			  display: flex;
			  align-items: center;
			  justify-content: center;
			  position: absolute;
			  left: 40px;
			  bottom: 20px;
			}

			.login_lang .lang_label {
			  margin-right: 8px;
			}

			.login_qrcode{
			  padding: 5px;
			  background-color: #fff;
			}

			input:focus,
			select:focus {
			  border-color: var(--login-input-focus-border-color);
			  background-color: var(--login-input-focus-bg);
			  outline: none;
			}

			/* 主题变量 */
			:root {
			  --page-bg: #444444;
			  --login-bg: #fff;
			  --layui-layer-bg: var(--login-bg);
			  --layui-layer-shadow: 1px 1px 50px rgb(0 0 0 / 30%);
			  --login-text-color: #444;
			  --login-body-color: #333;
			  --login-box-radius: 4px;
			  --login-box-shadow: none;
			  --login-input-border: 1px solid #d1d1d1;
			  --login-input-radius: 3px;
			  --login-input-color: #000000;
			  --login-input-focus-border-color: #000000;
			  --login-input-focus-bg: var(--login-bg);
			  --login-btn-radius: 3px;
			  --login-select-radius: none;
			  --login-select-border: 1px solid #ddd;
			  --login-select-bg: var(--login-bg);
			  --login-qr-code-img: url("data:image/png;base64,[encoded data, 20164 characters]");
			  --login-scan-title-color: var(--login-text-color);
			  --login-scan-text-color: #555;
			  --login-tips-bg: #dff0d8;
			}

			/* 暗黑模式 */
			[data-theme="dark"] {
			  --page-bg: #18191c;
			  --login-bg: linear-gradient(#202020, #18191c);
			  --layui-layer-bg: #202020;
			  --layui-layer-shadow: 0 0 3px 1px rgba(255, 255, 255, 0.4);
			  --login-text-color: #c5c5c5;
			  --login-body-color: #b3b3b3;
			  --login-box-radius: 16px;
			  --login-box-shadow: 0 0 3px 1px rgba(255, 255, 255, 0.4);
			  --login-input-border: 1px solid #434343;
			  --login-input-radius: 9px;
			  --login-input-color: var(--login-text-color);
			  --login-input-focus-border-color: var(--login-text-color);
			  --login-input-focus-bg: var(--page-bg);
			  --login-btn-radius: 9px;
			  --login-select-radius: 6px;
			  --login-select-border: var(--login-input-border);
			  --login-select-bg: #202020;
			  --login-qr-code-img: url("data:image/png;base64,[encoded data, 21976 characters]");
			  --login-scan-title-color: var(--login-text-color);
			  --login-scan-text-color: #b3b3b3;
			  --login-tips-bg: none;
			}
		</style>
		<script>
			var ie_version = (function () {
				var userAgent = navigator.userAgent,
					isLessIE11 = userAgent.indexOf('compatible') > -1 && userAgent.indexOf('MSIE') > -1,
					isEdge = userAgent.indexOf('Edge') > -1 && !isLessIE11,
					isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf('rv:11.0') > -1;
				if (isLessIE11) {
					var IEReg = new RegExp('MSIE (\\d+\\.\\d+);');
					IEReg.test(userAgent);
					var IEVersionNum = parseFloat(RegExp['$1']);
					if (IEVersionNum === 7) {
						// IE7
						return 7;
					} else if (IEVersionNum === 8) {
						// IE8
						return 8;
					} else if (IEVersionNum === 9) {
						// IE9
						return 9;
					} else if (IEVersionNum === 10) {
						// IE10
						return 10;
					} else {
						return 6;
					}
				} else if (isEdge) {
					// edge
					return 'edge';
				} else if (isIE11) {
					// IE11
					return 11;
				} else {
					// 不是ie浏览器
					return -1;
				}
			})();
			if (ie_version != -1 && ie_version < 9) {
				window.location.href = '/tips';
			}
		</script>
	</head>

	<body>
		<div class="main">
			<div class="login-bg {% if g['panel_theme']['login']['is_show_bg'] %}active{% endif %}"></div>
			<div class="login{% if session['code'] %} code{% endif %}">
				<div class="account">
					<div class="last_token" style="display: block" data="{{data['last_login_token']}}"></div>
					<div class="public_key" style="display: block" data="{{data['public_key']}}"></div>
					<form class="login_form" onsubmit="return false;">
						<div class="form_title">{{g.title}}</div>
						<div class="form_item">
							<input type="text" class="form_input" id="username" data-i18n="Login.index_1" placeholder="" />
							<div class="validform_checktip"></div>
						</div>
						<div class="form_item">
							<input type="password" class="form_input" id="password" data-i18n="Login.index_2" placeholder="" />
							<div class="validform_checktip"></div>
						</div>
						<div class="error_tips"></div>
						<div class="form_item check_code{% if not session['code'] %} hide{% endif %}">
							<input type="text" class="form_input" id="code" data-i18n="Login.index_8" placeholder="" />
							<div class="validform_checktip"></div>
							<img class="check_img" data-i18n="Login.index_9" title="" src="/code" onClick="this.src = this.src.split('?')[0] + '?' + new Date().getTime()" />
						</div>
						<!-- 登录按钮 -->
						<button class="login_btn" data-i18n="Login.index_3"></button>
						<!-- 语言切换 -->
						<div class="login_lang">
							<div class="lang_label" data-i18n="Login.index_5"></div>
							<select id="lang_select"></select>
						</div>
						<!-- 忘记密码 -->
						<a class="forget_pwd" href="https://www.yakpanel.com/forum/d/16-how-to-reset-password-for-yakpanel-linux-6-x" target="_blank" data-i18n="Login.index_4"></a>
						{% if data['hosts'] != '[]' %}
						<div class="static_cdn">
							<div class="cont">
								<div class="name" data-i18n="Login.index_20"></div>
								<select id="static_cdn">
									<option value="localhost" data-i18n="Login.index_21"></option>
								</select>
							</div>
						</div>
						{% endif %}
					</form>
				</div>
				<div class="scan_code hide">
					<div class="scan_title" data-i18n="Login.index_12"></div>
					<div class="login_qrcode">
						<div class="qrcode" id="qrcode"></div>
					</div>
					<div class="scan_tip">
						<div class="link">
							<span data-i18n="Login.index_13"></span>
							<a href="https://www.yakpanel.com/forum/d/3527-yakpanel-mobile" target="_blank" class="bt_link" data-i18n="Login.index_14"></a>
						</div>
						<div class="desc">
							<div class="icon scan"></div>
							<div class="text" data-i18n="Login.index_15"></div>
						</div>
					</div>
				</div>
				<div class="entrance">
					<div class="bg_img"></div>
					<div class="tips">
						<div class="icon scan"></div>
						<div class="text" data-i18n="Login.index_10"></div>
					</div>
				</div>
			</div>
		</div>
		<script type="text/javascript" src="/static/js/md5.js"></script>
		<script type="text/javascript" src="/static/js/qrcode.min.js"></script>
		<script type="text/javascript" src="/static/js/jsencrypt.min.js"></script>
		<script src="/static/js/i18next.min.js"></script>
		<script>
			var lang = '{{data.login_lang}}';
			var langData = JSON.parse(atob('{{data.login_translations}}'));

			console.log(langData);

			for (var key in langData) {
				langData[key] = {
					translation: langData[key],
				};
			}

			i18next.init(
				{
					lng: lang,
					resources: langData,
				},
				function () {
					updateContent();
				}
			);

			// 切换语言
			function changeLanguage(lang) {
				i18next.changeLanguage(lang, function (err, t) {
					updateContent();
				});
			}

			// 更新带有 data-i18n 属性的元素内容
			function updateContent() {
				document.querySelectorAll('[data-i18n]').forEach(function (element) {
					const key = element.getAttribute('data-i18n');
					switch (element.tagName.toLocaleLowerCase()) {
						case 'input':
							element.setAttribute('placeholder', i18next.t(key));
							break;
						case 'img':
							element.setAttribute('title', i18next.t(key));
							break;
						default:
							element.innerHTML = i18next.t(key);
							break;
					}
				});
			}

			// 左右清空空格
			if (typeof String.prototype.trim === 'undefined') {
				String.prototype.trim = function () {
					return String(this).replace(/^\s+|\s+$/g, '');
				};
			}

			window.onload = function () {
				run();
			};

			function rsa_encrypt(text) {
				var publicKey = document.querySelector('.public_key').attributes.data.value;
				if (publicKey.length < 10) return text;
				var encrypt = new JSEncrypt();
				encrypt.setPublicKey(publicKey);
				return encrypt.encrypt(text);
			}

			/**
			 * 加载完js后运行
			 */
			function run() {
				// 请求
				var request = new Request();
				// 时间
				var timer = null;
				// 二维码
				var qrcode = null;
				// 弹框
				var popup = new Popup();
				// 登录框
				var loginBox = document.querySelector('.login');
				// 登录按钮
				var loginBtn = document.querySelector('.login_btn');
				// 用户名input框
				var usernameInput = document.querySelector('#username');
				// 密码input框
				var passwordInput = document.querySelector('#password');
				// 验证码input框
				var codeInput = document.querySelector('#code');
				// 静态cdn选择框框
				var staticCdnSelect = document.querySelector('#static_cdn');
				// 错误提示框
				var errorTipsBox = document.querySelector('.error_tips');
				// 验证码
				var checkCodeBox = document.querySelector('.check_code');
				// 验证码图片
				var checkImg = document.querySelector('.check_img');
				// 切换二维码
				var entrance = document.querySelector('.entrance').querySelector('.bg_img');

				/**
				 * 显示验证码
				 */
				function show_check_img() {
					checkCodeBox.classList.remove('hide');
					checkImg.click();
				}
				/**
				 * 判断是否为空
				 */
				function is_empty(val) {
					return val === '' || val === undefined || val === null;
				}
				/**
				 * 单独验证
				 */
				function dom_validation(dom, tips, key) {
					var val = dom.value;
					var checktip = dom.parentNode.querySelector('.validform_checktip');
					if (!checktip) return;
					if (is_empty(val)) {
						dom.classList.add('validform_error');
						checktip.classList.add('validform_wrong');
						checktip.classList.remove('validform_right');
						checktip.innerText = tips;
						checktip.setAttribute('data-i18n', key);
					} else {
						dom.classList.remove('validform_error');
						checktip.classList.remove('validform_wrong');
						checktip.classList.add('validform_right');
						checktip.innerText = '';
						checktip.removeAttribute('data-i18n');
					}
				}
				/**
				 * 表单验证
				 */
				function form_validation(callback) {
					var username = usernameInput.value.trim();
					var password = passwordInput.value.trim();
					if (is_empty(username) || is_empty(password)) {
						popup.msg(i18next.t('Login.index_7'));
					}
					if (is_empty(username)) {
						dom_validation(usernameInput, i18next.t('Login.index_6'), 'Login.index_6');
						usernameInput.focus();
						return;
					}
					if (is_empty(password)) {
						dom_validation(passwordInput, i18next.t('Login.index_2'), 'Login.index_2');
						passwordInput.focus();
						return;
					}
					var code = codeInput.value.trim();
					var isHide = checkCodeBox.classList.contains('hide');
					if (!isHide && is_empty(code)) {
						popup.msg(i18next.t('Login.index_23'));
						dom_validation(codeInput, i18next.t('Login.index_8'), 'Login.index_8');
						codeInput.focus();
						return;
					}
					var last_token = document.querySelector('.last_token').attributes.data.value;
					var data = {
						username: rsa_encrypt(md5(md5(username + last_token))),
						password: rsa_encrypt(md5(md5(password) + '' + '_capnis.com')),
						code: code,
					};
					if (staticCdnSelect) {
						var index = staticCdnSelect.selectedIndex;
						data['cdn_url'] = staticCdnSelect.options[index].value;
					}
					if (callback) callback(data);
				}
				/**
				 * 设置每秒请求
				 */
				function set_control_time() {
					timer = setInterval(function () {
						request.post('/public?name=app&fun=is_scan_ok', {}, function (res) {
							if (res.status) {
								popup.msg(i18next.t('Login.index_24'), { time: 0, icon: 1 });
								clear_control_time();
								login_admin(res.msg);
							}
						});
					}, 2000);
				}
				/**
				 * 清除设置请求
				 */
				function clear_control_time() {
					if (timer) clearInterval(timer);
				}
				/**
				 * 登录
				 */
				function login_admin(key) {
					request.post(
						'/public?name=app&fun=set_login',
						{
							secret_key: key,
						},
						function (res) {
							if (res.status) {
								popup.msg(
									i18next.t('Login.index_25'),
									{
										icon: 16,
										time: 800,
										shade: [0.4, '#fff'],
									},
									function () {
										window.location.href = '/';
									}
								);
							} else {
								popup.msg(res.msg, { icon: 2 });
							}
						}
					);
				}
				/**
				 * 生成验证码
				 */
				function generate_qrcode() {
					if (qrcode) qrcode.clear();
					request.post('/public?name=app&fun=login_qrcode', {}, function (res) {
						var text = res.status ? res.msg : 'https://www.yakpanel.com/app.html';
						if (qrcode) {
							qrcode.makeCode(text);
						} else {
							qrcode = new QRCode('qrcode', {
								width: 150,
								height: 150,
								colorLight: '#fefefe',
								colorDark: '#333',
								text: text,
							});
						}
					});
				}
				// 用户名校验
				usernameInput.onblur = function () {
					dom_validation(this, i18next.t('Login.index_6'), 'Login.index_6');
				};
				// 密码校验
				passwordInput.onblur = function () {
					dom_validation(this, i18next.t('Login.index_2'), 'Login.index_2');
				};
				// 验证码校验
				codeInput.onblur = function () {
					dom_validation(this, i18next.t('Login.index_8'), 'Login.index_8');
				};
				// 登录
				loginBtn.onclick = function () {
					form_validation(function (data) {
						popup.msg(i18next.t('Login.index_22'), {
							time: 0,
							icon: 16,
							shade: [0.3, '#333'],
						});
						request.post('/login', data, function (res) {
							popup.remove_msg();
							if (res == '1') {
								popup.open({
									content:
										'\
										<div class="verification_view">\
												<div class="v_title">' +
										i18next.t('Login.index_16') +
										'</div>\
														<div class="v_input">\
																<input type="text" class="v_code" placeholder="' +
										i18next.t('Login.index_8') +
										'" />\
														</div>\
														<div class="v_btn">\
																<button id="auth_verif_btn">' +
										i18next.t('Login.index_3') +
										'</button>\
														</div>\
														<div class="v_tips">' +
										i18next.t('Login.index_17') +
										'<br><a class="bt_link" href="https://www.yakpanel.com/forum/d/357-how-to-use-google-authenticator-in-the-yakpanel" target="_blank">' +
										i18next.t('Login.index_18') +
										'</a>\
												</div>\
										</div>\
									',
									callback: function () {
										var btn = document.querySelector('#auth_verif_btn');
										var codeInput = document.querySelector('.v_code');
										codeInput.onkeydown = function (e) {
											if (e.keyCode == 13) btn.click();
										};
										btn.onclick = function () {
											var code = codeInput.value.trim();
											if (is_empty(code)) {
												popup.msg(i18next.t('Login.index_19'));
												return;
											}
											data['vcode'] = code;
											popup.msg(i18next.t('Login.index_22'), {
												icon: 16,
												shade: [0.3, '#333'],
											});
											request.post('/login', data, function (rdata) {
												popup.remove_msg();
												if (!rdata.status) {
													popup.msg(rdata.msg, { icon: 2 });
													return false;
												}
												popup.msg(
													rdata.msg,
													{
														icon: 16,
														time: 800,
														shade: [0.3, '#000'],
													},
													function () {
														window.location.href = '/';
													}
												);
											});
										};
									},
								});
								return;
							}
							var status = res.status;
							if (!status) {
								popup.msg(res.msg);
								codeInput.value = '';
								passwordInput.value = '';
								errorTipsBox.innerHTML = res.msg;
								loginBox.classList.add('code');
								show_check_img();
								return;
							}
							popup.msg(res.msg, { time: 0, icon: 16, shade: [0.3, '#333'] });
							setTimeout(function () {
								window.location.href = '/';
							}, 1000);
						});
					});
				};

				// 切换登录方式
				entrance.onclick = function () {
					var tips = this.nextSibling.nextSibling;
					var icon = tips.querySelector('.icon');
					var text = tips.querySelector('.text');
					var scanCode = document.querySelector('.scan_code');
					var account = document.querySelector('.account');
					if (this.classList.contains('pc')) {
						this.classList.remove('pc');
						icon.classList.add('scan');
						icon.classList.remove('safe');
						text.innerText = i18next.t('Login.index_10');
						account.classList.remove('hide');
						scanCode.classList.add('hide');
						clear_control_time();
					} else {
						this.classList.add('pc');
						icon.classList.add('safe');
						icon.classList.remove('scan');
						text.innerText = i18next.t('Login.index_11');
						account.classList.add('hide');
						scanCode.classList.remove('hide');
						generate_qrcode();
						set_control_time();
					}
				};

				window.onresize = function () {
					popup.set_msg_center();
					popup.set_open_center();
				};

				if ("{{data['app_login']}}" == 'True') {
					entrance.click();
				}

				// 获取语言列表
				function getLangList() {
					request.post('/userLang?action=get_language', {}, function (res) {
						var langSelect = document.querySelector('#lang_select');
						var langList = res.message.languages;
						var lang = res.message.default;

						for (var i = 0; i < langList.length; i++) {
							var option = document.createElement('option');
							option.value = langList[i].name;
							option.innerText = langList[i].title;
							if (lang == langList[i].name) {
								option.selected = true;
							}
							langSelect.appendChild(option);
						}
					});
				}

				getLangList();

				var langSelect = document.querySelector('#lang_select');

				langSelect.onchange = function () {
					var lang = this.value;
					popup.msg(i18next.t('Login.index_22'), {
						icon: 16,
						shade: [0.3, '#333'],
					});
					request.post('/userLang?action=set_language', { name: lang }, function (res) {
						popup.remove_msg();
						if (res.status === 0) {
							// popup.msg(res.message.result, { icon: 1 });
							changeLanguage(lang);
						}
					});
				};
			}
			/**
			 * 请求
			 */
			function Request() {
				this.xhr = new XMLHttpRequest();
			}
			Request.prototype = {
				post: function (url, data, callback) {
					var option = {
						method: 'POST',
						url: url,
						callback: callback,
					};
					var form = new FormData();
					for (var key in data) {
						if (data[key] !== '' && data[key] !== undefined && data[key] !== null) {
							form.append(key, data[key]);
						}
					}
					option.data = form;
					this.http(option);
				},
				http: function (option) {
					var xhr = this.xhr;
					var toUrl = window.location.protocol + '//' + window.location.host + option.url;
					var method = option.method || 'GET';
					// 打开连接
					xhr.open(method, toUrl, true);
					// 发送请求
					if (method == 'GET') {
						xhr.send();
					} else if (method == 'POST') {
						xhr.send(option.data);
					}
					// 请求后的回调接口
					xhr.onreadystatechange = function () {
						if (xhr.readyState == 4 && xhr.status == 200) {
							var res = xhr.responseText;
							res = res ? JSON.parse(res) : '';
							if (option.callback) option.callback(res);
						}
					};
				},
			};
			/**
			 * 弹框
			 */
			function Popup() {
				this.zIndex = 200000;
			}
			Popup.prototype = {
				/**
				 * 弹框
				 */
				open: function (option) {
					var _this = this;
					option = option || {};
					this.set_open_option(option);
					this.add_overlay(option);
					var container = document.createElement('div');
					container.classList.add('layui-layer');
					var content = document.createElement('div');
					content.classList.add('layui-layer-content');
					var setwin = document.createElement('div');
					setwin.classList.add('layui-layer-setwin');
					var close = document.createElement('a');
					close.classList.add('layui-layer-close');
					if (option.area[0]) container.style.width = option.area[0];
					if (option.area[1]) container.style.height = option.area[1];
					content.innerHTML = option.content;
					close.onclick = function () {
						_this.remove_open();
					};
					container.style['z-index'] = this.zIndex;
					this.zIndex++;
					setwin.appendChild(close);
					container.appendChild(content);
					container.appendChild(setwin);
					document.documentElement.appendChild(container);
					this.set_open_center('layui-layer');
					if (option.callback) option.callback();
				},
				/**
				 * 提示框
				 */
				msg: function (msg, option, callback) {
					var _this = this;
					option = option || {};
					this.remove_msg();
					this.add_overlay(option);
					this.set_msg_option(option);
					var container = document.createElement('div');
					container.className = 'layui-layer-msg';
					container.style['z-index'] = 200000;
					var box = document.createElement('div');
					box.className = 'layui-layer-content';
					var icon = document.createElement('i');
					icon.className = 'layui-layer-ico layui-layer-ico' + option.icon;
					box.appendChild(icon);
					box.innerHTML += msg;
					container.style['z-index'] = this.zIndex;
					this.zIndex++;
					container.appendChild(box);
					document.documentElement.appendChild(container);
					this.set_msg_center();
					if (option.time !== 0) {
						setTimeout(function () {
							_this.remove_msg();
							if (callback) callback();
						}, option.time);
					}
				},
				/**
				 * 添加遮罩层
				 */
				add_overlay: function (option) {
					if (option.hasOwnProperty('shade')) {
						var shade = option.shade;
						var overlay = document.createElement('div');
						overlay.className = 'layui-layer-shade';
						overlay.style.opacity = shade[0];
						overlay.style['background-color'] = shade[1];
						overlay.style['z-index'] = this.zIndex;
						this.zIndex++;
						document.documentElement.appendChild(overlay);
					}
				},
				/**
				 * 弹框配置项
				 */
				set_open_option: function (option) {
					var defaultOption = {
						area: ['390px', '280px'],
						shade: [0.3, '#000'],
						content: '',
					};
					this.set_option(option, defaultOption);
				},
				/**
				 * msg配置项
				 */
				set_msg_option: function (option) {
					var defaultOption = {
						icon: 2,
						time: 2000,
					};
					this.set_option(option, defaultOption);
				},
				/**
				 * 设置默认配置项
				 */
				set_option: function (option, defaultOption) {
					for (var key in defaultOption) {
						if (option[key] === undefined) {
							option[key] = defaultOption[key];
						}
					}
				},
				/**
				 * 提示框设置居中
				 */
				set_msg_center: function () {
					this.set_center('layui-layer-msg');
				},
				/**
				 * 弹框设置居中
				 */
				set_open_center: function () {
					this.set_center('layui-layer');
				},
				/**
				 * 设置居中
				 */
				set_open_center: function () {
					this.set_center('layui-layer');
				},
				/**
				 * 居中
				 */
				set_center: function (_class) {
					var dom = document.querySelector('.' + _class);
					if (!dom) return;
					var bodyWidth = document.documentElement.clientWidth;
					var bodyHeight = document.documentElement.clientHeight;
					var domWidth = dom.clientWidth;
					var domHeight = dom.clientHeight;
					dom.style.left = (bodyWidth - domWidth) / 2 + 'px';
					dom.style.top = (bodyHeight - domHeight) / 2 + 'px';
				},
				/**
				 * 删除提示框
				 */
				remove_msg: function () {
					this.remove('layui-layer-msg');
				},
				/**
				 * 删除弹框
				 */
				remove_open: function () {
					this.remove('layui-layer');
				},
				/**
				 * 删除
				 */
				remove: function (_class) {
					var dom = document.querySelector('.' + _class);
					if (!dom) return;
					var overlay = dom.previousElementSibling;
					if (overlay.classList.contains('layui-layer-shade')) {
						document.documentElement.removeChild(overlay);
						this.zIndex--;
					}
					document.documentElement.removeChild(dom);
					this.zIndex--;
				},
			};

			// 获取当前主题模式
			const themMode = JSON.parse(localStorage.getItem('ThemeStore'));
			const isDark = themMode && themMode.theme === 'dark';
			document.documentElement.setAttribute('data-theme', isDark ? 'dark' : '');
		</script>
	</body>
</html>
