init jwt
@ -1,7 +1,6 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
@ -11,7 +10,6 @@ import (
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/hashicorp/go-uuid"
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"golang.org/x/sync/singleflight"
|
||||
|
||||
@ -68,7 +66,7 @@ func (p *commonPage) issueViewPassword(c *gin.Context) {
|
||||
err := c.ShouldBind(&vpf)
|
||||
var hash []byte
|
||||
if err == nil && vpf.Password != singleton.Conf.Site.ViewPassword {
|
||||
err = errors.New(singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "WrongAccessPassword"}))
|
||||
// err = errors.New(singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "WrongAccessPassword"}))
|
||||
}
|
||||
if err == nil {
|
||||
hash, err = bcrypt.GenerateFromPassword([]byte(vpf.Password), bcrypt.DefaultCost)
|
||||
@ -76,9 +74,9 @@ func (p *commonPage) issueViewPassword(c *gin.Context) {
|
||||
if err != nil {
|
||||
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
||||
Code: http.StatusOK,
|
||||
Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
MessageID: "AnErrorEccurred",
|
||||
}),
|
||||
// Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
// MessageID: "AnErrorEccurred",
|
||||
// }),
|
||||
Msg: err.Error(),
|
||||
}, true)
|
||||
c.Abort()
|
||||
@ -107,7 +105,7 @@ func (p *commonPage) service(c *gin.Context) {
|
||||
}, nil
|
||||
})
|
||||
c.HTML(http.StatusOK, mygin.GetPreferredTheme(c, "/service"), mygin.CommonEnvironment(c, gin.H{
|
||||
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ServicesStatus"}),
|
||||
// "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ServicesStatus"}),
|
||||
"Services": res.([]interface{})[0],
|
||||
"CycleTransferStats": res.([]interface{})[1],
|
||||
}))
|
||||
@ -255,9 +253,9 @@ func (cp *commonPage) home(c *gin.Context) {
|
||||
if err != nil {
|
||||
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
||||
Code: http.StatusInternalServerError,
|
||||
Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
MessageID: "SystemError",
|
||||
}),
|
||||
// Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
// MessageID: "SystemError",
|
||||
// }),
|
||||
Msg: "服务器状态获取失败",
|
||||
Link: "/",
|
||||
Btn: "返回首页",
|
||||
@ -284,9 +282,9 @@ func (cp *commonPage) ws(c *gin.Context) {
|
||||
if err != nil {
|
||||
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
||||
Code: http.StatusInternalServerError,
|
||||
Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
MessageID: "NetworkError",
|
||||
}),
|
||||
// Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
// MessageID: "NetworkError",
|
||||
// }),
|
||||
Msg: "Websocket协议切换失败",
|
||||
Link: "/",
|
||||
Btn: "返回首页",
|
||||
@ -332,9 +330,9 @@ func (cp *commonPage) terminal(c *gin.Context) {
|
||||
if err != nil {
|
||||
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
||||
Code: http.StatusInternalServerError,
|
||||
Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
MessageID: "NetworkError",
|
||||
}),
|
||||
// Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
// MessageID: "NetworkError",
|
||||
// }),
|
||||
Msg: "Websocket协议切换失败",
|
||||
Link: "/",
|
||||
Btn: "返回首页",
|
||||
@ -394,9 +392,9 @@ func (cp *commonPage) createTerminal(c *gin.Context) {
|
||||
if err != nil {
|
||||
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
||||
Code: http.StatusInternalServerError,
|
||||
Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
MessageID: "SystemError",
|
||||
}),
|
||||
// Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
// MessageID: "SystemError",
|
||||
// }),
|
||||
Msg: "生成会话ID失败",
|
||||
Link: "/server",
|
||||
Btn: "返回重试",
|
||||
@ -462,9 +460,9 @@ func (cp *commonPage) fm(c *gin.Context) {
|
||||
if err != nil {
|
||||
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
||||
Code: http.StatusInternalServerError,
|
||||
Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
MessageID: "NetworkError",
|
||||
}),
|
||||
// Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
// MessageID: "NetworkError",
|
||||
// }),
|
||||
Msg: "Websocket协议切换失败",
|
||||
Link: "/",
|
||||
Btn: "返回首页",
|
||||
@ -508,9 +506,9 @@ func (cp *commonPage) createFM(c *gin.Context) {
|
||||
if err != nil {
|
||||
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
||||
Code: http.StatusInternalServerError,
|
||||
Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
MessageID: "SystemError",
|
||||
}),
|
||||
// Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
// MessageID: "SystemError",
|
||||
// }),
|
||||
Msg: "生成会话ID失败",
|
||||
Link: "/server",
|
||||
Btn: "返回重试",
|
||||
|
@ -2,20 +2,14 @@ package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.cloudfoundry.org/bytefmt"
|
||||
jwt "github.com/appleboy/gin-jwt/v2"
|
||||
"github.com/gin-contrib/pprof"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/hashicorp/go-uuid"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
swaggerfiles "github.com/swaggo/files"
|
||||
ginSwagger "github.com/swaggo/gin-swagger"
|
||||
|
||||
@ -24,11 +18,29 @@ import (
|
||||
"github.com/naiba/nezha/pkg/mygin"
|
||||
"github.com/naiba/nezha/pkg/utils"
|
||||
"github.com/naiba/nezha/proto"
|
||||
"github.com/naiba/nezha/resource"
|
||||
"github.com/naiba/nezha/service/rpc"
|
||||
"github.com/naiba/nezha/service/singleton"
|
||||
)
|
||||
|
||||
// @title Swagger Example API
|
||||
// @version 1.0
|
||||
// @description This is a sample server celler server.
|
||||
// @termsOfService http://swagger.io/terms/
|
||||
|
||||
// @contact.name API Support
|
||||
// @contact.url http://www.swagger.io/support
|
||||
// @contact.email support@swagger.io
|
||||
|
||||
// @license.name Apache 2.0
|
||||
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
// @host localhost:8080
|
||||
// @BasePath /api/v1
|
||||
|
||||
// @securityDefinitions.basic BasicAuth
|
||||
|
||||
// @externalDocs.description OpenAPI
|
||||
// @externalDocs.url https://swagger.io/resources/open-api/
|
||||
func ServeWeb(port uint) *http.Server {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
r := gin.Default()
|
||||
@ -39,16 +51,7 @@ func ServeWeb(port uint) *http.Server {
|
||||
}
|
||||
r.Use(natGateway)
|
||||
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler))
|
||||
tmpl := template.New("").Funcs(funcMap)
|
||||
var err error
|
||||
tmpl, err = tmpl.ParseFS(resource.TemplateFS, "template/**/*.html")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
tmpl = loadThirdPartyTemplates(tmpl)
|
||||
r.SetHTMLTemplate(tmpl)
|
||||
r.Use(mygin.RecordPath)
|
||||
r.StaticFS("/static", http.FS(resource.StaticFS))
|
||||
routers(r)
|
||||
page404 := func(c *gin.Context) {
|
||||
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
||||
@ -71,6 +74,19 @@ func ServeWeb(port uint) *http.Server {
|
||||
}
|
||||
|
||||
func routers(r *gin.Engine) {
|
||||
authMiddleware, err := jwt.New(initParams())
|
||||
if err != nil {
|
||||
log.Fatal("JWT Error:" + err.Error())
|
||||
}
|
||||
|
||||
// register middleware
|
||||
r.Use(handlerMiddleWare(authMiddleware))
|
||||
|
||||
r.POST("/login", authMiddleware.LoginHandler)
|
||||
|
||||
auth := r.Group("/auth", authMiddleware.MiddlewareFunc())
|
||||
auth.GET("/refresh_token", authMiddleware.RefreshHandler)
|
||||
|
||||
// 通用页面
|
||||
cp := commonPage{r: r}
|
||||
cp.serve()
|
||||
@ -88,206 +104,6 @@ func routers(r *gin.Engine) {
|
||||
}
|
||||
}
|
||||
|
||||
func loadThirdPartyTemplates(tmpl *template.Template) *template.Template {
|
||||
ret := tmpl
|
||||
themes, err := os.ReadDir("resource/template")
|
||||
if err != nil {
|
||||
log.Printf("NEZHA>> Error reading themes folder: %v", err)
|
||||
return ret
|
||||
}
|
||||
for _, theme := range themes {
|
||||
if !theme.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
themeDir := theme.Name()
|
||||
if themeDir == "theme-custom" {
|
||||
// for backward compatibility
|
||||
// note: will remove this in future versions
|
||||
ret = loadTemplates(ret, themeDir)
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.HasPrefix(themeDir, "dashboard-") {
|
||||
// load dashboard templates, ignore desc file
|
||||
ret = loadTemplates(ret, themeDir)
|
||||
continue
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(themeDir, "theme-") {
|
||||
log.Printf("NEZHA>> Invalid theme name: %s", themeDir)
|
||||
continue
|
||||
}
|
||||
|
||||
descPath := filepath.Join("resource", "template", themeDir, "theme.json")
|
||||
desc, err := os.ReadFile(filepath.Clean(descPath))
|
||||
if err != nil {
|
||||
log.Printf("NEZHA>> Error opening %s config: %v", themeDir, err)
|
||||
continue
|
||||
}
|
||||
|
||||
themeName, err := utils.GjsonGet(desc, "name")
|
||||
if err != nil {
|
||||
log.Printf("NEZHA>> Error opening %s config: not a valid description file", theme.Name())
|
||||
continue
|
||||
}
|
||||
|
||||
// load templates
|
||||
ret = loadTemplates(ret, themeDir)
|
||||
|
||||
themeKey := strings.TrimPrefix(themeDir, "theme-")
|
||||
model.Themes[themeKey] = themeName.String()
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func loadTemplates(tmpl *template.Template, themeDir string) *template.Template {
|
||||
// load templates
|
||||
templatePath := filepath.Join("resource", "template", themeDir, "*.html")
|
||||
t, err := tmpl.ParseGlob(templatePath)
|
||||
if err != nil {
|
||||
log.Printf("NEZHA>> Error parsing templates %s: %v", themeDir, err)
|
||||
return tmpl
|
||||
}
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
var funcMap = template.FuncMap{
|
||||
"tr": func(id string, dataAndCount ...interface{}) string {
|
||||
conf := i18n.LocalizeConfig{
|
||||
MessageID: id,
|
||||
}
|
||||
if len(dataAndCount) > 0 {
|
||||
conf.TemplateData = dataAndCount[0]
|
||||
}
|
||||
if len(dataAndCount) > 1 {
|
||||
conf.PluralCount = dataAndCount[1]
|
||||
}
|
||||
return singleton.Localizer.MustLocalize(&conf)
|
||||
},
|
||||
"toValMap": func(val interface{}) map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"Value": val,
|
||||
}
|
||||
},
|
||||
"tf": func(t time.Time) string {
|
||||
return t.In(singleton.Loc).Format("01/02/2006 15:04:05")
|
||||
},
|
||||
"len": func(slice []interface{}) string {
|
||||
return strconv.Itoa(len(slice))
|
||||
},
|
||||
"safe": func(s string) template.HTML {
|
||||
return template.HTML(s) // #nosec
|
||||
},
|
||||
"tag": func(s string) template.HTML {
|
||||
return template.HTML(`<` + s + `>`) // #nosec
|
||||
},
|
||||
"stf": func(s uint64) string {
|
||||
return time.Unix(int64(s), 0).In(singleton.Loc).Format("01/02/2006 15:04")
|
||||
},
|
||||
"sf": func(duration uint64) string {
|
||||
return time.Duration(time.Duration(duration) * time.Second).String()
|
||||
},
|
||||
"sft": func(future time.Time) string {
|
||||
return time.Until(future).Round(time.Second).String()
|
||||
},
|
||||
"bf": func(b uint64) string {
|
||||
return bytefmt.ByteSize(b)
|
||||
},
|
||||
"ts": func(s string) string {
|
||||
return strings.TrimSpace(s)
|
||||
},
|
||||
"float32f": func(f float32) string {
|
||||
return fmt.Sprintf("%.3f", f)
|
||||
},
|
||||
"divU64": func(a, b uint64) float32 {
|
||||
if b == 0 {
|
||||
if a > 0 {
|
||||
return 100
|
||||
}
|
||||
return 0
|
||||
}
|
||||
if a == 0 {
|
||||
// 这是从未在线的情况
|
||||
return 0.00001 / float32(b) * 100
|
||||
}
|
||||
return float32(a) / float32(b) * 100
|
||||
},
|
||||
"div": func(a, b int) float32 {
|
||||
if b == 0 {
|
||||
if a > 0 {
|
||||
return 100
|
||||
}
|
||||
return 0
|
||||
}
|
||||
if a == 0 {
|
||||
// 这是从未在线的情况
|
||||
return 0.00001 / float32(b) * 100
|
||||
}
|
||||
return float32(a) / float32(b) * 100
|
||||
},
|
||||
"addU64": func(a, b uint64) uint64 {
|
||||
return a + b
|
||||
},
|
||||
"add": func(a, b int) int {
|
||||
return a + b
|
||||
},
|
||||
"TransLeftPercent": func(a, b float64) (n float64) {
|
||||
n, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", (100-(a/b)*100)), 64)
|
||||
if n < 0 {
|
||||
n = 0
|
||||
}
|
||||
return
|
||||
},
|
||||
"TransLeft": func(a, b uint64) string {
|
||||
if a < b {
|
||||
return "0B"
|
||||
}
|
||||
return bytefmt.ByteSize(a - b)
|
||||
},
|
||||
"TransClassName": func(a float64) string {
|
||||
if a == 0 {
|
||||
return "offline"
|
||||
}
|
||||
if a > 50 {
|
||||
return "fine"
|
||||
}
|
||||
if a > 20 {
|
||||
return "warning"
|
||||
}
|
||||
if a > 0 {
|
||||
return "error"
|
||||
}
|
||||
return "offline"
|
||||
},
|
||||
"UintToFloat": func(a uint64) (n float64) {
|
||||
n, _ = strconv.ParseFloat((strconv.FormatUint(a, 10)), 64)
|
||||
return
|
||||
},
|
||||
"dayBefore": func(i int) string {
|
||||
year, month, day := time.Now().Date()
|
||||
today := time.Date(year, month, day, 0, 0, 0, 0, singleton.Loc)
|
||||
return today.AddDate(0, 0, i-29).Format("01/02")
|
||||
},
|
||||
"className": func(percent float32) string {
|
||||
if percent == 0 {
|
||||
return ""
|
||||
}
|
||||
if percent > 95 {
|
||||
return "good"
|
||||
}
|
||||
if percent > 80 {
|
||||
return "warning"
|
||||
}
|
||||
return "danger"
|
||||
},
|
||||
"statusName": func(val float32) string {
|
||||
return singleton.StatusCodeToString(singleton.GetStatusCode(val))
|
||||
},
|
||||
}
|
||||
|
||||
func natGateway(c *gin.Context) {
|
||||
natConfig := singleton.GetNATConfigByDomain(c.Request.Host)
|
||||
if natConfig == nil {
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
|
||||
"github.com/naiba/nezha/model"
|
||||
"github.com/naiba/nezha/pkg/mygin"
|
||||
@ -56,7 +55,7 @@ func (gp *guestPage) login(c *gin.Context) {
|
||||
RegistrationLink = singleton.Conf.Oauth2.OidcRegisterURL
|
||||
}
|
||||
c.HTML(http.StatusOK, "dashboard-"+singleton.Conf.Site.DashboardTheme+"/login", mygin.CommonEnvironment(c, gin.H{
|
||||
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Login"}),
|
||||
// "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Login"}),
|
||||
"LoginType": LoginType,
|
||||
"RegistrationLink": RegistrationLink,
|
||||
}))
|
||||
|
96
cmd/dashboard/controller/jwt.go
Normal file
@ -0,0 +1,96 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
|
||||
jwt "github.com/appleboy/gin-jwt/v2"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/naiba/nezha/model"
|
||||
)
|
||||
|
||||
func initParams() *jwt.GinJWTMiddleware {
|
||||
return &jwt.GinJWTMiddleware{
|
||||
Realm: "test zone",
|
||||
Key: []byte("secret key"),
|
||||
Timeout: time.Hour,
|
||||
MaxRefresh: time.Hour,
|
||||
IdentityKey: model.CtxKeyAuthorizedUser,
|
||||
PayloadFunc: payloadFunc(),
|
||||
|
||||
IdentityHandler: identityHandler(),
|
||||
Authenticator: authenticator(),
|
||||
Authorizator: authorizator(),
|
||||
Unauthorized: unauthorized(),
|
||||
TokenLookup: "header: Authorization, query: token, cookie: jwt",
|
||||
TokenHeadName: "Bearer",
|
||||
TimeFunc: time.Now,
|
||||
}
|
||||
}
|
||||
|
||||
func handlerMiddleWare(authMiddleware *jwt.GinJWTMiddleware) gin.HandlerFunc {
|
||||
return func(context *gin.Context) {
|
||||
errInit := authMiddleware.MiddlewareInit()
|
||||
if errInit != nil {
|
||||
log.Fatal("authMiddleware.MiddlewareInit() Error:" + errInit.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func payloadFunc() func(data interface{}) jwt.MapClaims {
|
||||
return func(data interface{}) jwt.MapClaims {
|
||||
if v, ok := data.(*model.User); ok {
|
||||
return jwt.MapClaims{
|
||||
model.CtxKeyAuthorizedUser: v.Username,
|
||||
}
|
||||
}
|
||||
return jwt.MapClaims{}
|
||||
}
|
||||
}
|
||||
|
||||
func identityHandler() func(c *gin.Context) interface{} {
|
||||
return func(c *gin.Context) interface{} {
|
||||
claims := jwt.ExtractClaims(c)
|
||||
return &model.User{
|
||||
Username: claims[model.CtxKeyAuthorizedUser].(string),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func authenticator() func(c *gin.Context) (interface{}, error) {
|
||||
return func(c *gin.Context) (interface{}, error) {
|
||||
var loginVals model.LoginRequest
|
||||
if err := c.ShouldBind(&loginVals); err != nil {
|
||||
return "", jwt.ErrMissingLoginValues
|
||||
}
|
||||
userID := loginVals.Username
|
||||
password := loginVals.Password
|
||||
|
||||
if (userID == "admin" && password == "admin") || (userID == "test" && password == "test") {
|
||||
return &model.User{
|
||||
Username: userID,
|
||||
}, nil
|
||||
}
|
||||
return nil, jwt.ErrFailedAuthentication
|
||||
}
|
||||
}
|
||||
|
||||
func authorizator() func(data interface{}, c *gin.Context) bool {
|
||||
return func(data interface{}, c *gin.Context) bool {
|
||||
if v, ok := data.(*model.User); ok && v.Username == "admin" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func unauthorized() func(c *gin.Context, code int, message string) {
|
||||
return func(c *gin.Context, code int, message string) {
|
||||
c.JSON(code, model.CommonResponse{
|
||||
Success: false,
|
||||
Error: model.CommonError{
|
||||
Code: model.ApiErrorUnauthorized,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
@ -19,7 +19,6 @@ import (
|
||||
"github.com/naiba/nezha/pkg/mygin"
|
||||
"github.com/naiba/nezha/pkg/utils"
|
||||
"github.com/naiba/nezha/proto"
|
||||
"github.com/naiba/nezha/resource"
|
||||
"github.com/naiba/nezha/service/singleton"
|
||||
)
|
||||
|
||||
@ -1050,22 +1049,6 @@ func (ma *memberAPI) updateSetting(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if !utils.IsFileExists("resource/template/theme-"+sf.Theme+"/home.html") && !resource.IsTemplateFileExist("template/theme-"+sf.Theme+"/home.html") {
|
||||
c.JSON(http.StatusOK, model.Response{
|
||||
Code: http.StatusBadRequest,
|
||||
Message: fmt.Sprintf("前台主题文件异常:%s", sf.Theme),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if !utils.IsFileExists("resource/template/dashboard-"+sf.DashboardTheme+"/setting.html") && !resource.IsTemplateFileExist("template/dashboard-"+sf.DashboardTheme+"/setting.html") {
|
||||
c.JSON(http.StatusOK, model.Response{
|
||||
Code: http.StatusBadRequest,
|
||||
Message: fmt.Sprintf("后台主题文件异常:%s", sf.DashboardTheme),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
singleton.Conf.Language = sf.Language
|
||||
singleton.Conf.EnableIPChangeNotification = sf.EnableIPChangeNotification == "on"
|
||||
singleton.Conf.EnablePlainIPInNotification = sf.EnablePlainIPInNotification == "on"
|
||||
@ -1093,8 +1076,6 @@ func (ma *memberAPI) updateSetting(c *gin.Context) {
|
||||
})
|
||||
return
|
||||
}
|
||||
// 更新系统语言
|
||||
singleton.InitLocalizer()
|
||||
// 更新DNS服务器
|
||||
singleton.OnNameserverUpdate()
|
||||
c.JSON(http.StatusOK, model.Response{
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
"github.com/naiba/nezha/model"
|
||||
"github.com/naiba/nezha/pkg/mygin"
|
||||
"github.com/naiba/nezha/service/singleton"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
)
|
||||
|
||||
type memberPage struct {
|
||||
@ -19,8 +18,8 @@ func (mp *memberPage) serve() {
|
||||
mr.Use(mygin.Authorize(mygin.AuthorizeOption{
|
||||
MemberOnly: true,
|
||||
IsPage: true,
|
||||
Msg: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "YouAreNotAuthorized"}),
|
||||
Btn: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Login"}),
|
||||
// Msg: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "YouAreNotAuthorized"}),
|
||||
// Btn: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Login"}),
|
||||
Redirect: "/login",
|
||||
}))
|
||||
mr.GET("/server", mp.server)
|
||||
@ -37,7 +36,7 @@ func (mp *memberPage) api(c *gin.Context) {
|
||||
singleton.ApiLock.RLock()
|
||||
defer singleton.ApiLock.RUnlock()
|
||||
c.HTML(http.StatusOK, "dashboard-"+singleton.Conf.Site.DashboardTheme+"/api", mygin.CommonEnvironment(c, gin.H{
|
||||
"title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ApiManagement"}),
|
||||
// "title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ApiManagement"}),
|
||||
"Tokens": singleton.ApiTokenList,
|
||||
}))
|
||||
}
|
||||
@ -46,14 +45,14 @@ func (mp *memberPage) server(c *gin.Context) {
|
||||
singleton.SortedServerLock.RLock()
|
||||
defer singleton.SortedServerLock.RUnlock()
|
||||
c.HTML(http.StatusOK, "dashboard-"+singleton.Conf.Site.DashboardTheme+"/server", mygin.CommonEnvironment(c, gin.H{
|
||||
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ServersManagement"}),
|
||||
// "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ServersManagement"}),
|
||||
"Servers": singleton.SortedServerList,
|
||||
}))
|
||||
}
|
||||
|
||||
func (mp *memberPage) monitor(c *gin.Context) {
|
||||
c.HTML(http.StatusOK, "dashboard-"+singleton.Conf.Site.DashboardTheme+"/monitor", mygin.CommonEnvironment(c, gin.H{
|
||||
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ServicesManagement"}),
|
||||
// "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ServicesManagement"}),
|
||||
"Monitors": singleton.ServiceSentinelShared.Monitors(),
|
||||
}))
|
||||
}
|
||||
@ -62,7 +61,7 @@ func (mp *memberPage) cron(c *gin.Context) {
|
||||
var crons []model.Cron
|
||||
singleton.DB.Find(&crons)
|
||||
c.HTML(http.StatusOK, "dashboard-"+singleton.Conf.Site.DashboardTheme+"/cron", mygin.CommonEnvironment(c, gin.H{
|
||||
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ScheduledTasks"}),
|
||||
// "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ScheduledTasks"}),
|
||||
"Crons": crons,
|
||||
}))
|
||||
}
|
||||
@ -73,7 +72,7 @@ func (mp *memberPage) notification(c *gin.Context) {
|
||||
var ar []model.AlertRule
|
||||
singleton.DB.Find(&ar)
|
||||
c.HTML(http.StatusOK, "dashboard-"+singleton.Conf.Site.DashboardTheme+"/notification", mygin.CommonEnvironment(c, gin.H{
|
||||
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Notification"}),
|
||||
// "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Notification"}),
|
||||
"Notifications": nf,
|
||||
"AlertRules": ar,
|
||||
}))
|
||||
@ -83,7 +82,7 @@ func (mp *memberPage) ddns(c *gin.Context) {
|
||||
var data []model.DDNSProfile
|
||||
singleton.DB.Find(&data)
|
||||
c.HTML(http.StatusOK, "dashboard-"+singleton.Conf.Site.DashboardTheme+"/ddns", mygin.CommonEnvironment(c, gin.H{
|
||||
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "DDNS"}),
|
||||
// "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "DDNS"}),
|
||||
"DDNS": data,
|
||||
"ProviderMap": model.ProviderMap,
|
||||
"ProviderList": model.ProviderList,
|
||||
@ -94,14 +93,14 @@ func (mp *memberPage) nat(c *gin.Context) {
|
||||
var data []model.NAT
|
||||
singleton.DB.Find(&data)
|
||||
c.HTML(http.StatusOK, "dashboard-"+singleton.Conf.Site.DashboardTheme+"/nat", mygin.CommonEnvironment(c, gin.H{
|
||||
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "NAT"}),
|
||||
// "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "NAT"}),
|
||||
"NAT": data,
|
||||
}))
|
||||
}
|
||||
|
||||
func (mp *memberPage) setting(c *gin.Context) {
|
||||
c.HTML(http.StatusOK, "dashboard-"+singleton.Conf.Site.DashboardTheme+"/setting", mygin.CommonEnvironment(c, gin.H{
|
||||
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Settings"}),
|
||||
// "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Settings"}),
|
||||
"Languages": model.Languages,
|
||||
"DashboardThemes": model.DashboardThemes,
|
||||
}))
|
||||
|
@ -39,7 +39,6 @@ func init() {
|
||||
singleton.InitConfigFromPath(dashboardCliParam.ConfigFile)
|
||||
singleton.InitTimezoneAndCache()
|
||||
singleton.InitDBFromPath(dashboardCliParam.DatebaseLocation)
|
||||
singleton.InitLocalizer()
|
||||
initSystem()
|
||||
}
|
||||
|
||||
|
43
go.mod
@ -1,12 +1,13 @@
|
||||
module github.com/naiba/nezha
|
||||
|
||||
go 1.21
|
||||
go 1.21.0
|
||||
|
||||
toolchain go1.23.1
|
||||
|
||||
require (
|
||||
code.cloudfoundry.org/bytefmt v0.0.0-20240425163905-bcdc1ad063ea
|
||||
github.com/BurntSushi/toml v1.3.2
|
||||
github.com/appleboy/gin-jwt/v2 v2.10.0
|
||||
github.com/gin-contrib/pprof v1.4.0
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
github.com/gin-gonic/gin v1.10.0
|
||||
github.com/gorilla/websocket v1.5.1
|
||||
github.com/hashicorp/go-uuid v1.0.3
|
||||
github.com/jinzhu/copier v0.4.0
|
||||
@ -15,7 +16,6 @@ require (
|
||||
github.com/libdns/libdns v0.2.2
|
||||
github.com/libdns/tencentcloud v1.0.0
|
||||
github.com/miekg/dns v1.1.62
|
||||
github.com/nicksnyder/go-i18n/v2 v2.4.0
|
||||
github.com/ory/graceful v0.1.3
|
||||
github.com/oschwald/maxminddb-golang v1.13.1
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
@ -26,10 +26,9 @@ require (
|
||||
github.com/swaggo/gin-swagger v1.6.0
|
||||
github.com/swaggo/swag v1.16.4
|
||||
github.com/tidwall/gjson v1.18.0
|
||||
golang.org/x/crypto v0.25.0
|
||||
golang.org/x/net v0.27.0
|
||||
golang.org/x/sync v0.7.0
|
||||
golang.org/x/text v0.16.0
|
||||
golang.org/x/crypto v0.26.0
|
||||
golang.org/x/net v0.28.0
|
||||
golang.org/x/sync v0.8.0
|
||||
google.golang.org/grpc v1.63.0
|
||||
google.golang.org/protobuf v1.34.2
|
||||
gorm.io/driver/sqlite v1.5.5
|
||||
@ -41,10 +40,12 @@ require (
|
||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||
github.com/bytedance/sonic v1.9.1 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
github.com/bytedance/sonic v1.12.2 // indirect
|
||||
github.com/bytedance/sonic/loader v0.2.0 // indirect
|
||||
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.5 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.19.6 // indirect
|
||||
@ -52,14 +53,15 @@ require (
|
||||
github.com/go-openapi/swag v0.19.15 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.14.0 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/go-playground/validator/v10 v10.22.0 // indirect
|
||||
github.com/goccy/go-json v0.10.3 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||
github.com/leodido/go-urn v1.2.4 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mailru/easyjson v0.7.6 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
@ -67,7 +69,7 @@ require (
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
@ -79,13 +81,14 @@ require (
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.9.0 // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/arch v0.9.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
|
||||
golang.org/x/mod v0.18.0 // indirect
|
||||
golang.org/x/sys v0.22.0 // indirect
|
||||
golang.org/x/sys v0.24.0 // indirect
|
||||
golang.org/x/text v0.17.0 // indirect
|
||||
golang.org/x/tools v0.22.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
|
100
go.sum
@ -1,19 +1,22 @@
|
||||
code.cloudfoundry.org/bytefmt v0.0.0-20240425163905-bcdc1ad063ea h1:1tgMNDgo8PjpsHhlaxdibj28C0WyLeOW2SPJ7GGdc9A=
|
||||
code.cloudfoundry.org/bytefmt v0.0.0-20240425163905-bcdc1ad063ea/go.mod h1:3+xXJBOD8PsGHDqHedtCLalbaVJ+yi1OW+mXx9IcNxI=
|
||||
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
|
||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
|
||||
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
||||
github.com/appleboy/gin-jwt/v2 v2.10.0 h1:vOlGSly8oIGQiT8AcEh1nYMLYI1K9YvsZNVWM612xN0=
|
||||
github.com/appleboy/gin-jwt/v2 v2.10.0/go.mod h1:DvCh3V1Ma32/7kAsAHYQVyjsQMwG+wMXGpyCYLfHOJU=
|
||||
github.com/appleboy/gofight/v2 v2.1.2 h1:VOy3jow4vIK8BRQJoC/I9muxyYlJ2yb9ht2hZoS3rf4=
|
||||
github.com/appleboy/gofight/v2 v2.1.2/go.mod h1:frW+U1QZEdDgixycTj4CygQ48yLTUhplt43+Wczp3rw=
|
||||
github.com/bytedance/sonic v1.12.2 h1:oaMFuRTpMHYLpCntGca65YWt5ny+wAceDERTkT2L9lg=
|
||||
github.com/bytedance/sonic v1.12.2/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
|
||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM=
|
||||
github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
|
||||
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
|
||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@ -23,8 +26,8 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
|
||||
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
|
||||
github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4=
|
||||
github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4=
|
||||
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
|
||||
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
|
||||
github.com/gin-contrib/pprof v1.4.0 h1:XxiBSf5jWZ5i16lNOPbMTVdgHBdhfGRD5PZ1LWazzvg=
|
||||
@ -32,10 +35,8 @@ github.com/gin-contrib/pprof v1.4.0/go.mod h1:RrehPJasUVBPK6yTUwOl8/NP6i0vbUgmxt
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
|
||||
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
|
||||
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
|
||||
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
@ -56,21 +57,19 @@ github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
|
||||
github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
|
||||
github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao=
|
||||
github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
||||
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg=
|
||||
github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
|
||||
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
|
||||
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
|
||||
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||
@ -88,8 +87,9 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
|
||||
github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
|
||||
github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
|
||||
github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
@ -100,8 +100,8 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
||||
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||
github.com/libdns/cloudflare v0.1.1 h1:FVPfWwP8zZCqj268LZjmkDleXlHPlFU9KC4OJ3yn054=
|
||||
github.com/libdns/cloudflare v0.1.1/go.mod h1:9VK91idpOjg6v7/WbjkEW49bSCxj00ALesIFDhJ8PBU=
|
||||
github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s=
|
||||
@ -128,13 +128,7 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.4.0/go.mod h1:nxYSZE9M0bf3Y70gPQjN9ha7XNHX7gMc814+6wVyEI4=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8=
|
||||
github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
|
||||
github.com/onsi/gomega v1.33.0 h1:snPCflnZrpMsy94p4lXVEkHo12lmPnc3vY5XBbreexE=
|
||||
github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxjX3wY=
|
||||
github.com/ory/graceful v0.1.3 h1:FaeXcHZh168WzS+bqruqWEw/HgXWLdNv2nJ+fbhxbhc=
|
||||
github.com/ory/graceful v0.1.3/go.mod h1:4zFz687IAF7oNHHiB586U4iL+/4aV09o/PYLE34t2bA=
|
||||
github.com/oschwald/maxminddb-golang v1.13.1 h1:G3wwjdN9JmIK2o/ermkHM+98oX5fS+k5MbwsmL4MRQE=
|
||||
@ -142,8 +136,8 @@ github.com/oschwald/maxminddb-golang v1.13.1/go.mod h1:K4pgV9N/GcK694KSTmVSDTODk
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
|
||||
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@ -180,8 +174,6 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
@ -204,21 +196,20 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
||||
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
||||
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
|
||||
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
|
||||
golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.9.0 h1:ub9TgUInamJ8mrZIGlBG6/4TqWeMszd4N8lNorbrr6k=
|
||||
golang.org/x/arch v0.9.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
||||
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
||||
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
|
||||
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
@ -229,12 +220,12 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
|
||||
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
||||
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
||||
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -242,12 +233,11 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
|
||||
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
@ -256,8 +246,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
|
||||
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
@ -293,6 +283,6 @@ gorm.io/driver/sqlite v1.5.5 h1:7MDMtUZhV065SilG62E0MquljeArQZNfJnjd9i9gx3E=
|
||||
gorm.io/driver/sqlite v1.5.5/go.mod h1:6NgQ7sQWAIFsPrJJl1lSNSu2TABh0ZZ/zm5fosATavE=
|
||||
gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s=
|
||||
gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
||||
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
||||
|
20
model/api.go
@ -1,5 +1,9 @@
|
||||
package model
|
||||
|
||||
const (
|
||||
ApiErrorUnauthorized = 10001
|
||||
)
|
||||
|
||||
type ServiceItemResponse struct {
|
||||
Monitor *Monitor
|
||||
CurrentUp uint64
|
||||
@ -17,3 +21,19 @@ func (r ServiceItemResponse) TotalUptime() float32 {
|
||||
}
|
||||
return float32(r.TotalUp) / (float32(r.TotalUp + r.TotalDown)) * 100
|
||||
}
|
||||
|
||||
type LoginRequest struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
type CommonError struct {
|
||||
Code int `json:"code"`
|
||||
Args map[string]string `json:"args"`
|
||||
}
|
||||
|
||||
type CommonResponse struct {
|
||||
Success bool `json:"success"`
|
||||
Data interface{} `json:"data"`
|
||||
Error CommonError `json:"error"`
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
|
||||
"github.com/naiba/nezha/model"
|
||||
"github.com/naiba/nezha/service/singleton"
|
||||
@ -41,15 +40,6 @@ func CommonEnvironment(c *gin.Context, data map[string]interface{}) gin.H {
|
||||
if ok {
|
||||
data["Admin"] = u
|
||||
}
|
||||
data["LANG"] = map[string]string{
|
||||
"Add": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Add"}),
|
||||
"Edit": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Edit"}),
|
||||
"AlarmRule": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "AlarmRule"}),
|
||||
"Notification": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "NotificationMethod"}),
|
||||
"Server": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Server"}),
|
||||
"Monitor": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ServicesManagement"}),
|
||||
"Cron": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ScheduledTasks"}),
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/naiba/nezha/model"
|
||||
"github.com/naiba/nezha/service/singleton"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
@ -37,7 +36,7 @@ func ValidateViewPassword(opt ValidateViewPasswordOption) gin.HandlerFunc {
|
||||
}
|
||||
if opt.IsPage {
|
||||
c.HTML(http.StatusOK, GetPreferredTheme(c, "/viewpassword"), CommonEnvironment(c, gin.H{
|
||||
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "VerifyPassword"}),
|
||||
// "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "VerifyPassword"}),
|
||||
}))
|
||||
|
||||
} else {
|
||||
|
752
resource/l10n/en-US.toml
vendored
@ -1,752 +0,0 @@
|
||||
[NezhaMonitoring]
|
||||
other = "Nezha Monitoring"
|
||||
|
||||
[Server]
|
||||
other = "Servers"
|
||||
|
||||
[Services]
|
||||
other = "Services"
|
||||
|
||||
[Task]
|
||||
other = "Tasks"
|
||||
|
||||
[Notification]
|
||||
other = "Notifications"
|
||||
|
||||
[Settings]
|
||||
other = "Settings"
|
||||
|
||||
[Home]
|
||||
other = "Home"
|
||||
|
||||
[BackToHomepage]
|
||||
other = "Back to Homepage"
|
||||
|
||||
[AdminPanel]
|
||||
other = "Dashboard"
|
||||
|
||||
[Logout]
|
||||
other = "Log out"
|
||||
|
||||
[Login]
|
||||
other = "Log in"
|
||||
|
||||
[ConfirmLogout]
|
||||
other = "Confirm Logging Out?"
|
||||
|
||||
[AfterLoggingOutYouHaveToLoginAgain]
|
||||
other = "You will need to log in again to continue"
|
||||
|
||||
[Cancel]
|
||||
other = "Cancel"
|
||||
|
||||
[Confirm]
|
||||
other = "Confirm"
|
||||
|
||||
[AddScheduledTasks]
|
||||
other = "Add Schedule Task"
|
||||
|
||||
[Name]
|
||||
other = "Name"
|
||||
|
||||
[Scheduler]
|
||||
other = "Cron Expression"
|
||||
|
||||
[BackUp]
|
||||
other = "Backup"
|
||||
|
||||
[3amDaily]
|
||||
other = "(At 3 AM)"
|
||||
|
||||
[Command]
|
||||
other = "Command"
|
||||
|
||||
[Coverage]
|
||||
other = "Coverage"
|
||||
|
||||
[IgnoreAllAndExecuteOnlyThroughSpecificServers]
|
||||
other = "Ignore All, Execute Only on Specific Servers"
|
||||
|
||||
[AllIncludedOnlySpecificServersAreNotExecuted]
|
||||
other = "Cover All, Except Specific Servers"
|
||||
|
||||
[ExecuteByTriggerServer]
|
||||
other = "Execute on Alarmed Servers"
|
||||
|
||||
[SpecificServers]
|
||||
other = "Specific Servers"
|
||||
|
||||
[EnterIdAndNameToSearch]
|
||||
other = "Enter ID/Name to search"
|
||||
|
||||
[NotificationMethodGroup]
|
||||
other = "Notification Method Group"
|
||||
|
||||
[PushSuccessMessages]
|
||||
other = "Send Success Messages"
|
||||
|
||||
[TaskType]
|
||||
other = "Task Type"
|
||||
|
||||
[CronTask]
|
||||
other = "Cron Task"
|
||||
|
||||
[TriggerTask]
|
||||
other = "Trigger Task"
|
||||
|
||||
[TheFormaOfTheScheduleIs]
|
||||
other = "The Cron Expression format is:"
|
||||
|
||||
[SecondsMinutesHoursDaysMonthsWeeksSeeDetails]
|
||||
other = "Sec Min Hour Day Month Week, see details in "
|
||||
|
||||
[ScheduleExpressionFormat]
|
||||
other = "CRON Expression Format"
|
||||
|
||||
[IntroductionOfCommands]
|
||||
other = "Note on writing commands: It is similar to shell/bat scripts. but it's advised not to start a newline, and connect multiple commands with <code>&&</code> or <code>;</code>. If a command cannot be found, it is possibly due to <code>PATH</code> environment variable issues. On <code>Linux</code> servers, you can add <code>source ~/.bashrc</code> at the beginning of the command, or just use the absolute path."
|
||||
|
||||
[AddMonitor]
|
||||
other = "Add Service Monitor"
|
||||
|
||||
[Blog]
|
||||
other = "Blog"
|
||||
|
||||
[Target]
|
||||
other = "Target"
|
||||
|
||||
[Type]
|
||||
other = "Type"
|
||||
|
||||
[SslExpirationOrChange]
|
||||
other = "(Certificate Expiration and Changes)"
|
||||
|
||||
[Duration]
|
||||
other = "Interval"
|
||||
|
||||
[Seconds]
|
||||
other = "Seconds"
|
||||
|
||||
[EnableFailureNotification]
|
||||
other = "Enable Failure Notification"
|
||||
|
||||
[FailureNotification]
|
||||
other = "Failure Notification"
|
||||
|
||||
[MaxLatency]
|
||||
other = "Maximum Latency (ms)"
|
||||
|
||||
[MinLatency]
|
||||
other = "Minimum Latency (ms)"
|
||||
|
||||
[EnableLatencyNotification]
|
||||
other = "Enable Latency Notification"
|
||||
|
||||
[LatencyNotification]
|
||||
other = "Latency Notification"
|
||||
|
||||
[IntroductionOfMonitor]
|
||||
other = """
|
||||
For type <b>HTTP-GET</b>, enter URL (with http/https scheme, HTTPS protocol will also monitor SSL certificate);<br>
|
||||
For type <b>ICMP-Ping</b>, enter domain/IP without port: example.com;<br>
|
||||
For type <b>TCP-Ping</b>, enter domain/IP + port number: example.com:22"""
|
||||
|
||||
[AddNotificationMethod]
|
||||
other = "Add Notification Method"
|
||||
|
||||
[Tag]
|
||||
other = "Notification Group"
|
||||
|
||||
[DoNotSendTestMessages]
|
||||
other = "Do Not Send Test Message"
|
||||
|
||||
[RequestMethod]
|
||||
other = "Request Method"
|
||||
|
||||
[RequestType]
|
||||
other = "Request Type"
|
||||
|
||||
[VerifySSL]
|
||||
other = "Verify SSL"
|
||||
|
||||
[AddNotificationRule]
|
||||
other = "Add Notification Rule"
|
||||
|
||||
[Rules]
|
||||
other = "Rules"
|
||||
|
||||
[NotificationTriggerMode]
|
||||
other = "Notification Trigger Mode"
|
||||
|
||||
[ModeAlwaysTrigger]
|
||||
other = "Always Trigger"
|
||||
|
||||
[ModeOnetimeTrigger]
|
||||
other = "Trigger Once"
|
||||
|
||||
[EnableTriggerTask]
|
||||
other = "Enable Trigger Task"
|
||||
|
||||
[FailTriggerTasks]
|
||||
other = "Tasks to trigger on an alarm"
|
||||
|
||||
[RecoverTriggerTasks]
|
||||
other = "Tasks to trigger after recovery"
|
||||
|
||||
[Enable]
|
||||
other = "Enable"
|
||||
|
||||
[AddServer]
|
||||
other = "Add Server"
|
||||
|
||||
[BatchEditServerGroup]
|
||||
other = "Batch Edit Server Group"
|
||||
|
||||
[BatchDeleteServer]
|
||||
other = "Batch Delete Server"
|
||||
|
||||
[InputServerGroupName]
|
||||
other = "Input Server Group Name"
|
||||
|
||||
[ServerGroup]
|
||||
other = "Server Group"
|
||||
|
||||
[EinsteinLightspeed1]
|
||||
other = "Einstein Lightspeed 1"
|
||||
|
||||
[DisplayIndex]
|
||||
other = "Display Index"
|
||||
|
||||
[TheLargerTheNumberTheHigherThePriority]
|
||||
other = "Greater Number, Higher Priority"
|
||||
|
||||
[Secret]
|
||||
other = "Secret"
|
||||
|
||||
[Note]
|
||||
other = "Note"
|
||||
|
||||
[PublicNote]
|
||||
other = "Public Note"
|
||||
|
||||
[LinuxOneKeyInstall]
|
||||
other = "Linux Installation Command"
|
||||
|
||||
[NoDomainAlert]
|
||||
other = "Please set the IP (or a domain pointed to it) of the original server in settings"
|
||||
|
||||
[PushSuccessfully]
|
||||
other = "Send Success Notification"
|
||||
|
||||
[LastExecution]
|
||||
other = "Last Execution"
|
||||
|
||||
[LastResult]
|
||||
other = "Last Result"
|
||||
|
||||
[Administration]
|
||||
other = "Manage"
|
||||
|
||||
[CoverAll]
|
||||
other = "Cover All"
|
||||
|
||||
[IgnoreAll]
|
||||
other = "Ignore All"
|
||||
|
||||
[ByTrigger]
|
||||
other = "Alarmed Servers"
|
||||
|
||||
[DeleteScheduledTask]
|
||||
other = "Delete Scheduled Task"
|
||||
|
||||
[ConfirmToDeleteThisScheduledTask]
|
||||
other = "Confirm deletion?"
|
||||
|
||||
[AccessDenied]
|
||||
other = "Access Denied"
|
||||
|
||||
[Use]
|
||||
other = "Use"
|
||||
|
||||
[AccountToLogin]
|
||||
other = "Account Login"
|
||||
|
||||
[SignUp]
|
||||
other = "Sign up"
|
||||
|
||||
[DontHaveAnAccount]
|
||||
other = "Don't Have an Account?"
|
||||
|
||||
[SSLCertificate]
|
||||
other = "HTTP(S)/SSL Certificate"
|
||||
|
||||
[TCPPort]
|
||||
other = "TCPing"
|
||||
|
||||
[DeleteService]
|
||||
other = "Remove Service Monitor"
|
||||
|
||||
[ConfirmToDeleteThisService]
|
||||
other = "Confirm Deleting This Service?"
|
||||
|
||||
[DeleteNotificationMethod]
|
||||
other = "Delete Notification Method"
|
||||
|
||||
[ConfirmToDeleteThisNotificationMethod]
|
||||
other = "Confirm Deleting This Notification Method?"
|
||||
|
||||
[ForceUpdate]
|
||||
other = "Trigger Agent Update"
|
||||
|
||||
[SelectAll]
|
||||
other = "Select All"
|
||||
|
||||
[VersionNumber]
|
||||
other = "Version"
|
||||
|
||||
[OneKeyInstall]
|
||||
other = "Installation commands"
|
||||
|
||||
[ClickToCopy]
|
||||
other = "Click To Copy"
|
||||
|
||||
[DeleteServer]
|
||||
other = "Delete Server"
|
||||
|
||||
[ConfirmToDeleteServer]
|
||||
other = "Confirm Deleting This Server?"
|
||||
|
||||
[NoServerSelected]
|
||||
other = "No Server Selected"
|
||||
|
||||
[ExecutionResults]
|
||||
other = "Execute Results"
|
||||
|
||||
[SiteTitle]
|
||||
other = "Site Title"
|
||||
|
||||
[AdministratorList]
|
||||
other = "Administrator List"
|
||||
|
||||
[Theme]
|
||||
other = "Frontend Theme"
|
||||
|
||||
[CustomCodes]
|
||||
other = "Custom Codes (Style and Script)"
|
||||
|
||||
[CustomCodesDashboard]
|
||||
other = "Custom Codes for Dashboard"
|
||||
|
||||
[AccessPassword]
|
||||
other = "Frontend Access Password"
|
||||
|
||||
[PanelServerDomainAndIP]
|
||||
other = "Dashboard Server Domain/IP without CDN"
|
||||
|
||||
[IPChangeAlert]
|
||||
other = "IP Change Notification"
|
||||
|
||||
[AllIncludedOnlySpecificServersAreNotAlerted]
|
||||
other = "Cover All, Only ignore Specific Servers"
|
||||
|
||||
[IgnoreAllOnlyAlertSpecificServers]
|
||||
other = "Ignore All, Cover only Specific Servers"
|
||||
|
||||
[IgnoreAllRequestOnlyThroughSpecificServers]
|
||||
other = "Ignore All, Request Only Through Specific Servers"
|
||||
|
||||
[AllIncludedOnlySpecificServersAreNotRequest]
|
||||
other = "Cover All, Only Specific Servers do not request."
|
||||
|
||||
[ServerIDSeparatedByCommas]
|
||||
other = "Server IDs Separated by Commas"
|
||||
|
||||
[IPChangeNotificationTag]
|
||||
other = "Send Notification To Specific Notification Group"
|
||||
|
||||
[NotificationMessagesDoNotHideIP]
|
||||
other = "Show Full IP Address in Notification Messages"
|
||||
|
||||
[Save]
|
||||
other = "Save"
|
||||
|
||||
[ModifiedSuccessfully]
|
||||
other = "Modified successfully"
|
||||
|
||||
[TerminalConnectionTimeOutOrSessionEnded]
|
||||
other = "Terminal Connection Timeout or Session Ended"
|
||||
|
||||
[TerminalConnectionFailed]
|
||||
other = "The terminal connection failed. Please check the WebSocket reverse proxy configuration for /terminal/*."
|
||||
|
||||
[Default]
|
||||
other = "Default"
|
||||
|
||||
[Offline]
|
||||
other = "Offline"
|
||||
|
||||
[Platform]
|
||||
other = "System"
|
||||
|
||||
[DiskUsed]
|
||||
other = "Disk"
|
||||
|
||||
[MemUsed]
|
||||
other = "RAM"
|
||||
|
||||
[CpuUsed]
|
||||
other = "CPU"
|
||||
|
||||
[Virtualization]
|
||||
other = "Virtualization"
|
||||
|
||||
[SwapUsed]
|
||||
other = "Swap"
|
||||
|
||||
[NetTransfer]
|
||||
other = "Usage"
|
||||
|
||||
[Load]
|
||||
other = "Load"
|
||||
|
||||
[ProcessCount]
|
||||
other = "Process Count"
|
||||
|
||||
[ConnCount]
|
||||
other = "Connection Count"
|
||||
|
||||
[BootTime]
|
||||
other = "Boot Time"
|
||||
|
||||
[LastActive]
|
||||
other = "Last Active"
|
||||
|
||||
[Version]
|
||||
other = "Version"
|
||||
|
||||
[NetSpeed]
|
||||
other = "NIC"
|
||||
|
||||
[Uptime]
|
||||
other = "Uptime"
|
||||
|
||||
[ServerIsOffline]
|
||||
other = "Server is Offline"
|
||||
|
||||
[Day]
|
||||
other = "Days"
|
||||
|
||||
[RealtimeChannelEstablished]
|
||||
other = "Realtime Channel Established"
|
||||
|
||||
[GetTheLatestMonitoringDataInRealTime]
|
||||
other = "You Can Get the Latest Monitoring Data in Real Time!"
|
||||
|
||||
[RealtimeChannelDisconnect]
|
||||
other = "Realtime Channel Disconnect"
|
||||
|
||||
[CanNotGetTheLatestMonitoringDataInRealTime]
|
||||
other = "Cannot Get the Latest Monitoring Data in Real Time!"
|
||||
|
||||
[30DaysOnline]
|
||||
other = "30-Day Availability"
|
||||
|
||||
[Details]
|
||||
other = "Details"
|
||||
|
||||
[Status]
|
||||
other = "Status"
|
||||
|
||||
[Availability]
|
||||
other = "Availability"
|
||||
|
||||
[AverageLatency]
|
||||
other = "Average Latency"
|
||||
|
||||
[CycleTransferStats]
|
||||
other = "Periodic Transfer Stats"
|
||||
|
||||
[From]
|
||||
other = "From"
|
||||
|
||||
[To]
|
||||
other = "To"
|
||||
|
||||
[NextCheck]
|
||||
other = "Next check"
|
||||
|
||||
[CurrentUsage]
|
||||
other = "Current Usage"
|
||||
|
||||
[VerifyPassword]
|
||||
other = "Please enter your password"
|
||||
|
||||
[LightMode]
|
||||
other = "Light Mode"
|
||||
|
||||
[DarkMode]
|
||||
other = "Dark Mode"
|
||||
|
||||
[FollowSystem]
|
||||
other = "System Auto"
|
||||
|
||||
[GridLayout]
|
||||
other = "Grid Layout"
|
||||
|
||||
[ListLayout]
|
||||
other = "List Layout"
|
||||
|
||||
[EnterPassword]
|
||||
other = "Enter Password"
|
||||
|
||||
[Location]
|
||||
other = "Location"
|
||||
|
||||
[Running]
|
||||
other = "Running"
|
||||
|
||||
[UpNetTransfer]
|
||||
other = "Outbound"
|
||||
|
||||
[DownNetTransfer]
|
||||
other = "Inbound"
|
||||
|
||||
[TotalUpNetTransfer]
|
||||
other = "Total Outbound"
|
||||
|
||||
[TotalDownNetTransfer]
|
||||
other = "Total Inbound"
|
||||
|
||||
[WrongPassword]
|
||||
other = "Incorrect Password"
|
||||
|
||||
[AnErrorEccurred]
|
||||
other = "An Error Occurred"
|
||||
|
||||
[SystemError]
|
||||
other = "System Error"
|
||||
|
||||
[NetworkError]
|
||||
other = "Network Error"
|
||||
|
||||
[ServicesStatus]
|
||||
other = "Services Status"
|
||||
|
||||
[ServersManagement]
|
||||
other = "Servers"
|
||||
|
||||
[ServicesManagement]
|
||||
other = "Services"
|
||||
|
||||
[ScheduledTasks]
|
||||
other = "Scheduled Tasks"
|
||||
|
||||
[ApiManagement]
|
||||
other = "API Management"
|
||||
|
||||
[IssueNewApiToken]
|
||||
other = "Generate New API Token"
|
||||
|
||||
[Token]
|
||||
other = "Token"
|
||||
|
||||
[DeleteToken]
|
||||
other = "Delete Token"
|
||||
|
||||
[ConfirmToDeleteThisToken]
|
||||
other = "Confirm Deleting This Token?"
|
||||
|
||||
[YouAreNotAuthorized]
|
||||
other = "This Page needs Authorization"
|
||||
|
||||
[WrongAccessPassword]
|
||||
other = "Wrong Access Password"
|
||||
|
||||
[Add]
|
||||
other = "Add"
|
||||
|
||||
[Edit]
|
||||
other = "Edit"
|
||||
|
||||
[AlarmRule]
|
||||
other = "Alarm Rule"
|
||||
|
||||
[NotificationMethod]
|
||||
other = "Notification Method"
|
||||
|
||||
[Incident]
|
||||
other = "Incident"
|
||||
|
||||
[Resolved]
|
||||
other = "Resolved"
|
||||
|
||||
[StatusDown]
|
||||
other = "Down"
|
||||
|
||||
[StatusNoData]
|
||||
other = "No Data"
|
||||
|
||||
[StatusGood]
|
||||
other = "Good"
|
||||
|
||||
[StatusLowAvailability]
|
||||
other = "Low Availability"
|
||||
|
||||
[ScheduledTaskExecutedSuccessfully]
|
||||
other = "Scheduled Task Executed Successfully"
|
||||
|
||||
[ScheduledTaskExecutedFailed]
|
||||
other = "Scheduled Task Execution Failed"
|
||||
|
||||
[IPChanged]
|
||||
other = "IP Changed"
|
||||
|
||||
[Transleft]
|
||||
other = "Remaining Data"
|
||||
|
||||
[DashboardTheme]
|
||||
other = "Dashboard Theme"
|
||||
|
||||
[Info]
|
||||
other = "Info"
|
||||
|
||||
[HideForGuest]
|
||||
other = "Hide from Guest"
|
||||
|
||||
[Menu]
|
||||
other = "Menu"
|
||||
|
||||
[NetworkSpiter]
|
||||
other = "Network"
|
||||
|
||||
[EnableShowInService]
|
||||
other = "Enable Show in Service"
|
||||
|
||||
[DDNS]
|
||||
other = "Dynamic DNS"
|
||||
|
||||
[DDNSProfiles]
|
||||
other = "DDNS Profiles"
|
||||
|
||||
[AddDDNSProfile]
|
||||
other = "New Profile"
|
||||
|
||||
[EnableDDNS]
|
||||
other = "Enable DDNS"
|
||||
|
||||
[EnableIPv4]
|
||||
other = "IPv4 Enabled"
|
||||
|
||||
[EnableIPv6]
|
||||
other = "IPv6 Enabled"
|
||||
|
||||
[DDNSDomain]
|
||||
other = "Domains"
|
||||
|
||||
[DDNSDomains]
|
||||
other = "Domains (separate with comma)"
|
||||
|
||||
[DDNSProvider]
|
||||
other = "DDNS Provider"
|
||||
|
||||
[MaxRetries]
|
||||
other = "Maximum retry attempts"
|
||||
|
||||
[DDNSAccessID]
|
||||
other = "Credential 1"
|
||||
|
||||
[DDNSAccessSecret]
|
||||
other = "Credential 2"
|
||||
|
||||
[DDNSTokenID]
|
||||
other = "Token ID"
|
||||
|
||||
[DDNSTokenSecret]
|
||||
other = "Token Secret"
|
||||
|
||||
[WebhookURL]
|
||||
other = "Webhook URL"
|
||||
|
||||
[WebhookMethod]
|
||||
other = "Webhook Request Method"
|
||||
|
||||
[WebhookRequestType]
|
||||
other = "Webhook Request Type"
|
||||
|
||||
[WebhookHeaders]
|
||||
other = "Webhook Request Headers"
|
||||
|
||||
[WebhookRequestBody]
|
||||
other = "Webhook Request Body"
|
||||
|
||||
[Feature]
|
||||
other = "Feature"
|
||||
|
||||
[Template]
|
||||
other = "Template"
|
||||
|
||||
[Stat]
|
||||
other = "Asset"
|
||||
|
||||
[Temperature]
|
||||
other = "Temperature"
|
||||
|
||||
[DisableSwitchTemplateInFrontend]
|
||||
other = "Disable Switch Template in Frontend"
|
||||
|
||||
[ServersOnWorldMap]
|
||||
other = "Servers On World Map"
|
||||
|
||||
[NAT]
|
||||
other = "NAT Traversal"
|
||||
|
||||
[LocalService]
|
||||
other = "Local service"
|
||||
|
||||
[LocalServicePlaceholder]
|
||||
other = "192.168.1.1:80 (with port)"
|
||||
|
||||
[BindHostname]
|
||||
other = "Bind hostname"
|
||||
|
||||
[NetworkSpiterList]
|
||||
other = "Network Monitor"
|
||||
|
||||
[Refresh]
|
||||
other = "Refresh"
|
||||
|
||||
[CopyPath]
|
||||
other = "Copy Path"
|
||||
|
||||
[Goto]
|
||||
other = "Go to"
|
||||
|
||||
[GotoHeadline]
|
||||
other = "Go to a Folder"
|
||||
|
||||
[GotoGo]
|
||||
other = "Go"
|
||||
|
||||
[GotoClose]
|
||||
other = "Cancel"
|
||||
|
||||
[FMError]
|
||||
other = "Agent returned an error, please view the console for details. To open a new connection, reopen the FM again."
|
||||
|
||||
[Remaining]
|
||||
other = "Remaining"
|
||||
|
||||
[Lifetime]
|
||||
other = "Lifetime"
|
||||
|
||||
[Price]
|
||||
other = "Price"
|
||||
|
||||
[Expired]
|
||||
other = "Expired"
|
||||
|
||||
[Days]
|
||||
other = "d"
|
||||
|
||||
[CustomNameservers]
|
||||
other = "Custom Public DNS Nameservers for DDNS (separate with comma)"
|
752
resource/l10n/es-ES.toml
vendored
@ -1,752 +0,0 @@
|
||||
[NezhaMonitoring]
|
||||
other = "Nezha Monitoring"
|
||||
|
||||
[Server]
|
||||
other = "Servidores"
|
||||
|
||||
[Services]
|
||||
other = "Servicios"
|
||||
|
||||
[Task]
|
||||
other = "Tareas"
|
||||
|
||||
[Notification]
|
||||
other = "Notificaciones"
|
||||
|
||||
[Settings]
|
||||
other = "Configuraciones"
|
||||
|
||||
[Home]
|
||||
other = "Inicio"
|
||||
|
||||
[BackToHomepage]
|
||||
other = "Volver al Inicio"
|
||||
|
||||
[AdminPanel]
|
||||
other = "Panel de Administración"
|
||||
|
||||
[Logout]
|
||||
other = "Cerrar Sesión"
|
||||
|
||||
[Login]
|
||||
other = "Iniciar Sesión"
|
||||
|
||||
[ConfirmLogout]
|
||||
other = "¿Confirmar Cierre de Sesión?"
|
||||
|
||||
[AfterLoggingOutYouHaveToLoginAgain]
|
||||
other = "Después de cerrar sesión, debe iniciar sesión nuevamente para continuar"
|
||||
|
||||
[Cancel]
|
||||
other = "Cancelar"
|
||||
|
||||
[Confirm]
|
||||
other = "Confirmar"
|
||||
|
||||
[AddScheduledTasks]
|
||||
other = "Agregar Tareas Programadas"
|
||||
|
||||
[Name]
|
||||
other = "Nombre"
|
||||
|
||||
[Scheduler]
|
||||
other = "Plan"
|
||||
|
||||
[BackUp]
|
||||
other = "Respaldo"
|
||||
|
||||
[3amDaily]
|
||||
other = "(Diariamente a las 3 a.m.)"
|
||||
|
||||
[Command]
|
||||
other = "Comandos"
|
||||
|
||||
[Coverage]
|
||||
other = "Cobertura"
|
||||
|
||||
[IgnoreAllAndExecuteOnlyThroughSpecificServers]
|
||||
other = "Ignorar todo, ejecutar solo a través de servidores específicos"
|
||||
|
||||
[AllIncludedOnlySpecificServersAreNotExecuted]
|
||||
other = "Incluir todo, excepto servidores específicos"
|
||||
|
||||
[ExecuteByTriggerServer]
|
||||
other = "Ejecutar en servidores con alarma"
|
||||
|
||||
[SpecificServers]
|
||||
other = "Servidores Específicos"
|
||||
|
||||
[EnterIdAndNameToSearch]
|
||||
other = "Ingrese ID/Nombre para buscar"
|
||||
|
||||
[NotificationMethodGroup]
|
||||
other = "Grupo de Métodos de Notificación"
|
||||
|
||||
[PushSuccessMessages]
|
||||
other = "Enviar el mensaje de éxito"
|
||||
|
||||
[TaskType]
|
||||
other = "Tipo de Tarea"
|
||||
|
||||
[CronTask]
|
||||
other = "Tarea Cron"
|
||||
|
||||
[TriggerTask]
|
||||
other = "Tarea Disparadora"
|
||||
|
||||
[TheFormaOfTheScheduleIs]
|
||||
other = "El formato del plan es:"
|
||||
|
||||
[SecondsMinutesHoursDaysMonthsWeeksSeeDetails]
|
||||
other = "Segundos, Minutos, Horas, Días, Meses, Semanas - Ver detalles a"
|
||||
|
||||
[ScheduleExpressionFormat]
|
||||
other = "Formato de Expresión de Cron"
|
||||
|
||||
[IntroductionOfCommands]
|
||||
other = "Introducción de Comandos: Escriba comandos como en scripts shell/bat. Evite saltos de línea; conecte múltiples comandos con <code>&&</code> o <code>;</code>. Si no se encuentra un comando, verifique la variable de entorno <code>PATH</code>. En servidores <code>Linux</code>, antepóngale <code>source ~/.bashrc</code> a los comandos, o use rutas absolutas."
|
||||
|
||||
[AddMonitor]
|
||||
other = "Agregar Monitor de Servicio"
|
||||
|
||||
[Blog]
|
||||
other = "Blog"
|
||||
|
||||
[Target]
|
||||
other = "Objetivo"
|
||||
|
||||
[Type]
|
||||
other = "Tipo"
|
||||
|
||||
[SslExpirationOrChange]
|
||||
other = "(Expiración o Cambio de SSL)"
|
||||
|
||||
[Duration]
|
||||
other = "Intervalo de Solicitud"
|
||||
|
||||
[Seconds]
|
||||
other = "Segundos"
|
||||
|
||||
[EnableFailureNotification]
|
||||
other = "Habilitar Notificación de Fallo"
|
||||
|
||||
[FailureNotification]
|
||||
other = "Notificación de Fallo"
|
||||
|
||||
[MaxLatency]
|
||||
other = "Máxima Latencia (ms)"
|
||||
|
||||
[MinLatency]
|
||||
other = "Mínima Latencia (ms)"
|
||||
|
||||
[EnableLatencyNotification]
|
||||
other = "Habilitar Notificación de Latencia"
|
||||
|
||||
[LatencyNotification]
|
||||
other = "Notificación de Latencia"
|
||||
|
||||
[IntroductionOfMonitor]
|
||||
other = """
|
||||
Para tipo <b>HTTP-GET</b>, ingrese URL (http/https, HTTPS también monitorea el certificado SSL);<br>
|
||||
Para tipo <b>ICMP-Ping</b>, ingrese dominio/IP sin puerto;<br>
|
||||
Para tipo <b>TCP-Ping</b>, ingrese dominio/IP + puerto: ejemplo.com:22"""
|
||||
|
||||
[AddNotificationMethod]
|
||||
other = "Agregar Método de Notificación"
|
||||
|
||||
[Tag]
|
||||
other = "Grupo de servidores"
|
||||
|
||||
[DoNotSendTestMessages]
|
||||
other = "No Enviar Mensajes de Prueba"
|
||||
|
||||
[RequestMethod]
|
||||
other = "Método de Solicitud"
|
||||
|
||||
[RequestType]
|
||||
other = "Tipo de Solicitud"
|
||||
|
||||
[VerifySSL]
|
||||
other = "Validar SSL"
|
||||
|
||||
[AddNotificationRule]
|
||||
other = "Agregar Regla de Notificación"
|
||||
|
||||
[Rules]
|
||||
other = "Reglas"
|
||||
|
||||
[NotificationTriggerMode]
|
||||
other = "Modo de Disparo de Notificación"
|
||||
|
||||
[ModeAlwaysTrigger]
|
||||
other = "Siempre Activar"
|
||||
|
||||
[ModeOnetimeTrigger]
|
||||
other = "Activación Única"
|
||||
|
||||
[EnableTriggerTask]
|
||||
other = "Habilitar Tarea Disparadora"
|
||||
|
||||
[FailTriggerTasks]
|
||||
other = "Tareas Disparadas por Fallo"
|
||||
|
||||
[RecoverTriggerTasks]
|
||||
other = "Tareas Disparadas por Recuperación"
|
||||
|
||||
[Enable]
|
||||
other = "Habilitar"
|
||||
|
||||
[AddServer]
|
||||
other = "Agregar Servidor"
|
||||
|
||||
[BatchEditServerGroup]
|
||||
other = "Editar Grupo de Servidores en Lote"
|
||||
|
||||
[BatchDeleteServer]
|
||||
other = "Eliminar Servidores en Lote"
|
||||
|
||||
[InputServerGroupName]
|
||||
other = "Ingrese Nombre del Grupo de Servidores"
|
||||
|
||||
[ServerGroup]
|
||||
other = "Grupos de Servidores"
|
||||
|
||||
[EinsteinLightspeed1]
|
||||
other = "Einstein - Velocidad de luz 1"
|
||||
|
||||
[DisplayIndex]
|
||||
other = "Índice de Visualización"
|
||||
|
||||
[TheLargerTheNumberTheHigherThePriority]
|
||||
other = "A mayor número, mayor prioridad"
|
||||
|
||||
[Secret]
|
||||
other = "Secreto"
|
||||
|
||||
[Note]
|
||||
other = "Nota"
|
||||
|
||||
[PublicNote]
|
||||
other = "Nota Pública"
|
||||
|
||||
[LinuxOneKeyInstall]
|
||||
other = "Instalación Linux con Un Solo Clic"
|
||||
|
||||
[NoDomainAlert]
|
||||
other = "Por favor, configure el dominio o IP del servidor del panel que no está conectado a la CDN en la página de configuración"
|
||||
|
||||
[PushSuccessfully]
|
||||
other = "Envío Exitoso"
|
||||
|
||||
[LastExecution]
|
||||
other = "Última Ejecución en"
|
||||
|
||||
[LastResult]
|
||||
other = "Último Resultado"
|
||||
|
||||
[Administration]
|
||||
other = "Administración"
|
||||
|
||||
[CoverAll]
|
||||
other = "Cubrir Todo"
|
||||
|
||||
[IgnoreAll]
|
||||
other = "Ignorar Todo"
|
||||
|
||||
[ByTrigger]
|
||||
other = "Servidores con alarma"
|
||||
|
||||
[DeleteScheduledTask]
|
||||
other = "Eliminar Tarea Programada"
|
||||
|
||||
[ConfirmToDeleteThisScheduledTask]
|
||||
other = "¿Confirmar para eliminar esta Tarea Programada?"
|
||||
|
||||
[AccessDenied]
|
||||
other = "Acceso Denegado"
|
||||
|
||||
[Use]
|
||||
other = "Usar"
|
||||
|
||||
[AccountToLogin]
|
||||
other = "Iniciar Sesión con Cuenta"
|
||||
|
||||
[SignUp]
|
||||
other = "Registrarse"
|
||||
|
||||
[DontHaveAnAccount]
|
||||
other = "¿No tiene una cuenta?"
|
||||
|
||||
[SSLCertificate]
|
||||
other = "Certificados HTTP(S)/SSL"
|
||||
|
||||
[TCPPort]
|
||||
other = "TCPing"
|
||||
|
||||
[DeleteService]
|
||||
other = "Eliminar Servicio"
|
||||
|
||||
[ConfirmToDeleteThisService]
|
||||
other = "¿Confirmar para eliminar este Servicio?"
|
||||
|
||||
[DeleteNotificationMethod]
|
||||
other = "Eliminar Método de Notificación"
|
||||
|
||||
[ConfirmToDeleteThisNotificationMethod]
|
||||
other = "¿Confirmar para eliminar este Método de Notificación?"
|
||||
|
||||
[ForceUpdate]
|
||||
other = "Actualizar Ahora"
|
||||
|
||||
[SelectAll]
|
||||
other = "Seleccionar Todo"
|
||||
|
||||
[VersionNumber]
|
||||
other = "Número de Versión"
|
||||
|
||||
[OneKeyInstall]
|
||||
other = "Instalación con Un Solo Clic"
|
||||
|
||||
[ClickToCopy]
|
||||
other = "Hacer Clic para Copiar"
|
||||
|
||||
[DeleteServer]
|
||||
other = "Eliminar Servidor"
|
||||
|
||||
[ConfirmToDeleteServer]
|
||||
other = "¿Confirmar para eliminar este Servidor?"
|
||||
|
||||
[NoServerSelected]
|
||||
other = "No hay Servidores Seleccionados"
|
||||
|
||||
[ExecutionResults]
|
||||
other = "Resultados de Ejecución"
|
||||
|
||||
[SiteTitle]
|
||||
other = "Título del Sitio"
|
||||
|
||||
[AdministratorList]
|
||||
other = "Lista de Administradores"
|
||||
|
||||
[Theme]
|
||||
other = "Tema de Frontend"
|
||||
|
||||
[CustomCodes]
|
||||
other = "Códigos Personalizados (Incluye style y script)"
|
||||
|
||||
[CustomCodesDashboard]
|
||||
other = "Custom Codes for Dashboard"
|
||||
|
||||
[AccessPassword]
|
||||
other = "Contraseña de Acceso al Frontend"
|
||||
|
||||
[PanelServerDomainAndIP]
|
||||
other = "Dominio/IP del Servidor del Panel sin CDN"
|
||||
|
||||
[IPChangeAlert]
|
||||
other = "Notificación de Cambio de IP"
|
||||
|
||||
[AllIncludedOnlySpecificServersAreNotAlerted]
|
||||
other = "Incluir Todo, Excepto Servidores Específicos"
|
||||
|
||||
[IgnoreAllOnlyAlertSpecificServers]
|
||||
other = "Ignorar Todo, Alertar Solo Servidores Específicos"
|
||||
|
||||
[IgnoreAllRequestOnlyThroughSpecificServers]
|
||||
other = "Ignorar Todo, Solicitar Solo a Través de Servidores Específicos"
|
||||
|
||||
[AllIncludedOnlySpecificServersAreNotRequest]
|
||||
other = "Incluir Todo, Solo Los Servidores Específicos No Solicitan"
|
||||
|
||||
[ServerIDSeparatedByCommas]
|
||||
other = "IDs de Servidores Separados por Comas"
|
||||
|
||||
[IPChangeNotificationTag]
|
||||
other = "Enviar Alerta a Grupo de Notificación Específico"
|
||||
|
||||
[NotificationMessagesDoNotHideIP]
|
||||
other = "Mostrar Dirección IP Completa en Mensajes de Notificación"
|
||||
|
||||
[Save]
|
||||
other = "Guardar"
|
||||
|
||||
[ModifiedSuccessfully]
|
||||
other = "Modificado con Éxito"
|
||||
|
||||
[TerminalConnectionTimeOutOrSessionEnded]
|
||||
other = "Tiempo de Conexión del Terminal Agotado o Sesión Finalizada"
|
||||
|
||||
[TerminalConnectionFailed]
|
||||
other = "Fallo en la Conexión del Terminal, Verifique la Configuración de Proxy Inverso de WebSocket en /terminal/*"
|
||||
|
||||
[Default]
|
||||
other = "Predeterminado"
|
||||
|
||||
[Offline]
|
||||
other = "Desconectado"
|
||||
|
||||
[Platform]
|
||||
other = "Sistema"
|
||||
|
||||
[DiskUsed]
|
||||
other = "Disco"
|
||||
|
||||
[MemUsed]
|
||||
other = "Memoria"
|
||||
|
||||
[CpuUsed]
|
||||
other = "CPU"
|
||||
|
||||
[Virtualization]
|
||||
other = "Virtualización"
|
||||
|
||||
[SwapUsed]
|
||||
other = "Swap"
|
||||
|
||||
[NetTransfer]
|
||||
other = "Transferencia de Red"
|
||||
|
||||
[Load]
|
||||
other = "Carga"
|
||||
|
||||
[ProcessCount]
|
||||
other = "Cantidad de Procesos"
|
||||
|
||||
[ConnCount]
|
||||
other = "Cantidad de Conexiones"
|
||||
|
||||
[BootTime]
|
||||
other = "Tiempo de Arranque"
|
||||
|
||||
[LastActive]
|
||||
other = "Última Actividad"
|
||||
|
||||
[Version]
|
||||
other = "Versión"
|
||||
|
||||
[NetSpeed]
|
||||
other = "Red"
|
||||
|
||||
[Uptime]
|
||||
other = "Uptime"
|
||||
|
||||
[ServerIsOffline]
|
||||
other = "El Servidor está Desconectado"
|
||||
|
||||
[Day]
|
||||
other = "Días"
|
||||
|
||||
[RealtimeChannelEstablished]
|
||||
other = "Canal en Tiempo Real Establecido"
|
||||
|
||||
[GetTheLatestMonitoringDataInRealTime]
|
||||
other = "¡Ahora Puede Obtener los Últimos Datos de Monitoreo en Tiempo Real!"
|
||||
|
||||
[RealtimeChannelDisconnect]
|
||||
other = "Canal en Tiempo Real Desconectado"
|
||||
|
||||
[CanNotGetTheLatestMonitoringDataInRealTime]
|
||||
other = "¡No se Pueden Obtener los Últimos Datos de Monitoreo en Tiempo Real!"
|
||||
|
||||
[30DaysOnline]
|
||||
other = "Disponibilidad de 30 Días"
|
||||
|
||||
[Details]
|
||||
other = "Detalles"
|
||||
|
||||
[Status]
|
||||
other = "Estado"
|
||||
|
||||
[Availability]
|
||||
other = "Disponibilidad"
|
||||
|
||||
[AverageLatency]
|
||||
other = "Latencia Promedio"
|
||||
|
||||
[CycleTransferStats]
|
||||
other = "Estadísticas de Transferencia Periódica"
|
||||
|
||||
[From]
|
||||
other = "Desde"
|
||||
|
||||
[To]
|
||||
other = "Hasta"
|
||||
|
||||
[NextCheck]
|
||||
other = "Próxima Verificación"
|
||||
|
||||
[CurrentUsage]
|
||||
other = "Uso Actual"
|
||||
|
||||
[VerifyPassword]
|
||||
other = "Verificar Contraseña"
|
||||
|
||||
[LightMode]
|
||||
other = "Modo Claro"
|
||||
|
||||
[DarkMode]
|
||||
other = "Modo Oscuro"
|
||||
|
||||
[FollowSystem]
|
||||
other = "Seguir al Sistema"
|
||||
|
||||
[GridLayout]
|
||||
other = "Diseño de Cuadrícula"
|
||||
|
||||
[ListLayout]
|
||||
other = "Diseño de Lista"
|
||||
|
||||
[EnterPassword]
|
||||
other = "Ingrese Contraseña"
|
||||
|
||||
[Location]
|
||||
other = "Ubicación"
|
||||
|
||||
[Running]
|
||||
other = "En Funcionamiento"
|
||||
|
||||
[UpNetTransfer]
|
||||
other = "Red Ascendente"
|
||||
|
||||
[DownNetTransfer]
|
||||
other = "Red Descendente"
|
||||
|
||||
[TotalUpNetTransfer]
|
||||
other = "Total Ascendente"
|
||||
|
||||
[TotalDownNetTransfer]
|
||||
other = "Total Descendente"
|
||||
|
||||
[WrongPassword]
|
||||
other = "Contraseña Incorrecta"
|
||||
|
||||
[AnErrorEccurred]
|
||||
other = "Ocurrió un Error"
|
||||
|
||||
[SystemError]
|
||||
other = "Error del Sistema"
|
||||
|
||||
[NetworkError]
|
||||
other = "Error de Red"
|
||||
|
||||
[ServicesStatus]
|
||||
other = "Estado de los Servicios"
|
||||
|
||||
[ServersManagement]
|
||||
other = "Gestión de Servidores"
|
||||
|
||||
[ServicesManagement]
|
||||
other = "Gestión de Servicios"
|
||||
|
||||
[ScheduledTasks]
|
||||
other = "Tareas Programadas"
|
||||
|
||||
[ApiManagement]
|
||||
other = "Gestión de API"
|
||||
|
||||
[IssueNewApiToken]
|
||||
other = "Emitir Nuevo Token"
|
||||
|
||||
[Token]
|
||||
other = "Token"
|
||||
|
||||
[DeleteToken]
|
||||
other = "Eliminar Token"
|
||||
|
||||
[ConfirmToDeleteThisToken]
|
||||
other = "¿Confirmar para Eliminar este Token?"
|
||||
|
||||
[YouAreNotAuthorized]
|
||||
other = "No Autorizado para esta Página"
|
||||
|
||||
[WrongAccessPassword]
|
||||
other = "Contraseña de Acceso Incorrecta"
|
||||
|
||||
[Add]
|
||||
other = "Agregar"
|
||||
|
||||
[Edit]
|
||||
other = "Editar"
|
||||
|
||||
[AlarmRule]
|
||||
other = "Reglas de Alarma"
|
||||
|
||||
[NotificationMethod]
|
||||
other = "Método de notificación"
|
||||
|
||||
[Incident]
|
||||
other = "Incidente"
|
||||
|
||||
[Resolved]
|
||||
other = "Resuelto"
|
||||
|
||||
[StatusDown]
|
||||
other = "Caído"
|
||||
|
||||
[StatusNoData]
|
||||
other = "Sin Datos"
|
||||
|
||||
[StatusGood]
|
||||
other = "Bueno"
|
||||
|
||||
[StatusLowAvailability]
|
||||
other = "Baja Disponibilidad"
|
||||
|
||||
[ScheduledTaskExecutedSuccessfully]
|
||||
other = "Tarea Programada Ejecutada con Éxito"
|
||||
|
||||
[ScheduledTaskExecutedFailed]
|
||||
other = "Fallo en la Ejecución de la Tarea Programada"
|
||||
|
||||
[IPChanged]
|
||||
other = "Cambio de IP"
|
||||
|
||||
[Transleft]
|
||||
other = "Transferencia Restante"
|
||||
|
||||
[DashboardTheme]
|
||||
other = "Tema del Panel de Administración"
|
||||
|
||||
[Info]
|
||||
other = "Información"
|
||||
|
||||
[HideForGuest]
|
||||
other = "Ocultar para Invitados"
|
||||
|
||||
[Menu]
|
||||
other = "Menú"
|
||||
|
||||
[NetworkSpiter]
|
||||
other = "Red"
|
||||
|
||||
[EnableShowInService]
|
||||
other = "Mostrar en servicio"
|
||||
|
||||
[DDNS]
|
||||
other = "DNS Dinámico"
|
||||
|
||||
[DDNSProfiles]
|
||||
other = "Perfiles DDNS"
|
||||
|
||||
[AddDDNSProfile]
|
||||
other = "Nuevo Perfil"
|
||||
|
||||
[EnableDDNS]
|
||||
other = "Habilitar DDNS"
|
||||
|
||||
[EnableIPv4]
|
||||
other = "IPv4 Activado"
|
||||
|
||||
[EnableIPv6]
|
||||
other = "IPv6 Activado"
|
||||
|
||||
[DDNSDomain]
|
||||
other = "Dominios"
|
||||
|
||||
[DDNSDomains]
|
||||
other = "Dominios (separados por comas)"
|
||||
|
||||
[DDNSProvider]
|
||||
other = "Proveedor DDNS"
|
||||
|
||||
[MaxRetries]
|
||||
other = "Número máximo de intentos de reintento"
|
||||
|
||||
[DDNSAccessID]
|
||||
other = "Credencial 1"
|
||||
|
||||
[DDNSAccessSecret]
|
||||
other = "Credencial 2"
|
||||
|
||||
[DDNSTokenID]
|
||||
other = "ID del Token"
|
||||
|
||||
[DDNSTokenSecret]
|
||||
other = "Secreto del Token"
|
||||
|
||||
[WebhookURL]
|
||||
other = "URL del Webhook"
|
||||
|
||||
[WebhookMethod]
|
||||
other = "Método de Solicitud del Webhook"
|
||||
|
||||
[WebhookRequestType]
|
||||
other = "Tipo de solicitud del Webhook"
|
||||
|
||||
[WebhookHeaders]
|
||||
other = "Encabezados de Solicitud del Webhook"
|
||||
|
||||
[WebhookRequestBody]
|
||||
other = "Cuerpo de Solicitud del Webhook"
|
||||
|
||||
[Feature]
|
||||
other = "Característica"
|
||||
|
||||
[Template]
|
||||
other = "Plantilla"
|
||||
|
||||
[Stat]
|
||||
other = "Stat"
|
||||
|
||||
[Temperature]
|
||||
other = "Temperatura"
|
||||
|
||||
[DisableSwitchTemplateInFrontend]
|
||||
other = "Deshabilitar Cambio de Plantilla en Frontend"
|
||||
|
||||
[ServersOnWorldMap]
|
||||
other = "Servidores en el mapa mundial"
|
||||
|
||||
[NAT]
|
||||
other = "NAT traversal"
|
||||
|
||||
[LocalService]
|
||||
other = "Servicio de red local"
|
||||
|
||||
[LocalServicePlaceholder]
|
||||
other = "192.168.1.1:80 (con puerto)"
|
||||
|
||||
[BindHostname]
|
||||
other = "Vincular nombre de host"
|
||||
|
||||
[NetworkSpiterList]
|
||||
other = "Monitor de red"
|
||||
|
||||
[Refresh]
|
||||
other = "Actualizar"
|
||||
|
||||
[CopyPath]
|
||||
other = "Copiar ruta"
|
||||
|
||||
[Goto]
|
||||
other = "Ir a"
|
||||
|
||||
[GotoHeadline]
|
||||
other = "Ir a una carpeta"
|
||||
|
||||
[GotoGo]
|
||||
other = "Ir"
|
||||
|
||||
[GotoClose]
|
||||
other = "Cancelar"
|
||||
|
||||
[FMError]
|
||||
other = "Agent devolvió un error, consulte la consola para obtener más detalles. Para abrir una nueva conexión, vuelva a abrir el FM."
|
||||
|
||||
[Remaining]
|
||||
other = "Remaining"
|
||||
|
||||
[Lifetime]
|
||||
other = "Lifetime"
|
||||
|
||||
[Price]
|
||||
other = "Price"
|
||||
|
||||
[Expired]
|
||||
other = "Expired"
|
||||
|
||||
[Days]
|
||||
other = "d"
|
||||
|
||||
[CustomNameservers]
|
||||
other = "Servidores DNS públicos personalizados para DDNS (separar con coma)"
|
752
resource/l10n/zh-CN.toml
vendored
@ -1,752 +0,0 @@
|
||||
[NezhaMonitoring]
|
||||
other = "哪吒监控"
|
||||
|
||||
[Server]
|
||||
other = "服务器"
|
||||
|
||||
[Services]
|
||||
other = "服务"
|
||||
|
||||
[Task]
|
||||
other = "任务"
|
||||
|
||||
[Notification]
|
||||
other = "告警"
|
||||
|
||||
[Settings]
|
||||
other = "设置"
|
||||
|
||||
[Home]
|
||||
other = "首页"
|
||||
|
||||
[BackToHomepage]
|
||||
other = "返回前台"
|
||||
|
||||
[AdminPanel]
|
||||
other = "管理后台"
|
||||
|
||||
[Logout]
|
||||
other = "注销登录"
|
||||
|
||||
[Login]
|
||||
other = "登录"
|
||||
|
||||
[ConfirmLogout]
|
||||
other = "确定要注销吗?"
|
||||
|
||||
[AfterLoggingOutYouHaveToLoginAgain]
|
||||
other = "注销后需重新登录以继续使用"
|
||||
|
||||
[Cancel]
|
||||
other = "取消"
|
||||
|
||||
[Confirm]
|
||||
other = "确认"
|
||||
|
||||
[AddScheduledTasks]
|
||||
other = "新增计划任务"
|
||||
|
||||
[Name]
|
||||
other = "名称"
|
||||
|
||||
[Scheduler]
|
||||
other = "计划"
|
||||
|
||||
[BackUp]
|
||||
other = "备份"
|
||||
|
||||
[3amDaily]
|
||||
other = "(每天3点)"
|
||||
|
||||
[Command]
|
||||
other = "命令"
|
||||
|
||||
[Coverage]
|
||||
other = "覆盖范围"
|
||||
|
||||
[IgnoreAllAndExecuteOnlyThroughSpecificServers]
|
||||
other = "忽略所有,仅通过特定服务器执行"
|
||||
|
||||
[AllIncludedOnlySpecificServersAreNotExecuted]
|
||||
other = "覆盖所有,仅特定服务器不执行"
|
||||
|
||||
[ExecuteByTriggerServer]
|
||||
other = "由触发告警的服务器执行"
|
||||
|
||||
[SpecificServers]
|
||||
other = "特定服务器"
|
||||
|
||||
[EnterIdAndNameToSearch]
|
||||
other = "输入ID/名称以搜索"
|
||||
|
||||
[NotificationMethodGroup]
|
||||
other = "通知方式组"
|
||||
|
||||
[PushSuccessMessages]
|
||||
other = "推送成功的消息"
|
||||
|
||||
[TaskType]
|
||||
other = "任务类型"
|
||||
|
||||
[CronTask]
|
||||
other = "计划任务"
|
||||
|
||||
[TriggerTask]
|
||||
other = "触发任务"
|
||||
|
||||
[TheFormaOfTheScheduleIs]
|
||||
other = "计划的格式为:"
|
||||
|
||||
[SecondsMinutesHoursDaysMonthsWeeksSeeDetails]
|
||||
other = "秒 分 时 天 月 星期,详情见"
|
||||
|
||||
[ScheduleExpressionFormat]
|
||||
other = "计划表达式格式"
|
||||
|
||||
[IntroductionOfCommands]
|
||||
other = "命令说明:编写命令时类似于 shell/bat 脚本。建议不要换行,多个命令可用 <code>&&</code> 或 <code>;</code> 连接,若出现命令无法找到的情况,可能是由于 <code>PATH</code> 环境变量配置问题。在 <code>Linux</code> 服务器上,可在命令开头加入 <code>source ~/.bashrc</code>,或使用命令的绝对路径执行。"
|
||||
|
||||
[AddMonitor]
|
||||
other = "新增监控"
|
||||
|
||||
[Blog]
|
||||
other = "博客"
|
||||
|
||||
[Target]
|
||||
other = "目标"
|
||||
|
||||
[Type]
|
||||
other = "类型"
|
||||
|
||||
[SslExpirationOrChange]
|
||||
other = "(SSL到期、变更)"
|
||||
|
||||
[Duration]
|
||||
other = "请求间隔"
|
||||
|
||||
[Seconds]
|
||||
other = "秒"
|
||||
|
||||
[EnableFailureNotification]
|
||||
other = "启用故障通知"
|
||||
|
||||
[FailureNotification]
|
||||
other = "故障通知"
|
||||
|
||||
[MaxLatency]
|
||||
other = "最大延迟(ms)"
|
||||
|
||||
[MinLatency]
|
||||
other = "最小延迟(ms)"
|
||||
|
||||
[EnableLatencyNotification]
|
||||
other = "启用延迟通知"
|
||||
|
||||
[LatencyNotification]
|
||||
other = "延迟通知"
|
||||
|
||||
[IntroductionOfMonitor]
|
||||
other = """
|
||||
类型为 <b>HTTP-GET</b> 时输入URL(带 http/https, HTTPS协议的会顺带监控SSL证书);<br>
|
||||
类型为 <b>ICMP-Ping</b> 时输入域名/IP,不带端口;<br>
|
||||
类型为 <b>TCP-Ping</b> 时输入域名/IP + 端口号:example.com:22"""
|
||||
|
||||
[AddNotificationMethod]
|
||||
other = "新增通知方式"
|
||||
|
||||
[Tag]
|
||||
other = "分组"
|
||||
|
||||
[DoNotSendTestMessages]
|
||||
other = "不发送测试信息"
|
||||
|
||||
[RequestMethod]
|
||||
other = "请求方式"
|
||||
|
||||
[RequestType]
|
||||
other = "请求类型"
|
||||
|
||||
[VerifySSL]
|
||||
other = "验证SSL"
|
||||
|
||||
[AddNotificationRule]
|
||||
other = "新增告警规则"
|
||||
|
||||
[Rules]
|
||||
other = "规则"
|
||||
|
||||
[NotificationTriggerMode]
|
||||
other = "通知触发模式"
|
||||
|
||||
[ModeAlwaysTrigger]
|
||||
other = "始终触发"
|
||||
|
||||
[ModeOnetimeTrigger]
|
||||
other = "单次触发"
|
||||
|
||||
[EnableTriggerTask]
|
||||
other = "启用触发任务"
|
||||
|
||||
[FailTriggerTasks]
|
||||
other = "告警时触发任务"
|
||||
|
||||
[RecoverTriggerTasks]
|
||||
other = "恢复时触发任务"
|
||||
|
||||
[Enable]
|
||||
other = "启用"
|
||||
|
||||
[AddServer]
|
||||
other = "新增服务器"
|
||||
|
||||
[BatchEditServerGroup]
|
||||
other = "批量修改分组"
|
||||
|
||||
[BatchDeleteServer]
|
||||
other = "批量删除服务器"
|
||||
|
||||
[InputServerGroupName]
|
||||
other = "输入分组名称"
|
||||
|
||||
[ServerGroup]
|
||||
other = "服务器分组"
|
||||
|
||||
[EinsteinLightspeed1]
|
||||
other = "爱因斯坦-光速1号"
|
||||
|
||||
[DisplayIndex]
|
||||
other = "排序"
|
||||
|
||||
[TheLargerTheNumberTheHigherThePriority]
|
||||
other = "越大越靠前"
|
||||
|
||||
[Secret]
|
||||
other = "密钥"
|
||||
|
||||
[Note]
|
||||
other = "备注"
|
||||
|
||||
[PublicNote]
|
||||
other = "公开备注"
|
||||
|
||||
[LinuxOneKeyInstall]
|
||||
other = "Linux 一键安装"
|
||||
|
||||
[NoDomainAlert]
|
||||
other = "请先在设置页面配置 未接入CDN的面板服务器域名/IP"
|
||||
|
||||
[PushSuccessfully]
|
||||
other = "推送成功"
|
||||
|
||||
[LastExecution]
|
||||
other = "最近执行"
|
||||
|
||||
[LastResult]
|
||||
other = "最后结果"
|
||||
|
||||
[Administration]
|
||||
other = "管理"
|
||||
|
||||
[CoverAll]
|
||||
other = "覆盖所有"
|
||||
|
||||
[IgnoreAll]
|
||||
other = "忽略所有"
|
||||
|
||||
[ByTrigger]
|
||||
other = "触发告警的服务器"
|
||||
|
||||
[DeleteScheduledTask]
|
||||
other = "删除计划任务"
|
||||
|
||||
[ConfirmToDeleteThisScheduledTask]
|
||||
other = "确认删除此计划任务?"
|
||||
|
||||
[AccessDenied]
|
||||
other = "访问被拒绝"
|
||||
|
||||
[Use]
|
||||
other = "使用"
|
||||
|
||||
[AccountToLogin]
|
||||
other = "账号登录"
|
||||
|
||||
[SignUp]
|
||||
other = "注册"
|
||||
|
||||
[DontHaveAnAccount]
|
||||
other = "没有账号?"
|
||||
|
||||
[SSLCertificate]
|
||||
other = "HTTP(S)/SSL证书"
|
||||
|
||||
[TCPPort]
|
||||
other = "TCPing"
|
||||
|
||||
[DeleteService]
|
||||
other = "移除服务"
|
||||
|
||||
[ConfirmToDeleteThisService]
|
||||
other = "确认删除此服务?"
|
||||
|
||||
[DeleteNotificationMethod]
|
||||
other = "删除通知方式"
|
||||
|
||||
[ConfirmToDeleteThisNotificationMethod]
|
||||
other = "确认删除此通知方式?"
|
||||
|
||||
[ForceUpdate]
|
||||
other = "立即更新"
|
||||
|
||||
[SelectAll]
|
||||
other = "全选"
|
||||
|
||||
[VersionNumber]
|
||||
other = "版本号"
|
||||
|
||||
[OneKeyInstall]
|
||||
other = "一键安装"
|
||||
|
||||
[ClickToCopy]
|
||||
other = "点击复制"
|
||||
|
||||
[DeleteServer]
|
||||
other = "删除服务器"
|
||||
|
||||
[ConfirmToDeleteServer]
|
||||
other = "确认删除服务器?"
|
||||
|
||||
[NoServerSelected]
|
||||
other = "当前没有选中的服务器"
|
||||
|
||||
[ExecutionResults]
|
||||
other = "执行结果"
|
||||
|
||||
[SiteTitle]
|
||||
other = "网站标题"
|
||||
|
||||
[AdministratorList]
|
||||
other = "管理员列表"
|
||||
|
||||
[Theme]
|
||||
other = "前台界面主题"
|
||||
|
||||
[CustomCodes]
|
||||
other = "自定义代码(包括 style 和 script)"
|
||||
|
||||
[CustomCodesDashboard]
|
||||
other = "Custom Codes for Dashboard"
|
||||
|
||||
[AccessPassword]
|
||||
other = "前台访问密码"
|
||||
|
||||
[PanelServerDomainAndIP]
|
||||
other = "未接入CDN的面板服务器域名/IP"
|
||||
|
||||
[IPChangeAlert]
|
||||
other = "IP 变动通知"
|
||||
|
||||
[AllIncludedOnlySpecificServersAreNotAlerted]
|
||||
other = "覆盖所有,仅特定服务器不提醒"
|
||||
|
||||
[IgnoreAllOnlyAlertSpecificServers]
|
||||
other = "忽略所有,仅提醒特定服务器"
|
||||
|
||||
[IgnoreAllRequestOnlyThroughSpecificServers]
|
||||
other = "忽略所有,仅通过特定服务器请求"
|
||||
|
||||
[AllIncludedOnlySpecificServersAreNotRequest]
|
||||
other = "覆盖所有,仅特定服务器不请求"
|
||||
|
||||
[ServerIDSeparatedByCommas]
|
||||
other = "服务器ID 以逗号隔开"
|
||||
|
||||
[IPChangeNotificationTag]
|
||||
other = "将提醒发送至指定通知分组"
|
||||
|
||||
[NotificationMessagesDoNotHideIP]
|
||||
other = "通知信息中显示完整IP地址"
|
||||
|
||||
[Save]
|
||||
other = "保存"
|
||||
|
||||
[ModifiedSuccessfully]
|
||||
other = "修改成功"
|
||||
|
||||
[TerminalConnectionTimeOutOrSessionEnded]
|
||||
other = "Terminal 连接超时或会话已结束"
|
||||
|
||||
[TerminalConnectionFailed]
|
||||
other = "Terminal 连接失败,请检查 /terminal/* 的 WebSocket 反向代理配置"
|
||||
|
||||
[Default]
|
||||
other = "默认"
|
||||
|
||||
[Offline]
|
||||
other = "已离线"
|
||||
|
||||
[Platform]
|
||||
other = "系统"
|
||||
|
||||
[DiskUsed]
|
||||
other = "硬盘"
|
||||
|
||||
[MemUsed]
|
||||
other = "内存"
|
||||
|
||||
[CpuUsed]
|
||||
other = "核心"
|
||||
|
||||
[Virtualization]
|
||||
other = "虚拟化"
|
||||
|
||||
[SwapUsed]
|
||||
other = "交换"
|
||||
|
||||
[NetTransfer]
|
||||
other = "流量"
|
||||
|
||||
[Load]
|
||||
other = "负载"
|
||||
|
||||
[ProcessCount]
|
||||
other = "进程数"
|
||||
|
||||
[ConnCount]
|
||||
other = "连接数"
|
||||
|
||||
[BootTime]
|
||||
other = "启动"
|
||||
|
||||
[LastActive]
|
||||
other = "活动"
|
||||
|
||||
[Version]
|
||||
other = "版本"
|
||||
|
||||
[NetSpeed]
|
||||
other = "网速"
|
||||
|
||||
[Uptime]
|
||||
other = "在线"
|
||||
|
||||
[ServerIsOffline]
|
||||
other = "服务器已离线"
|
||||
|
||||
[Day]
|
||||
other = "天"
|
||||
|
||||
[RealtimeChannelEstablished]
|
||||
other = "实时通道已建立"
|
||||
|
||||
[GetTheLatestMonitoringDataInRealTime]
|
||||
other = "可以实时获取最新监控数据啦"
|
||||
|
||||
[RealtimeChannelDisconnect]
|
||||
other = "实时通道已断开"
|
||||
|
||||
[CanNotGetTheLatestMonitoringDataInRealTime]
|
||||
other = "无法实时获取最新监控数据咯"
|
||||
|
||||
[30DaysOnline]
|
||||
other = "近30天可用性"
|
||||
|
||||
[Details]
|
||||
other = "详情"
|
||||
|
||||
[Status]
|
||||
other = "状态"
|
||||
|
||||
[Availability]
|
||||
other = "可用性"
|
||||
|
||||
[AverageLatency]
|
||||
other = "平均响应时间"
|
||||
|
||||
[CycleTransferStats]
|
||||
other = "周期性流量统计"
|
||||
|
||||
[From]
|
||||
other = "起始"
|
||||
|
||||
[To]
|
||||
other = "结束"
|
||||
|
||||
[NextCheck]
|
||||
other = "下一次检测"
|
||||
|
||||
[CurrentUsage]
|
||||
other = "当前用量"
|
||||
|
||||
[VerifyPassword]
|
||||
other = "验证查看密码"
|
||||
|
||||
[LightMode]
|
||||
other = "亮色模式"
|
||||
|
||||
[DarkMode]
|
||||
other = "暗色模式"
|
||||
|
||||
[FollowSystem]
|
||||
other = "跟随系统"
|
||||
|
||||
[GridLayout]
|
||||
other = "网格布局"
|
||||
|
||||
[ListLayout]
|
||||
other = "列表布局"
|
||||
|
||||
[EnterPassword]
|
||||
other = "请输入密码"
|
||||
|
||||
[Location]
|
||||
other = "位置"
|
||||
|
||||
[Running]
|
||||
other = "运行中"
|
||||
|
||||
[UpNetTransfer]
|
||||
other = "上行"
|
||||
|
||||
[DownNetTransfer]
|
||||
other = "下行"
|
||||
|
||||
[TotalUpNetTransfer]
|
||||
other = "总上行"
|
||||
|
||||
[TotalDownNetTransfer]
|
||||
other = "总下行"
|
||||
|
||||
[WrongPassword]
|
||||
other = "输入的密码错误"
|
||||
|
||||
[AnErrorEccurred]
|
||||
other = "发生错误"
|
||||
|
||||
[SystemError]
|
||||
other = "系统错误"
|
||||
|
||||
[NetworkError]
|
||||
other = "网络错误"
|
||||
|
||||
[ServicesStatus]
|
||||
other = "服务状态"
|
||||
|
||||
[ServersManagement]
|
||||
other = "服务器管理"
|
||||
|
||||
[ServicesManagement]
|
||||
other = "服务监控"
|
||||
|
||||
[ScheduledTasks]
|
||||
other = "计划任务"
|
||||
|
||||
[ApiManagement]
|
||||
other = "API 管理"
|
||||
|
||||
[IssueNewApiToken]
|
||||
other = "生成Token"
|
||||
|
||||
[Token]
|
||||
other = "Token"
|
||||
|
||||
[DeleteToken]
|
||||
other = "删除Token"
|
||||
|
||||
[ConfirmToDeleteThisToken]
|
||||
other = "确认删除Token"
|
||||
|
||||
[YouAreNotAuthorized]
|
||||
other = "此页面需要登录"
|
||||
|
||||
[WrongAccessPassword]
|
||||
other = "访问密码错误"
|
||||
|
||||
[Add]
|
||||
other = "新增"
|
||||
|
||||
[Edit]
|
||||
other = "修改"
|
||||
|
||||
[AlarmRule]
|
||||
other = "告警规则"
|
||||
|
||||
[NotificationMethod]
|
||||
other = "通知方式"
|
||||
|
||||
[Incident]
|
||||
other = "事件"
|
||||
|
||||
[Resolved]
|
||||
other = "恢复"
|
||||
|
||||
[StatusDown]
|
||||
other = "故障"
|
||||
|
||||
[StatusNoData]
|
||||
other = "无数据"
|
||||
|
||||
[StatusGood]
|
||||
other = "正常"
|
||||
|
||||
[StatusLowAvailability]
|
||||
other = "低可用"
|
||||
|
||||
[ScheduledTaskExecutedSuccessfully]
|
||||
other = "任务执行成功"
|
||||
|
||||
[ScheduledTaskExecutedFailed]
|
||||
other = "任务执行失败"
|
||||
|
||||
[IPChanged]
|
||||
other = "IP变更"
|
||||
|
||||
[Transleft]
|
||||
other = "剩余流量"
|
||||
|
||||
[DashboardTheme]
|
||||
other = "后台界面主题"
|
||||
|
||||
[Info]
|
||||
other = "信息"
|
||||
|
||||
[HideForGuest]
|
||||
other = "对游客隐藏"
|
||||
|
||||
[Menu]
|
||||
other = "菜单"
|
||||
|
||||
[NetworkSpiter]
|
||||
other = "网络"
|
||||
|
||||
[EnableShowInService]
|
||||
other = "在服务中显示"
|
||||
|
||||
[DDNS]
|
||||
other = "动态 DNS"
|
||||
|
||||
[DDNSProfiles]
|
||||
other = "DDNS配置"
|
||||
|
||||
[AddDDNSProfile]
|
||||
other = "新配置"
|
||||
|
||||
[EnableDDNS]
|
||||
other = "启用 DDNS"
|
||||
|
||||
[EnableIPv4]
|
||||
other = "启用 DDNS IPv4"
|
||||
|
||||
[EnableIPv6]
|
||||
other = "启用 DDNS IPv6"
|
||||
|
||||
[DDNSDomain]
|
||||
other = "DDNS 域名"
|
||||
|
||||
[DDNSDomains]
|
||||
other = "域名(逗号分隔)"
|
||||
|
||||
[DDNSProvider]
|
||||
other = "DDNS 供应商"
|
||||
|
||||
[MaxRetries]
|
||||
other = "最大重试次数"
|
||||
|
||||
[DDNSAccessID]
|
||||
other = "DDNS 凭据 1"
|
||||
|
||||
[DDNSAccessSecret]
|
||||
other = "DDNS 凭据 2"
|
||||
|
||||
[DDNSTokenID]
|
||||
other = "令牌 ID"
|
||||
|
||||
[DDNSTokenSecret]
|
||||
other = "令牌 Secret"
|
||||
|
||||
[WebhookURL]
|
||||
other = "Webhook 地址"
|
||||
|
||||
[WebhookMethod]
|
||||
other = "Webhook 请求方式"
|
||||
|
||||
[WebhookRequestType]
|
||||
other = "Webhook 请求类型"
|
||||
|
||||
[WebhookHeaders]
|
||||
other = "Webhook 请求头"
|
||||
|
||||
[WebhookRequestBody]
|
||||
other = "Webhook 请求体"
|
||||
|
||||
[Feature]
|
||||
other = "功能"
|
||||
|
||||
[Template]
|
||||
other = "主题"
|
||||
|
||||
[Stat]
|
||||
other = "信息"
|
||||
|
||||
[Temperature]
|
||||
other = "温度"
|
||||
|
||||
[DisableSwitchTemplateInFrontend]
|
||||
other = "禁止前台切换模板"
|
||||
|
||||
[ServersOnWorldMap]
|
||||
other = "服务器世界分布图"
|
||||
|
||||
[NAT]
|
||||
other = "内网穿透"
|
||||
|
||||
[LocalService]
|
||||
other = "内网服务"
|
||||
|
||||
[LocalServicePlaceholder]
|
||||
other = "192.168.1.1:80(带端口)"
|
||||
|
||||
[BindHostname]
|
||||
other = "绑定域名"
|
||||
|
||||
[NetworkSpiterList]
|
||||
other = "网络监控"
|
||||
|
||||
[Refresh]
|
||||
other = "刷新"
|
||||
|
||||
[CopyPath]
|
||||
other = "复制路径"
|
||||
|
||||
[Goto]
|
||||
other = "跳往"
|
||||
|
||||
[GotoHeadline]
|
||||
other = "跳往文件夹"
|
||||
|
||||
[GotoGo]
|
||||
other = "确认"
|
||||
|
||||
[GotoClose]
|
||||
other = "取消"
|
||||
|
||||
[FMError]
|
||||
other = "Agent 返回了错误,请查看控制台获取详细信息。要建立新连接,请重新打开 FM。"
|
||||
|
||||
[Remaining]
|
||||
other = "剩余"
|
||||
|
||||
[Lifetime]
|
||||
other = "永续"
|
||||
|
||||
[Price]
|
||||
other = "价格"
|
||||
|
||||
[Expired]
|
||||
other = "已到期"
|
||||
|
||||
[Days]
|
||||
other = "天"
|
||||
|
||||
[CustomNameservers]
|
||||
other = "自定义DDNS使用的公共DNS服务器(逗号分隔)"
|
752
resource/l10n/zh-TW.toml
vendored
@ -1,752 +0,0 @@
|
||||
[NezhaMonitoring]
|
||||
other = "哪吒監控"
|
||||
|
||||
[Server]
|
||||
other = "伺服器"
|
||||
|
||||
[Services]
|
||||
other = "服務"
|
||||
|
||||
[Task]
|
||||
other = "任務"
|
||||
|
||||
[Notification]
|
||||
other = "告警"
|
||||
|
||||
[Settings]
|
||||
other = "設置"
|
||||
|
||||
[Home]
|
||||
other = "首頁"
|
||||
|
||||
[BackToHomepage]
|
||||
other = "返回前台"
|
||||
|
||||
[AdminPanel]
|
||||
other = "管理後台"
|
||||
|
||||
[Logout]
|
||||
other = "登出"
|
||||
|
||||
[Login]
|
||||
other = "登入"
|
||||
|
||||
[ConfirmLogout]
|
||||
other = "確定要登出嗎?"
|
||||
|
||||
[AfterLoggingOutYouHaveToLoginAgain]
|
||||
other = "登出後需重新登入以繼續使用"
|
||||
|
||||
[Cancel]
|
||||
other = "取消"
|
||||
|
||||
[Confirm]
|
||||
other = "確認"
|
||||
|
||||
[AddScheduledTasks]
|
||||
other = "新增計劃任務"
|
||||
|
||||
[Name]
|
||||
other = "名稱"
|
||||
|
||||
[Scheduler]
|
||||
other = "排程"
|
||||
|
||||
[BackUp]
|
||||
other = "備份"
|
||||
|
||||
[3amDaily]
|
||||
other = "(每天3點)"
|
||||
|
||||
[Command]
|
||||
other = "命令"
|
||||
|
||||
[Coverage]
|
||||
other = "覆蓋範圍"
|
||||
|
||||
[IgnoreAllAndExecuteOnlyThroughSpecificServers]
|
||||
other = "忽略所有,僅通過特定伺服器執行"
|
||||
|
||||
[AllIncludedOnlySpecificServersAreNotExecuted]
|
||||
other = "覆蓋所有,僅特定伺服器不執行"
|
||||
|
||||
[ExecuteByTriggerServer]
|
||||
other = "由觸發告警的伺服器執行"
|
||||
|
||||
[SpecificServers]
|
||||
other = "特定伺服器"
|
||||
|
||||
[EnterIdAndNameToSearch]
|
||||
other = "輸入ID/名稱以搜尋"
|
||||
|
||||
[NotificationMethodGroup]
|
||||
other = "通知群組"
|
||||
|
||||
[PushSuccessMessages]
|
||||
other = "推送成功的訊息"
|
||||
|
||||
[TaskType]
|
||||
other = "任務類型"
|
||||
|
||||
[CronTask]
|
||||
other = "排程任務"
|
||||
|
||||
[TriggerTask]
|
||||
other = "觸發任務"
|
||||
|
||||
[TheFormaOfTheScheduleIs]
|
||||
other = "排程的格式為:"
|
||||
|
||||
[SecondsMinutesHoursDaysMonthsWeeksSeeDetails]
|
||||
other = "秒 分 時 天 月 星期,詳情見"
|
||||
|
||||
[ScheduleExpressionFormat]
|
||||
other = "排程表達式格式"
|
||||
|
||||
[IntroductionOfCommands]
|
||||
other = "命令說明:編寫命令時類似於 shell/bat 腳本。建議不要換行,多個命令可用 <code>&&</code> 或 <code>;</code> 連接,若出現命令無法找到的情況,可能是由於 <code>PATH</code> 環境變數配置問題。在 <code>Linux</code> 伺服器上,可在命令開頭加入 <code>source ~/.bashrc</code>,或使用命令的絕對路徑執行。"
|
||||
|
||||
[AddMonitor]
|
||||
other = "新增監控"
|
||||
|
||||
[Blog]
|
||||
other = "部落格"
|
||||
|
||||
[Target]
|
||||
other = "目標"
|
||||
|
||||
[Type]
|
||||
other = "類型"
|
||||
|
||||
[SslExpirationOrChange]
|
||||
other = "(SSL到期、變更)"
|
||||
|
||||
[Duration]
|
||||
other = "請求間隔"
|
||||
|
||||
[Seconds]
|
||||
other = "秒"
|
||||
|
||||
[EnableFailureNotification]
|
||||
other = "啟用故障通知"
|
||||
|
||||
[FailureNotification]
|
||||
other = "故障通知"
|
||||
|
||||
[MaxLatency]
|
||||
other = "最大延遲(ms)"
|
||||
|
||||
[MinLatency]
|
||||
other = "最小延遲(ms)"
|
||||
|
||||
[EnableLatencyNotification]
|
||||
other = "啟用延遲通知"
|
||||
|
||||
[LatencyNotification]
|
||||
other = "延遲通知"
|
||||
|
||||
[IntroductionOfMonitor]
|
||||
other = """
|
||||
類型為 <b>HTTP-GET</b> 時輸入URL(帶 http/https, HTTPS協議的會順帶監控SSL證書);<br>
|
||||
類型為 <b>ICMP-Ping</b> 時輸入域名/IP,不帶端口;<br>
|
||||
類型為 <b>TCP-Ping</b> 時輸入域名/IP + 端口號:example.com:22"""
|
||||
|
||||
[AddNotificationMethod]
|
||||
other = "新增通知方式"
|
||||
|
||||
[Tag]
|
||||
other = "分組"
|
||||
|
||||
[DoNotSendTestMessages]
|
||||
other = "不發送測試訊息"
|
||||
|
||||
[RequestMethod]
|
||||
other = "請求方式"
|
||||
|
||||
[RequestType]
|
||||
other = "請求類型"
|
||||
|
||||
[VerifySSL]
|
||||
other = "驗證SSL"
|
||||
|
||||
[AddNotificationRule]
|
||||
other = "新增告警規則"
|
||||
|
||||
[Rules]
|
||||
other = "規則"
|
||||
|
||||
[NotificationTriggerMode]
|
||||
other = "通知觸發模式"
|
||||
|
||||
[ModeAlwaysTrigger]
|
||||
other = "始終觸發"
|
||||
|
||||
[ModeOnetimeTrigger]
|
||||
other = "單次觸發"
|
||||
|
||||
[EnableTriggerTask]
|
||||
other = "啟用觸發任務"
|
||||
|
||||
[FailTriggerTasks]
|
||||
other = "告警時觸發任務"
|
||||
|
||||
[RecoverTriggerTasks]
|
||||
other = "恢復時觸發任務"
|
||||
|
||||
[Enable]
|
||||
other = "啟用"
|
||||
|
||||
[AddServer]
|
||||
other = "新增伺服器"
|
||||
|
||||
[BatchEditServerGroup]
|
||||
other = "批量修改分組"
|
||||
|
||||
[BatchDeleteServer]
|
||||
other = "批量刪除伺服器"
|
||||
|
||||
[InputServerGroupName]
|
||||
other = "輸入分組名稱"
|
||||
|
||||
[ServerGroup]
|
||||
other = "伺服器分組"
|
||||
|
||||
[EinsteinLightspeed1]
|
||||
other = "愛因斯坦-光速1號"
|
||||
|
||||
[DisplayIndex]
|
||||
other = "排序"
|
||||
|
||||
[TheLargerTheNumberTheHigherThePriority]
|
||||
other = "越大越靠前"
|
||||
|
||||
[Secret]
|
||||
other = "金鑰"
|
||||
|
||||
[Note]
|
||||
other = "備註"
|
||||
|
||||
[PublicNote]
|
||||
other = "公開備註"
|
||||
|
||||
[LinuxOneKeyInstall]
|
||||
other = "Linux 一鍵安裝"
|
||||
|
||||
[NoDomainAlert]
|
||||
other = "請先在設置頁面配置 未接入CDN的面板伺服器域名/IP"
|
||||
|
||||
[PushSuccessfully]
|
||||
other = "推送成功"
|
||||
|
||||
[LastExecution]
|
||||
other = "最近執行"
|
||||
|
||||
[LastResult]
|
||||
other = "最後結果"
|
||||
|
||||
[Administration]
|
||||
other = "管理"
|
||||
|
||||
[CoverAll]
|
||||
other = "覆蓋所有"
|
||||
|
||||
[IgnoreAll]
|
||||
other = "忽略所有"
|
||||
|
||||
[ByTrigger]
|
||||
other = "觸發告警的伺服器"
|
||||
|
||||
[DeleteScheduledTask]
|
||||
other = "刪除排程任務"
|
||||
|
||||
[ConfirmToDeleteThisScheduledTask]
|
||||
other = "確認刪除此排程任務?"
|
||||
|
||||
[AccessDenied]
|
||||
other = "訪問被拒絕"
|
||||
|
||||
[Use]
|
||||
other = "使用"
|
||||
|
||||
[AccountToLogin]
|
||||
other = "帳號登入"
|
||||
|
||||
[SignUp]
|
||||
other = "註冊"
|
||||
|
||||
[DontHaveAnAccount]
|
||||
other = "沒有帳號?"
|
||||
|
||||
[SSLCertificate]
|
||||
other = "HTTP(S)/SSL證書"
|
||||
|
||||
[TCPPort]
|
||||
other = "TCPing"
|
||||
|
||||
[DeleteService]
|
||||
other = "移除服務"
|
||||
|
||||
[ConfirmToDeleteThisService]
|
||||
other = "確認刪除此服務?"
|
||||
|
||||
[DeleteNotificationMethod]
|
||||
other = "刪除通知方式"
|
||||
|
||||
[ConfirmToDeleteThisNotificationMethod]
|
||||
other = "確認刪除此通知方式?"
|
||||
|
||||
[ForceUpdate]
|
||||
other = "立即更新"
|
||||
|
||||
[SelectAll]
|
||||
other = "全選"
|
||||
|
||||
[VersionNumber]
|
||||
other = "版本號"
|
||||
|
||||
[OneKeyInstall]
|
||||
other = "一鍵安裝"
|
||||
|
||||
[ClickToCopy]
|
||||
other = "點擊複製"
|
||||
|
||||
[DeleteServer]
|
||||
other = "刪除伺服器"
|
||||
|
||||
[ConfirmToDeleteServer]
|
||||
other = "確認刪除伺服器?"
|
||||
|
||||
[NoServerSelected]
|
||||
other = "當前沒有選中的伺服器"
|
||||
|
||||
[ExecutionResults]
|
||||
other = "執行結果"
|
||||
|
||||
[SiteTitle]
|
||||
other = "網站標題"
|
||||
|
||||
[AdministratorList]
|
||||
other = "管理員列表"
|
||||
|
||||
[Theme]
|
||||
other = "前台界面主題"
|
||||
|
||||
[CustomCodes]
|
||||
other = "自定義代碼(包括 style 和 script)"
|
||||
|
||||
[CustomCodesDashboard]
|
||||
other = "Custom Codes for Dashboard"
|
||||
|
||||
[AccessPassword]
|
||||
other = "前台訪問密碼"
|
||||
|
||||
[PanelServerDomainAndIP]
|
||||
other = "未接入CDN的面板伺服器域名/IP"
|
||||
|
||||
[IPChangeAlert]
|
||||
other = "IP 變動通知"
|
||||
|
||||
[AllIncludedOnlySpecificServersAreNotAlerted]
|
||||
other = "覆蓋所有,僅特定伺服器不提醒"
|
||||
|
||||
[IgnoreAllOnlyAlertSpecificServers]
|
||||
other = "忽略所有,僅提醒特定伺服器"
|
||||
|
||||
[IgnoreAllRequestOnlyThroughSpecificServers]
|
||||
other = "忽略所有,僅通過特定伺服器請求"
|
||||
|
||||
[AllIncludedOnlySpecificServersAreNotRequest]
|
||||
other = "覆蓋所有,僅特定伺服器不請求"
|
||||
|
||||
[ServerIDSeparatedByCommas]
|
||||
other = "伺服器ID 以逗號隔開"
|
||||
|
||||
[IPChangeNotificationTag]
|
||||
other = "將提醒發送至指定通知分組"
|
||||
|
||||
[NotificationMessagesDoNotHideIP]
|
||||
other = "通知信息中顯示完整IP地址"
|
||||
|
||||
[Save]
|
||||
other = "保存"
|
||||
|
||||
[ModifiedSuccessfully]
|
||||
other = "修改成功"
|
||||
|
||||
[TerminalConnectionTimeOutOrSessionEnded]
|
||||
other = "Terminal 連接超時或會話已結束"
|
||||
|
||||
[TerminalConnectionFailed]
|
||||
other = "Terminal 連接失敗,請檢查 /terminal/* 的 WebSocket 反向代理配置"
|
||||
|
||||
[Default]
|
||||
other = "默認"
|
||||
|
||||
[Offline]
|
||||
other = "已離線"
|
||||
|
||||
[Platform]
|
||||
other = "系統"
|
||||
|
||||
[DiskUsed]
|
||||
other = "硬碟"
|
||||
|
||||
[MemUsed]
|
||||
other = "記憶體"
|
||||
|
||||
[CpuUsed]
|
||||
other = "核心"
|
||||
|
||||
[Virtualization]
|
||||
other = "虛擬化"
|
||||
|
||||
[SwapUsed]
|
||||
other = "交換"
|
||||
|
||||
[NetTransfer]
|
||||
other = "流量"
|
||||
|
||||
[Load]
|
||||
other = "負載"
|
||||
|
||||
[ProcessCount]
|
||||
other = "行程數"
|
||||
|
||||
[ConnCount]
|
||||
other = "連接數"
|
||||
|
||||
[BootTime]
|
||||
other = "啟動"
|
||||
|
||||
[LastActive]
|
||||
other = "活動"
|
||||
|
||||
[Version]
|
||||
other = "版本"
|
||||
|
||||
[NetSpeed]
|
||||
other = "網速"
|
||||
|
||||
[Uptime]
|
||||
other = "在線"
|
||||
|
||||
[ServerIsOffline]
|
||||
other = "伺服器已離線"
|
||||
|
||||
[Day]
|
||||
other = "天"
|
||||
|
||||
[RealtimeChannelEstablished]
|
||||
other = "實時通道已建立"
|
||||
|
||||
[GetTheLatestMonitoringDataInRealTime]
|
||||
other = "可以實時獲取最新監控數據啦"
|
||||
|
||||
[RealtimeChannelDisconnect]
|
||||
other = "實時通道已斷開"
|
||||
|
||||
[CanNotGetTheLatestMonitoringDataInRealTime]
|
||||
other = "無法實時獲取最新監控數據咯"
|
||||
|
||||
[30DaysOnline]
|
||||
other = "近30天可用性"
|
||||
|
||||
[Details]
|
||||
other = "詳情"
|
||||
|
||||
[Status]
|
||||
other = "狀態"
|
||||
|
||||
[Availability]
|
||||
other = "可用性"
|
||||
|
||||
[AverageLatency]
|
||||
other = "平均回應時間"
|
||||
|
||||
[CycleTransferStats]
|
||||
other = "周期性流量統計"
|
||||
|
||||
[From]
|
||||
other = "起始"
|
||||
|
||||
[To]
|
||||
other = "結束"
|
||||
|
||||
[NextCheck]
|
||||
other = "下一次檢測"
|
||||
|
||||
[CurrentUsage]
|
||||
other = "當前用量"
|
||||
|
||||
[VerifyPassword]
|
||||
other = "驗證查看密碼"
|
||||
|
||||
[LightMode]
|
||||
other = "亮色模式"
|
||||
|
||||
[DarkMode]
|
||||
other = "暗色模式"
|
||||
|
||||
[FollowSystem]
|
||||
other = "跟隨系統"
|
||||
|
||||
[GridLayout]
|
||||
other = "網格佈局"
|
||||
|
||||
[ListLayout]
|
||||
other = "列表佈局"
|
||||
|
||||
[EnterPassword]
|
||||
other = "請輸入密碼"
|
||||
|
||||
[Location]
|
||||
other = "位置"
|
||||
|
||||
[Running]
|
||||
other = "運行中"
|
||||
|
||||
[UpNetTransfer]
|
||||
other = "上行"
|
||||
|
||||
[DownNetTransfer]
|
||||
other = "下行"
|
||||
|
||||
[TotalUpNetTransfer]
|
||||
other = "總上行"
|
||||
|
||||
[TotalDownNetTransfer]
|
||||
other = "總下行"
|
||||
|
||||
[WrongPassword]
|
||||
other = "輸入的密碼錯誤"
|
||||
|
||||
[AnErrorEccurred]
|
||||
other = "發生錯誤"
|
||||
|
||||
[SystemError]
|
||||
other = "系統錯誤"
|
||||
|
||||
[NetworkError]
|
||||
other = "網路錯誤"
|
||||
|
||||
[ServicesStatus]
|
||||
other = "服務狀態"
|
||||
|
||||
[ServersManagement]
|
||||
other = "伺服器管理"
|
||||
|
||||
[ServicesManagement]
|
||||
other = "服務監控"
|
||||
|
||||
[ScheduledTasks]
|
||||
other = "排程任務"
|
||||
|
||||
[ApiManagement]
|
||||
other = "API 管理"
|
||||
|
||||
[IssueNewApiToken]
|
||||
other = "生成Token"
|
||||
|
||||
[Token]
|
||||
other = "Token"
|
||||
|
||||
[DeleteToken]
|
||||
other = "刪除Token"
|
||||
|
||||
[ConfirmToDeleteThisToken]
|
||||
other = "確認刪除Token"
|
||||
|
||||
[YouAreNotAuthorized]
|
||||
other = "此頁面需要登入"
|
||||
|
||||
[WrongAccessPassword]
|
||||
other = "訪問密碼錯誤"
|
||||
|
||||
[Add]
|
||||
other = "新增"
|
||||
|
||||
[Edit]
|
||||
other = "修改"
|
||||
|
||||
[AlarmRule]
|
||||
other = "告警規則"
|
||||
|
||||
[NotificationMethod]
|
||||
other = "通知方式"
|
||||
|
||||
[Incident]
|
||||
other = "事件"
|
||||
|
||||
[Resolved]
|
||||
other = "恢復"
|
||||
|
||||
[StatusDown]
|
||||
other = "故障"
|
||||
|
||||
[StatusNoData]
|
||||
other = "無數據"
|
||||
|
||||
[StatusGood]
|
||||
other = "正常"
|
||||
|
||||
[StatusLowAvailability]
|
||||
other = "低可用"
|
||||
|
||||
[ScheduledTaskExecutedSuccessfully]
|
||||
other = "任務執行成功"
|
||||
|
||||
[ScheduledTaskExecutedFailed]
|
||||
other = "任務執行失敗"
|
||||
|
||||
[IPChanged]
|
||||
other = "IP變更"
|
||||
|
||||
[Transleft]
|
||||
other = "剩餘流量"
|
||||
|
||||
[DashboardTheme]
|
||||
other = "後台界面主題"
|
||||
|
||||
[Info]
|
||||
other = "信息"
|
||||
|
||||
[HideForGuest]
|
||||
other = "對遊客隱藏"
|
||||
|
||||
[Menu]
|
||||
other = "菜單"
|
||||
|
||||
[NetworkSpiter]
|
||||
other = "網路"
|
||||
|
||||
[EnableShowInService]
|
||||
other = "在服務中顯示"
|
||||
|
||||
[DDNS]
|
||||
other = "動態 DNS"
|
||||
|
||||
[DDNSProfiles]
|
||||
other = "DDNS配置"
|
||||
|
||||
[AddDDNSProfile]
|
||||
other = "新增配置"
|
||||
|
||||
[EnableDDNS]
|
||||
other = "啟用 DDNS"
|
||||
|
||||
[EnableIPv4]
|
||||
other = "啟用 DDNS IPv4"
|
||||
|
||||
[EnableIPv6]
|
||||
other = "啟用 DDNS IPv6"
|
||||
|
||||
[DDNSDomain]
|
||||
other = "DDNS 域名"
|
||||
|
||||
[DDNSDomains]
|
||||
other = "域名(逗號分隔)"
|
||||
|
||||
[DDNSProvider]
|
||||
other = "DDN S供應商"
|
||||
|
||||
[MaxRetries]
|
||||
other = "最大重試次數"
|
||||
|
||||
[DDNSAccessID]
|
||||
other = "DDNS 憑據 1"
|
||||
|
||||
[DDNSAccessSecret]
|
||||
other = "DDNS 憑據 2"
|
||||
|
||||
[DDNSTokenID]
|
||||
other = "令牌 ID"
|
||||
|
||||
[DDNSTokenSecret]
|
||||
other = "令牌 Secret"
|
||||
|
||||
[WebhookURL]
|
||||
other = "Webhook 地址"
|
||||
|
||||
[WebhookMethod]
|
||||
other = "Webhook 請求方式"
|
||||
|
||||
[WebhookRequestType]
|
||||
other = "Webhook 請求類型"
|
||||
|
||||
[WebhookHeaders]
|
||||
other = "Webhook 請求頭"
|
||||
|
||||
[WebhookRequestBody]
|
||||
other = "Webhook 請求體"
|
||||
|
||||
[Feature]
|
||||
other = "功能"
|
||||
|
||||
[Template]
|
||||
other = "主題"
|
||||
|
||||
[Stat]
|
||||
other = "信息"
|
||||
|
||||
[Temperature]
|
||||
other = "溫度"
|
||||
|
||||
[DisableSwitchTemplateInFrontend]
|
||||
other = "禁止前台切換主題"
|
||||
|
||||
[ServersOnWorldMap]
|
||||
other = "伺服器世界分布圖"
|
||||
|
||||
[NAT]
|
||||
other = "NAT穿透"
|
||||
|
||||
[LocalService]
|
||||
other = "內網服務"
|
||||
|
||||
[LocalServicePlaceholder]
|
||||
other = "192.168.1.1:80(帶埠號)"
|
||||
|
||||
[BindHostname]
|
||||
other = "綁定網域"
|
||||
|
||||
[NetworkSpiterList]
|
||||
other = "網路監控"
|
||||
|
||||
[Refresh]
|
||||
other = "重新整理"
|
||||
|
||||
[CopyPath]
|
||||
other = "複製路徑"
|
||||
|
||||
[Goto]
|
||||
other = "跳至"
|
||||
|
||||
[GotoHeadline]
|
||||
other = "跳至資料夾"
|
||||
|
||||
[GotoGo]
|
||||
other = "確定"
|
||||
|
||||
[GotoClose]
|
||||
other = "取消"
|
||||
|
||||
[FMError]
|
||||
other = "Agent 回傳了錯誤,請查看主控台獲取詳細資訊。要建立新連線,請重新開啟 FM。"
|
||||
|
||||
[Remaining]
|
||||
other = "剩餘"
|
||||
|
||||
[Lifetime]
|
||||
other = "永續"
|
||||
|
||||
[Price]
|
||||
other = "價格"
|
||||
|
||||
[Expired]
|
||||
other = "已到期"
|
||||
|
||||
[Days]
|
||||
other = "天"
|
||||
|
||||
[CustomNameservers]
|
||||
other = "自訂DDNS使用的公共DNS伺服器(逗號分隔)"
|
31
resource/resource.go
vendored
@ -1,31 +0,0 @@
|
||||
package resource
|
||||
|
||||
import (
|
||||
"embed"
|
||||
|
||||
"github.com/naiba/nezha/pkg/utils"
|
||||
)
|
||||
|
||||
var StaticFS *utils.HybridFS
|
||||
|
||||
//go:embed static
|
||||
var staticFS embed.FS
|
||||
|
||||
//go:embed template
|
||||
var TemplateFS embed.FS
|
||||
|
||||
//go:embed l10n
|
||||
var I18nFS embed.FS
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
StaticFS, err = utils.NewHybridFS(staticFS, "static", "resource/static/custom")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func IsTemplateFileExist(name string) bool {
|
||||
_, err := TemplateFS.Open(name)
|
||||
return err == nil
|
||||
}
|
Before Width: | Height: | Size: 13 KiB |
@ -1,141 +0,0 @@
|
||||
html[nz-theme='dark'] body {
|
||||
background-color: #121212 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .ui.menu {
|
||||
background-color: #282828 !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .ui.menu * {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .accordion {
|
||||
background-color: #282828 !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .accordion .title {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .ui.card {
|
||||
background-color: #3f3f3f !important;
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .header {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .description {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .icon {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .ui.popup {
|
||||
background-color: #575757 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .ui.table {
|
||||
background-color: #282828 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .ui thead th {
|
||||
background-color: #3f3f3f !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .ui.buttons .button {
|
||||
background-color: #3f3f3f !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .ui.modal {
|
||||
background-color: #282828 !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .ui.modal * {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] textarea,
|
||||
html[nz-theme='dark'] input,
|
||||
html[nz-theme='dark'] select,
|
||||
html[nz-theme='dark'] .dropdown {
|
||||
background-color: #3f3f3f !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .ui.message {
|
||||
background-color: unset !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .ui.dropdown .menu {
|
||||
background-color: #575757 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .ui.modal>.header {
|
||||
background-color: #3f3f3f !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .ui.modal>.content {
|
||||
background-color: #282828 !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .ui.modal>.actions {
|
||||
background-color: #3f3f3f !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] #alert {
|
||||
background-color: #3f3f3f !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .ui.form .field>label {
|
||||
color: unset !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .ui.segment {
|
||||
background-color: #3f3f3f !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .ui.segment textarea,
|
||||
html[nz-theme='dark'] input,
|
||||
html[nz-theme='dark'] select,
|
||||
html[nz-theme='dark'] .dropdown {
|
||||
background-color: #575757 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] form label {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .ui.inverted.segment {
|
||||
background-color: #121212 !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .ui.inverted.segment * {
|
||||
color: #8b8b8b !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .menu .dropdown {
|
||||
background-color: #282828 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .ui.menu .ui.dropdown .menu>.item {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
html[nz-theme='dark'] .login .ui.message{
|
||||
color: #8b8b8b !important;
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
let receivedLength = 0;
|
||||
let expectedLength = 0;
|
||||
let root;
|
||||
let draftHandle;
|
||||
let accessHandle;
|
||||
|
||||
const Operation = Object.freeze({
|
||||
WriteHeader: 1,
|
||||
WriteChunks: 2,
|
||||
DeleteFiles: 3
|
||||
});
|
||||
|
||||
onmessage = async function (event) {
|
||||
try {
|
||||
const { operation, arrayBuffer, fileName } = event.data;
|
||||
|
||||
switch (operation) {
|
||||
case Operation.WriteHeader: {
|
||||
const dataView = new DataView(arrayBuffer);
|
||||
expectedLength = Number(dataView.getBigUint64(4, false));
|
||||
receivedLength = 0;
|
||||
|
||||
// Create a new temporary file
|
||||
root = await navigator.storage.getDirectory();
|
||||
draftHandle = await root.getFileHandle(fileName, { create: true });
|
||||
accessHandle = await draftHandle.createSyncAccessHandle();
|
||||
|
||||
// Inform that file handle is created
|
||||
const dataChunk = arrayBuffer.slice(12);
|
||||
receivedLength += dataChunk.byteLength;
|
||||
accessHandle.write(dataChunk, { at: 0 });
|
||||
const progress = 'got handle';
|
||||
postMessage({ type: 'progress', progress: progress });
|
||||
break;
|
||||
}
|
||||
case Operation.WriteChunks: {
|
||||
if (!accessHandle) {
|
||||
throw new Error('accessHandle is undefined');
|
||||
}
|
||||
|
||||
const dataChunk = arrayBuffer;
|
||||
accessHandle.write(dataChunk, { at: receivedLength });
|
||||
receivedLength += dataChunk.byteLength;
|
||||
|
||||
if (receivedLength === expectedLength) {
|
||||
accessHandle.flush();
|
||||
accessHandle.close();
|
||||
|
||||
const fileBlob = await draftHandle.getFile();
|
||||
const blob = new Blob([fileBlob], { type: 'application/octet-stream' });
|
||||
|
||||
postMessage({ type: 'result', blob: blob, fileName: fileName });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Operation.DeleteFiles: {
|
||||
for await (const [name, handle] of root.entries()) {
|
||||
if (handle.kind === 'file') {
|
||||
await root.removeEntry(name);
|
||||
} else if (handle.kind === 'directory') {
|
||||
await root.removeEntry(name, { recursive: true });
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
postMessage({ error: error.message });
|
||||
}
|
||||
};
|
@ -1 +0,0 @@
|
||||
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path fill="#0A94F2" d="M30 17v61.84L73.588 106 177 43.082l-7.336-.542V17z"/><path fill="#0338D6" d="M77.42 139.845L30 109.943v42.6L99.585 187l69.582-34.457V75.38L186 48z"/></g></svg>
|
Before Width: | Height: | Size: 283 B |
@ -1,129 +0,0 @@
|
||||
@media only screen and (min-width: 1200px) {
|
||||
.ui.container {
|
||||
width: 77%;
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.ui.container{
|
||||
width: 95vw !important;
|
||||
max-width: 1680px !important;
|
||||
}
|
||||
|
||||
.nb-container {
|
||||
padding-top: 75px;
|
||||
min-height: 100vh;
|
||||
padding-bottom: 65px;
|
||||
margin-bottom: -47px;
|
||||
}
|
||||
|
||||
#app .ui.fluid.accordion {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.login.nb-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-top: unset;
|
||||
}
|
||||
|
||||
.login.nb-container > .grid {
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.login.nb-container > .grid .column {
|
||||
max-width: 450px;
|
||||
}
|
||||
|
||||
.status.cards .flag {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
|
||||
.status.cards .header > .info.icon {
|
||||
float: right;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.status.cards .wide.column {
|
||||
padding-top: 0 !important;
|
||||
padding-bottom: 0 !important;
|
||||
height: 2rem !important;
|
||||
}
|
||||
|
||||
.status.cards .three.wide.column {
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
|
||||
.status.cards .wide.column:nth-child(1) {
|
||||
margin-top: 1rem !important;
|
||||
}
|
||||
|
||||
.status.cards .wide.column:nth-child(2) {
|
||||
margin-top: 1rem !important;
|
||||
}
|
||||
|
||||
.status.cards .description {
|
||||
padding-bottom: 1rem !important;
|
||||
}
|
||||
|
||||
.status.cards .ui.content.popup {
|
||||
min-width: 250px;
|
||||
}
|
||||
|
||||
.status.cards .outline.icon {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
|
||||
.ui.progress .bar {
|
||||
min-width: 1.26em !important;
|
||||
text-align: right;
|
||||
padding-right: 0.4em;
|
||||
line-height: 1.75em;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-weight: 700;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
.service-status .delay-today {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.service-status .delay-today > i {
|
||||
display: inline-block;
|
||||
width: 1.2em;
|
||||
height: 1.2em;
|
||||
border-radius: 0.6em;
|
||||
background-color: grey;
|
||||
margin-right: 0.3em;
|
||||
}
|
||||
|
||||
.service-status .danger {
|
||||
background-color: crimson !important;
|
||||
}
|
||||
|
||||
.service-status .good {
|
||||
background-color: rgb(10, 148, 242) !important;
|
||||
}
|
||||
|
||||
.service-status .warning {
|
||||
background-color: orange !important;
|
||||
}
|
||||
|
||||
.nezha-primary-btn {
|
||||
background-color: #0338d6 !important;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.nezha-primary-font {
|
||||
color: #0338d6 !important;
|
||||
}
|
||||
|
||||
.nezha-secondary-font {
|
||||
color: rgb(10, 148, 242) !important;
|
||||
}
|
@ -1,717 +0,0 @@
|
||||
let LANG = {
|
||||
Add: "添加",
|
||||
Edit: "修改",
|
||||
AlarmRule: "报警规则",
|
||||
Notification: "通知方式",
|
||||
Server: "服务器",
|
||||
Monitor: "监控",
|
||||
Cron: "计划任务",
|
||||
}
|
||||
|
||||
function updateLang(newLang) {
|
||||
if (newLang) {
|
||||
LANG = newLang;
|
||||
}
|
||||
}
|
||||
|
||||
function readableBytes(bytes) {
|
||||
if (!bytes) {
|
||||
return '0B'
|
||||
}
|
||||
var i = Math.floor(Math.log(bytes) / Math.log(1024)),
|
||||
sizes = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
||||
return parseFloat((bytes / Math.pow(1024, i)).toFixed(2)) + sizes[i];
|
||||
}
|
||||
|
||||
const confirmBtn = $(".mini.confirm.modal .nezha-primary-btn.button");
|
||||
|
||||
function showConfirm(title, content, callFn, extData) {
|
||||
const modal = $(".mini.confirm.modal");
|
||||
modal.children(".header").text(title);
|
||||
modal.children(".content").text(content);
|
||||
if (confirmBtn.hasClass("loading")) {
|
||||
return false;
|
||||
}
|
||||
modal
|
||||
.modal({
|
||||
closable: true,
|
||||
onApprove: function () {
|
||||
confirmBtn.toggleClass("loading");
|
||||
callFn(extData);
|
||||
return false;
|
||||
},
|
||||
})
|
||||
.modal("show");
|
||||
}
|
||||
|
||||
function postJson(url, data) {
|
||||
return $.ajax({
|
||||
url: url,
|
||||
type: "POST",
|
||||
contentType: "application/json",
|
||||
data: JSON.stringify(data),
|
||||
}).done((resp) => {
|
||||
if (resp.code == 200) {
|
||||
if (resp.message) {
|
||||
alert(resp.message);
|
||||
} else {
|
||||
alert("删除成功");
|
||||
}
|
||||
window.location.reload();
|
||||
} else {
|
||||
alert("删除失败 " + resp.code + ":" + resp.message);
|
||||
confirmBtn.toggleClass("loading");
|
||||
}
|
||||
})
|
||||
.fail((err) => {
|
||||
alert("网络错误:" + err.responseText);
|
||||
});
|
||||
}
|
||||
|
||||
function showFormModal(modelSelector, formID, URL, getData) {
|
||||
$(modelSelector)
|
||||
.modal({
|
||||
closable: true,
|
||||
onApprove: function () {
|
||||
let success = false;
|
||||
const btn = $(modelSelector + " .nezha-primary-btn.button");
|
||||
const form = $(modelSelector + " form");
|
||||
if (btn.hasClass("loading")) {
|
||||
return success;
|
||||
}
|
||||
form.children(".message").remove();
|
||||
btn.toggleClass("loading");
|
||||
const data = getData
|
||||
? getData()
|
||||
: $(formID)
|
||||
.serializeArray()
|
||||
.reduce(function (obj, item) {
|
||||
// ID 类的数据
|
||||
if (
|
||||
item.name.endsWith("_id") ||
|
||||
item.name === "id" ||
|
||||
item.name === "ID" ||
|
||||
item.name === "ServerID" ||
|
||||
item.name === "RequestType" ||
|
||||
item.name === "RequestMethod" ||
|
||||
item.name === "TriggerMode" ||
|
||||
item.name === "TaskType" ||
|
||||
item.name === "DisplayIndex" ||
|
||||
item.name === "Type" ||
|
||||
item.name === "Cover" ||
|
||||
item.name === "Duration" ||
|
||||
item.name === "MaxRetries" ||
|
||||
item.name === "Provider" ||
|
||||
item.name === "WebhookMethod" ||
|
||||
item.name === "WebhookRequestType"
|
||||
) {
|
||||
obj[item.name] = parseInt(item.value);
|
||||
} else if (item.name.endsWith("Latency")) {
|
||||
obj[item.name] = parseFloat(item.value);
|
||||
} else {
|
||||
obj[item.name] = item.value;
|
||||
}
|
||||
|
||||
if (item.name.endsWith("ServersRaw")) {
|
||||
if (item.value.length > 2) {
|
||||
obj[item.name] = JSON.stringify(
|
||||
[...item.value.matchAll(/\d+/gm)].map((k) =>
|
||||
parseInt(k[0])
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (item.name.endsWith("TasksRaw")) {
|
||||
if (item.value.length > 2) {
|
||||
obj[item.name] = JSON.stringify(
|
||||
[...item.value.matchAll(/\d+/gm)].map((k) =>
|
||||
parseInt(k[0])
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (item.name.endsWith("DDNSProfilesRaw")) {
|
||||
if (item.value.length > 2) {
|
||||
obj[item.name] = JSON.stringify(
|
||||
[...item.value.matchAll(/\d+/gm)].map((k) =>
|
||||
parseInt(k[0])
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}, {});
|
||||
$.post(URL, JSON.stringify(data))
|
||||
.done(function (resp) {
|
||||
if (resp.code == 200) {
|
||||
window.location.reload()
|
||||
} else {
|
||||
form.append(
|
||||
`<div class="ui negative message"><div class="header">操作失败</div><p>` +
|
||||
resp.message +
|
||||
`</p></div>`
|
||||
);
|
||||
}
|
||||
})
|
||||
.fail(function (err) {
|
||||
form.append(
|
||||
`<div class="ui negative message"><div class="header">网络错误</div><p>` +
|
||||
err.responseText +
|
||||
`</p></div>`
|
||||
);
|
||||
})
|
||||
.always(function () {
|
||||
btn.toggleClass("loading");
|
||||
});
|
||||
return success;
|
||||
},
|
||||
})
|
||||
.modal("show");
|
||||
}
|
||||
|
||||
function addOrEditAlertRule(rule) {
|
||||
const modal = $(".rule.modal");
|
||||
modal.children(".header").text((rule ? LANG.Edit : LANG.Add) + ' ' + LANG.AlarmRule);
|
||||
modal
|
||||
.find(".nezha-primary-btn.button")
|
||||
.html(
|
||||
rule ? LANG.Edit + '<i class="edit icon"></i>' : LANG.Add + '<i class="add icon"></i>'
|
||||
);
|
||||
modal.find("input[name=ID]").val(rule ? rule.ID : null);
|
||||
modal.find("input[name=Name]").val(rule ? rule.Name : null);
|
||||
modal.find("textarea[name=RulesRaw]").val(rule ? rule.RulesRaw : null);
|
||||
modal.find("select[name=TriggerMode]").val(rule ? rule.TriggerMode : 0);
|
||||
modal.find("input[name=NotificationTag]").val(rule ? rule.NotificationTag : null);
|
||||
if (rule && rule.Enable) {
|
||||
modal.find(".ui.rule-enable.checkbox").checkbox("set checked");
|
||||
} else {
|
||||
modal.find(".ui.rule-enable.checkbox").checkbox("set unchecked");
|
||||
}
|
||||
modal.find("a.ui.label.visible").each((i, el) => {
|
||||
el.remove();
|
||||
});
|
||||
var failTriggerTasks;
|
||||
var recoverTriggerTasks;
|
||||
if (rule) {
|
||||
failTriggerTasks = rule.FailTriggerTasksRaw;
|
||||
recoverTriggerTasks = rule.RecoverTriggerTasksRaw;
|
||||
const failTriggerTasksList = JSON.parse(failTriggerTasks || "[]");
|
||||
const recoverTriggerTasksList = JSON.parse(recoverTriggerTasks || "[]");
|
||||
const node1 = modal.find("i.dropdown.icon.1");
|
||||
const node2 = modal.find("i.dropdown.icon.2");
|
||||
for (let i = 0; i < failTriggerTasksList.length; i++) {
|
||||
node1.after(
|
||||
'<a class="ui label transition visible" data-value="' +
|
||||
failTriggerTasksList[i] +
|
||||
'" style="display: inline-block !important;">ID:' +
|
||||
failTriggerTasksList[i] +
|
||||
'<i class="delete icon"></i></a>'
|
||||
);
|
||||
}
|
||||
for (let i = 0; i < recoverTriggerTasksList.length; i++) {
|
||||
node2.after(
|
||||
'<a class="ui label transition visible" data-value="' +
|
||||
recoverTriggerTasksList[i] +
|
||||
'" style="display: inline-block !important;">ID:' +
|
||||
recoverTriggerTasksList[i] +
|
||||
'<i class="delete icon"></i></a>'
|
||||
);
|
||||
}
|
||||
}
|
||||
// 需要在 showFormModal 进一步拼接数组
|
||||
modal
|
||||
.find("input[name=FailTriggerTasksRaw]")
|
||||
.val(rule ? "[]," + failTriggerTasks.substr(1, failTriggerTasks.length - 2) : "[]");
|
||||
modal
|
||||
.find("input[name=RecoverTriggerTasksRaw]")
|
||||
.val(rule ? "[]," + recoverTriggerTasks.substr(1, recoverTriggerTasks.length - 2) : "[]");
|
||||
|
||||
showFormModal(".rule.modal", "#ruleForm", "/api/alert-rule");
|
||||
}
|
||||
|
||||
function addOrEditNotification(notification) {
|
||||
const modal = $(".notification.modal");
|
||||
modal.children(".header").text((notification ? LANG.Edit : LANG.Add) + ' ' + LANG.Notification);
|
||||
modal
|
||||
.find(".nezha-primary-btn.button")
|
||||
.html(
|
||||
notification
|
||||
? LANG.Edit + '<i class="edit icon"></i>'
|
||||
: LANG.Add + '<i class="add icon"></i>'
|
||||
);
|
||||
modal.find("input[name=ID]").val(notification ? notification.ID : null);
|
||||
modal.find("input[name=Name]").val(notification ? notification.Name : null);
|
||||
modal.find("input[name=Tag]").val(notification ? notification.Tag : null);
|
||||
modal.find("input[name=URL]").val(notification ? notification.URL : null);
|
||||
modal
|
||||
.find("textarea[name=RequestHeader]")
|
||||
.val(notification ? notification.RequestHeader : null);
|
||||
modal
|
||||
.find("textarea[name=RequestBody]")
|
||||
.val(notification ? notification.RequestBody : null);
|
||||
modal
|
||||
.find("select[name=RequestMethod]")
|
||||
.val(notification ? notification.RequestMethod : 1);
|
||||
modal
|
||||
.find("select[name=RequestType]")
|
||||
.val(notification ? notification.RequestType : 1);
|
||||
if (notification && notification.VerifySSL) {
|
||||
modal.find(".ui.nf-ssl.checkbox").checkbox("set checked");
|
||||
} else {
|
||||
modal.find(".ui.nf-ssl.checkbox").checkbox("set unchecked");
|
||||
}
|
||||
modal.find(".ui.nf-skip-check.checkbox").checkbox("set unchecked");
|
||||
showFormModal(
|
||||
".notification.modal",
|
||||
"#notificationForm",
|
||||
"/api/notification"
|
||||
);
|
||||
}
|
||||
|
||||
function addOrEditDDNS(ddns) {
|
||||
const modal = $(".ddns.modal");
|
||||
modal.children(".header").text((ddns ? LANG.Edit : LANG.Add));
|
||||
modal
|
||||
.find(".nezha-primary-btn.button")
|
||||
.html(
|
||||
ddns
|
||||
? LANG.Edit + '<i class="edit icon"></i>'
|
||||
: LANG.Add + '<i class="add icon"></i>'
|
||||
);
|
||||
modal.find("input[name=ID]").val(ddns ? ddns.ID : null);
|
||||
modal.find("input[name=Name]").val(ddns ? ddns.Name : null);
|
||||
modal.find("input[name=DomainsRaw]").val(ddns ? ddns.DomainsRaw : null);
|
||||
modal.find("input[name=AccessID]").val(ddns ? ddns.AccessID : null);
|
||||
modal.find("input[name=AccessSecret]").val(ddns ? ddns.AccessSecret : null);
|
||||
modal.find("input[name=MaxRetries]").val(ddns ? ddns.MaxRetries : 3);
|
||||
modal.find("input[name=WebhookURL]").val(ddns ? ddns.WebhookURL : null);
|
||||
modal
|
||||
.find("textarea[name=WebhookHeaders]")
|
||||
.val(ddns ? ddns.WebhookHeaders : null);
|
||||
modal
|
||||
.find("textarea[name=WebhookRequestBody]")
|
||||
.val(ddns ? ddns.WebhookRequestBody : null);
|
||||
modal
|
||||
.find("select[name=Provider]")
|
||||
.val(ddns ? ddns.Provider : 0);
|
||||
modal
|
||||
.find("select[name=WebhookMethod]")
|
||||
.val(ddns ? ddns.WebhookMethod : 1);
|
||||
modal
|
||||
.find("select[name=WebhookRequestType]")
|
||||
.val(ddns ? ddns.WebhookRequestType : 1);
|
||||
if (ddns && ddns.EnableIPv4) {
|
||||
modal.find(".ui.enableipv4.checkbox").checkbox("set checked");
|
||||
} else {
|
||||
modal.find(".ui.enableipv4.checkbox").checkbox("set unchecked");
|
||||
}
|
||||
if (ddns && ddns.EnableIPv6) {
|
||||
modal.find(".ui.enableipv6.checkbox").checkbox("set checked");
|
||||
} else {
|
||||
modal.find(".ui.enableipv6.checkbox").checkbox("set unchecked");
|
||||
}
|
||||
showFormModal(
|
||||
".ddns.modal",
|
||||
"#ddnsForm",
|
||||
"/api/ddns"
|
||||
);
|
||||
}
|
||||
|
||||
function addOrEditNAT(nat) {
|
||||
const modal = $(".nat.modal");
|
||||
modal.children(".header").text((nat ? LANG.Edit : LANG.Add));
|
||||
modal
|
||||
.find(".nezha-primary-btn.button")
|
||||
.html(
|
||||
nat
|
||||
? LANG.Edit + '<i class="edit icon"></i>'
|
||||
: LANG.Add + '<i class="add icon"></i>'
|
||||
);
|
||||
modal.find("input[name=ID]").val(nat ? nat.ID : null);
|
||||
modal.find("input[name=ServerID]").val(nat ? nat.ServerID : null);
|
||||
modal.find("input[name=Name]").val(nat ? nat.Name : null);
|
||||
modal.find("input[name=Host]").val(nat ? nat.Host : null);
|
||||
modal.find("input[name=Domain]").val(nat ? nat.Domain : null);
|
||||
showFormModal(
|
||||
".nat.modal",
|
||||
"#natForm",
|
||||
"/api/nat"
|
||||
);
|
||||
}
|
||||
|
||||
function connectToServer(id) {
|
||||
post('/terminal', { Host: window.location.host, Protocol: window.location.protocol, ID: id })
|
||||
}
|
||||
|
||||
function post(path, params, method = 'post') {
|
||||
const form = document.createElement('form');
|
||||
form.method = method;
|
||||
form.action = path;
|
||||
form.target = "_blank";
|
||||
|
||||
for (const key in params) {
|
||||
if (params.hasOwnProperty(key)) {
|
||||
const hiddenField = document.createElement('input');
|
||||
hiddenField.type = 'hidden';
|
||||
hiddenField.name = key;
|
||||
hiddenField.value = params[key];
|
||||
form.appendChild(hiddenField);
|
||||
}
|
||||
}
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
document.body.removeChild(form);
|
||||
}
|
||||
|
||||
function issueNewApiToken(apiToken) {
|
||||
const modal = $(".api.modal");
|
||||
modal.children(".header").text((apiToken ? LANG.Edit : LANG.Add) + ' ' + "API Token");
|
||||
modal
|
||||
.find(".nezha-primary-btn.button")
|
||||
.html(
|
||||
apiToken ? LANG.Edit + '<i class="edit icon"></i>' : LANG.Add + '<i class="add icon"></i>'
|
||||
);
|
||||
modal.find("textarea[name=Note]").val(apiToken ? apiToken.Note : null);
|
||||
showFormModal(".api.modal", "#apiForm", "/api/token");
|
||||
}
|
||||
|
||||
function addOrEditServer(server, conf) {
|
||||
const modal = $(".server.modal");
|
||||
modal.children(".header").text((server ? LANG.Edit : LANG.Add) + ' ' + LANG.Server);
|
||||
modal
|
||||
.find(".nezha-primary-btn.button")
|
||||
.html(
|
||||
server ? LANG.Edit + '<i class="edit icon"></i>' : LANG.Add + '<i class="add icon"></i>'
|
||||
);
|
||||
modal.find("input[name=id]").val(server ? server.ID : null);
|
||||
modal.find("input[name=name]").val(server ? server.Name : null);
|
||||
modal.find("input[name=Tag]").val(server ? server.Tag : null);
|
||||
modal.find("a.ui.label.visible").each((i, el) => {
|
||||
el.remove();
|
||||
});
|
||||
var ddns;
|
||||
if (server) {
|
||||
ddns = server.DDNSProfilesRaw;
|
||||
let serverList;
|
||||
try {
|
||||
serverList = JSON.parse(ddns);
|
||||
} catch (error) {
|
||||
serverList = "[]";
|
||||
}
|
||||
const node = modal.find("i.dropdown.icon.ddnsProfiles");
|
||||
for (let i = 0; i < serverList.length; i++) {
|
||||
node.after(
|
||||
'<a class="ui label transition visible" data-value="' +
|
||||
serverList[i] +
|
||||
'" style="display: inline-block !important;">ID:' +
|
||||
serverList[i] +
|
||||
'<i class="delete icon"></i></a>'
|
||||
);
|
||||
}
|
||||
}
|
||||
// 需要在 showFormModal 进一步拼接数组
|
||||
modal
|
||||
.find("input[name=DDNSProfilesRaw]")
|
||||
.val(server ? "[]," + ddns.substr(1, ddns.length - 2) : "[]");
|
||||
modal
|
||||
.find("input[name=DisplayIndex]")
|
||||
.val(server ? server.DisplayIndex : null);
|
||||
modal.find("textarea[name=Note]").val(server ? server.Note : null);
|
||||
modal.find("textarea[name=PublicNote]").val(server ? server.PublicNote : null);
|
||||
if (server) {
|
||||
modal.find(".secret.field").attr("style", "");
|
||||
modal.find(".command.field").attr("style", "");
|
||||
modal.find(".command.hostSecret").text(server.Secret);
|
||||
modal.find("input[name=secret]").val(server.Secret);
|
||||
} else {
|
||||
modal.find(".secret.field").attr("style", "display:none");
|
||||
modal.find(".command.field").attr("style", "display:none");
|
||||
modal.find("input[name=secret]").val("");
|
||||
}
|
||||
if (server && server.EnableDDNS) {
|
||||
modal.find(".ui.enableddns.checkbox").checkbox("set checked");
|
||||
} else {
|
||||
modal.find(".ui.enableddns.checkbox").checkbox("set unchecked");
|
||||
}
|
||||
if (server && server.HideForGuest) {
|
||||
modal.find(".ui.hideforguest.checkbox").checkbox("set checked");
|
||||
} else {
|
||||
modal.find(".ui.hideforguest.checkbox").checkbox("set unchecked");
|
||||
}
|
||||
|
||||
showFormModal(".server.modal", "#serverForm", "/api/server");
|
||||
}
|
||||
|
||||
function addOrEditMonitor(monitor) {
|
||||
const modal = $(".monitor.modal");
|
||||
modal.children(".header").text((monitor ? LANG.Edit : LANG.Add) + ' ' + LANG.Monitor);
|
||||
modal
|
||||
.find(".nezha-primary-btn.button")
|
||||
.html(
|
||||
monitor ? LANG.Edit + '<i class="edit icon"></i>' : LANG.Add + '<i class="add icon"></i>'
|
||||
);
|
||||
modal.find("input[name=ID]").val(monitor ? monitor.ID : null);
|
||||
modal.find("input[name=Name]").val(monitor ? monitor.Name : null);
|
||||
modal.find("input[name=Target]").val(monitor ? monitor.Target : null);
|
||||
modal.find("input[name=Duration]").val(monitor && monitor.Duration ? monitor.Duration : 30);
|
||||
modal.find("select[name=Type]").val(monitor ? monitor.Type : 1);
|
||||
modal.find("select[name=Cover]").val(monitor ? monitor.Cover : 0);
|
||||
modal.find("input[name=NotificationTag]").val(monitor ? monitor.NotificationTag : null);
|
||||
if (monitor && monitor.EnableShowInService) {
|
||||
modal.find(".ui.nb-show-in-service.checkbox").checkbox("set checked")
|
||||
} else {
|
||||
modal.find(".ui.nb-show-in-service.checkbox").checkbox("set unchecked")
|
||||
}
|
||||
if (monitor && monitor.Notify) {
|
||||
modal.find(".ui.nb-notify.checkbox").checkbox("set checked");
|
||||
} else {
|
||||
modal.find(".ui.nb-notify.checkbox").checkbox("set unchecked");
|
||||
}
|
||||
modal.find("input[name=MaxLatency]").val(monitor ? monitor.MaxLatency : null);
|
||||
modal.find("input[name=MinLatency]").val(monitor ? monitor.MinLatency : null);
|
||||
if (monitor && monitor.LatencyNotify) {
|
||||
modal.find(".ui.nb-lt-notify.checkbox").checkbox("set checked");
|
||||
} else {
|
||||
modal.find(".ui.nb-lt-notify.checkbox").checkbox("set unchecked");
|
||||
}
|
||||
modal.find("a.ui.label.visible").each((i, el) => {
|
||||
el.remove();
|
||||
});
|
||||
if (monitor && monitor.EnableTriggerTask) {
|
||||
modal.find(".ui.nb-EnableTriggerTask.checkbox").checkbox("set checked");
|
||||
} else {
|
||||
modal.find(".ui.nb-EnableTriggerTask.checkbox").checkbox("set unchecked");
|
||||
}
|
||||
var servers;
|
||||
var failTriggerTasks;
|
||||
var recoverTriggerTasks;
|
||||
if (monitor) {
|
||||
servers = monitor.SkipServersRaw;
|
||||
const serverList = JSON.parse(servers || "[]");
|
||||
const node = modal.find("i.dropdown.icon.specificServer");
|
||||
for (let i = 0; i < serverList.length; i++) {
|
||||
node.after(
|
||||
'<a class="ui label transition visible" data-value="' +
|
||||
serverList[i] +
|
||||
'" style="display: inline-block !important;">ID:' +
|
||||
serverList[i] +
|
||||
'<i class="delete icon"></i></a>'
|
||||
);
|
||||
}
|
||||
|
||||
failTriggerTasks = monitor.FailTriggerTasksRaw;
|
||||
recoverTriggerTasks = monitor.RecoverTriggerTasksRaw;
|
||||
const failTriggerTasksList = JSON.parse(failTriggerTasks || "[]");
|
||||
const recoverTriggerTasksList = JSON.parse(recoverTriggerTasks || "[]");
|
||||
const node1 = modal.find("i.dropdown.icon.failTask");
|
||||
const node2 = modal.find("i.dropdown.icon.recoverTask");
|
||||
for (let i = 0; i < failTriggerTasksList.length; i++) {
|
||||
node1.after(
|
||||
'<a class="ui label transition visible" data-value="' +
|
||||
failTriggerTasksList[i] +
|
||||
'" style="display: inline-block !important;">ID:' +
|
||||
failTriggerTasksList[i] +
|
||||
'<i class="delete icon"></i></a>'
|
||||
);
|
||||
}
|
||||
for (let i = 0; i < recoverTriggerTasksList.length; i++) {
|
||||
node2.after(
|
||||
'<a class="ui label transition visible" data-value="' +
|
||||
recoverTriggerTasksList[i] +
|
||||
'" style="display: inline-block !important;">ID:' +
|
||||
recoverTriggerTasksList[i] +
|
||||
'<i class="delete icon"></i></a>'
|
||||
);
|
||||
}
|
||||
}
|
||||
// 需要在 showFormModal 进一步拼接数组
|
||||
modal
|
||||
.find("input[name=FailTriggerTasksRaw]")
|
||||
.val(monitor ? "[]," + failTriggerTasks.substr(1, failTriggerTasks.length - 2) : "[]");
|
||||
modal
|
||||
.find("input[name=RecoverTriggerTasksRaw]")
|
||||
.val(monitor ? "[]," + recoverTriggerTasks.substr(1, recoverTriggerTasks.length - 2) : "[]");
|
||||
|
||||
modal
|
||||
.find("input[name=SkipServersRaw]")
|
||||
.val(monitor ? "[]," + servers.substr(1, servers.length - 2) : "[]");
|
||||
showFormModal(".monitor.modal", "#monitorForm", "/api/monitor");
|
||||
}
|
||||
|
||||
function addOrEditCron(cron) {
|
||||
const modal = $(".cron.modal");
|
||||
modal.children(".header").text((cron ? LANG.Edit : LANG.Add) + ' ' + LANG.Cron);
|
||||
modal
|
||||
.find(".nezha-primary-btn.button")
|
||||
.html(
|
||||
cron ? LANG.Edit + '<i class="edit icon"></i>' : LANG.Add + '<i class="add icon"></i>'
|
||||
);
|
||||
modal.find("input[name=ID]").val(cron ? cron.ID : null);
|
||||
modal.find("input[name=Name]").val(cron ? cron.Name : null);
|
||||
modal.find("select[name=TaskType]").val(cron ? cron.TaskType : 0);
|
||||
modal.find("select[name=Cover]").val(cron ? cron.Cover : 0);
|
||||
modal.find("input[name=NotificationTag]").val(cron ? cron.NotificationTag : null);
|
||||
modal.find("input[name=Scheduler]").val(cron ? cron.Scheduler : null);
|
||||
modal.find("a.ui.label.visible").each((i, el) => {
|
||||
el.remove();
|
||||
});
|
||||
var servers;
|
||||
if (cron) {
|
||||
servers = cron.ServersRaw;
|
||||
const serverList = JSON.parse(servers || "[]");
|
||||
const node = modal.find("i.dropdown.icon");
|
||||
for (let i = 0; i < serverList.length; i++) {
|
||||
node.after(
|
||||
'<a class="ui label transition visible" data-value="' +
|
||||
serverList[i] +
|
||||
'" style="display: inline-block !important;">ID:' +
|
||||
serverList[i] +
|
||||
'<i class="delete icon"></i></a>'
|
||||
);
|
||||
}
|
||||
}
|
||||
// 需要在 showFormModal 进一步拼接数组
|
||||
modal
|
||||
.find("input[name=ServersRaw]")
|
||||
.val(cron ? "[]," + servers.substr(1, servers.length - 2) : "[]");
|
||||
modal.find("textarea[name=Command]").val(cron ? cron.Command : null);
|
||||
if (cron && cron.PushSuccessful) {
|
||||
modal.find(".ui.push-successful.checkbox").checkbox("set checked");
|
||||
} else {
|
||||
modal.find(".ui.push-successful.checkbox").checkbox("set unchecked");
|
||||
}
|
||||
showFormModal(".cron.modal", "#cronForm", "/api/cron");
|
||||
}
|
||||
|
||||
function deleteRequest(api) {
|
||||
$.ajax({
|
||||
url: api,
|
||||
type: "DELETE",
|
||||
})
|
||||
.done((resp) => {
|
||||
if (resp.code == 200) {
|
||||
if (resp.message) {
|
||||
alert(resp.message);
|
||||
} else {
|
||||
alert("删除成功");
|
||||
}
|
||||
window.location.reload();
|
||||
} else {
|
||||
alert("删除失败 " + resp.code + ":" + resp.message);
|
||||
confirmBtn.toggleClass("loading");
|
||||
}
|
||||
})
|
||||
.fail((err) => {
|
||||
alert("网络错误:" + err.responseText);
|
||||
});
|
||||
}
|
||||
|
||||
function manualTrigger(btn, cronId) {
|
||||
$(btn).toggleClass("loading");
|
||||
$.ajax({
|
||||
url: "/api/cron/" + cronId + "/manual",
|
||||
type: "GET",
|
||||
})
|
||||
.done((resp) => {
|
||||
$(btn).toggleClass("loading");
|
||||
if (resp.code == 200) {
|
||||
$.suiAlert({
|
||||
title: "触发成功,等待执行结果",
|
||||
type: "success",
|
||||
description: resp.message,
|
||||
time: "3",
|
||||
position: "top-center",
|
||||
});
|
||||
} else {
|
||||
$.suiAlert({
|
||||
title: "触发失败 ",
|
||||
type: "error",
|
||||
description: resp.code + ":" + resp.message,
|
||||
time: "3",
|
||||
position: "top-center",
|
||||
});
|
||||
}
|
||||
})
|
||||
.fail((err) => {
|
||||
$(btn).toggleClass("loading");
|
||||
$.suiAlert({
|
||||
title: "触发失败 ",
|
||||
type: "error",
|
||||
description: "网络错误:" + err.responseText,
|
||||
time: "3",
|
||||
position: "top-center",
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function logout(id) {
|
||||
$.post("/api/logout", JSON.stringify({ id: id }))
|
||||
.done(function (resp) {
|
||||
if (resp.code == 200) {
|
||||
$.suiAlert({
|
||||
title: "注销成功",
|
||||
type: "success",
|
||||
description: "如需继续访问请使用 GitHub 再次登录",
|
||||
time: "3",
|
||||
position: "top-center",
|
||||
});
|
||||
window.location.reload();
|
||||
} else {
|
||||
$.suiAlert({
|
||||
title: "注销失败",
|
||||
description: resp.code + ":" + resp.message,
|
||||
type: "error",
|
||||
time: "3",
|
||||
position: "top-center",
|
||||
});
|
||||
}
|
||||
})
|
||||
.fail(function (err) {
|
||||
$.suiAlert({
|
||||
title: "网络错误",
|
||||
description: err.responseText,
|
||||
type: "error",
|
||||
time: "3",
|
||||
position: "top-center",
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(() => {
|
||||
try {
|
||||
$(".ui.servers.search.dropdown").dropdown({
|
||||
clearable: true,
|
||||
apiSettings: {
|
||||
url: "/api/search-server?word={query}",
|
||||
cache: false,
|
||||
},
|
||||
});
|
||||
} catch (error) { }
|
||||
});
|
||||
|
||||
$(document).ready(() => {
|
||||
try {
|
||||
$(".ui.tasks.search.dropdown").dropdown({
|
||||
clearable: true,
|
||||
apiSettings: {
|
||||
url: "/api/search-tasks?word={query}",
|
||||
cache: false,
|
||||
},
|
||||
});
|
||||
} catch (error) { }
|
||||
});
|
||||
|
||||
$(document).ready(() => {
|
||||
try {
|
||||
$(".ui.ddns.search.dropdown").dropdown({
|
||||
clearable: true,
|
||||
apiSettings: {
|
||||
url: "/api/search-ddns?word={query}",
|
||||
cache: false,
|
||||
},
|
||||
});
|
||||
} catch (error) { }
|
||||
});
|
Before Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 13 KiB |
@ -1,36 +0,0 @@
|
||||
{
|
||||
"name": "Nezha",
|
||||
"short_name": "Nezha",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/static/manifest-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "any"
|
||||
},
|
||||
{
|
||||
"src": "/static/manifest-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
},
|
||||
{
|
||||
"src": "/static/manifest-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "any"
|
||||
},
|
||||
{
|
||||
"src": "/static/manifest-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
}
|
||||
],
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#000000",
|
||||
"lang": "eu-US",
|
||||
"dir": "auto"
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
{
|
||||
"name": "哪吒监控",
|
||||
"short_name": "哪吒监控",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/static/manifest-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "any"
|
||||
},
|
||||
{
|
||||
"src": "/static/manifest-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
},
|
||||
{
|
||||
"src": "/static/manifest-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "any"
|
||||
},
|
||||
{
|
||||
"src": "/static/manifest-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
}
|
||||
],
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#000000",
|
||||
"lang": "zh-CN",
|
||||
"dir": "auto"
|
||||
}
|
1
resource/static/semantic-ui-alerts.min.css
vendored
@ -1 +0,0 @@
|
||||
.ui-alerts{position:fixed;z-index:2060;padding:23px}.ui-alerts.center{top:50%;left:50%;margin-top:-100px;margin-left:-222px}.ui-alerts.top-right{top:20px;right:20px}.ui-alerts.top-center{top:20px;margin-left:-222px;left:50%}.ui-alerts.top-left{top:20px;left:20px}.ui-alerts.bottom-right{bottom:0;right:20px}.ui-alerts.bottom-center{bottom:0;margin-left:-222px;left:50%}.ui-alerts.bottom-left{bottom:0;left:20px}.ui-alerts.ui-alerts>.message>.content>.header{padding-right:13px}@media (min-width:320px){.ui-alerts.top-center{margin-left:-163px}}
|
1
resource/static/semantic-ui-alerts.min.js
vendored
@ -1 +0,0 @@
|
||||
$.suiAlert=function(i){function t(){l=setTimeout(function(){c.transition({animation:e,duration:"2s",onComplete:function(){c.remove()}})},1e3*o.time)}var o=$.extend({title:"Semantic UI Alerts",description:"semantic ui alerts library",type:"error",time:5,position:"top-right",icon:!1},i);o.icon===!1&&("info"==o.type?o.icon="announcement":"success"==o.type?o.icon="checkmark":"error"==o.type?o.icon="remove":"warning"==o.type&&(o.icon="warning circle"));var e="drop";"top-right"==o.position?e="fly left":"top-center"==o.position?e="fly down":"top-left"==o.position?e="fly right":"bottom-right"==o.position?e="fly left":"bottom-center"==o.position?e="fly up":"bottom-left"==o.position&&(e="fly right");var n="",r=$(window).width();r<425&&(n="mini");var s="ui-alerts."+o.position;$("body > ."+s).length||$("body").append('<div class="ui-alerts '+o.position+'"></div>');var c=$('<div class="ui icon floating '+n+" message "+o.type+'" id="alert"> <i class="'+o.icon+' icon"></i> <i class="close icon" id="alertclose"></i> <div class="content"> <div class="header">'+o.title+"</div> <p>"+o.description+"</p> </div> </div>");$("."+s).prepend(c),c.transition("pulse"),$("#alertclose").on("click",function(){$(this).closest("#alert").transition({animation:e,onComplete:function(){c.remove()}})});var l=0;$(c).mouseenter(function(){clearTimeout(l)}).mouseleave(function(){t()}),t()};
|
BIN
resource/static/theme-angel-kanade/ailmm.woff2
vendored
379
resource/static/theme-angel-kanade/ktz.css
vendored
@ -1,379 +0,0 @@
|
||||
@font-face {
|
||||
font-family: HarmonyOS;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
src: url(./HarmonyOS_Sans_SC_Medium.subset.woff2) format('woff2')
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-weight: 900;
|
||||
font-family: dianzhenzt;
|
||||
src: url(./ailmm.woff2)
|
||||
}
|
||||
|
||||
body {
|
||||
background: #e6eef4;
|
||||
font-family: dianzhenzt !important
|
||||
}
|
||||
|
||||
.header {
|
||||
font-family: harmonyos, dianzhenzt !important
|
||||
}
|
||||
|
||||
.container {
|
||||
font-family: harmonyos, dianzhenzt !important
|
||||
}
|
||||
|
||||
#app {
|
||||
font-family: harmonyos, dianzhenzt !important
|
||||
}
|
||||
|
||||
.ui.inverted.segment {
|
||||
background: #e6eef4
|
||||
}
|
||||
|
||||
.ui.menu {
|
||||
background: #e6eef4;
|
||||
border: none !important;
|
||||
box-shadow: 0 0 0 #e6eef4 !important;
|
||||
-webkit-box-shadow: 0 0 0 #e6eef4 !important
|
||||
}
|
||||
|
||||
.ui.menu .active {
|
||||
border: none !important;
|
||||
border-radius: 10px !important;
|
||||
background: #e6eef4 !important;
|
||||
box-shadow: inset 5px 5px 16px #d6dde3, inset -5px -5px 16px #f6ffff !important
|
||||
}
|
||||
|
||||
.ui.menu .item:before {
|
||||
width: 0 !important
|
||||
}
|
||||
|
||||
.ui.menu:not(.secondary):not(.text):not(.tabular):not(.borderless)>.container>.item:not(.right):not(.borderless):first-child {
|
||||
border-left: none !important
|
||||
}
|
||||
|
||||
.ui.menu.fixed {
|
||||
position: static
|
||||
}
|
||||
|
||||
.nb-container {
|
||||
padding-top: 40px !important
|
||||
}
|
||||
|
||||
.ui.menu {
|
||||
margin-top: 20px !important
|
||||
}
|
||||
|
||||
#app .styled {
|
||||
box-shadow: 0 0 0 #e6eef4;
|
||||
-webkit-box-shadow: 0 0 0 #e6eef4
|
||||
}
|
||||
|
||||
#app .accordion {
|
||||
background: #e6eef4;
|
||||
border-style: none
|
||||
}
|
||||
|
||||
#app .accordion .content .card {
|
||||
border-radius: 20px;
|
||||
background: #e6eef4;
|
||||
box-shadow: -6px -6px 12px #b8bec3, 6px 6px 12px #fff
|
||||
}
|
||||
|
||||
.ui.fine.progress>.bar {
|
||||
background-image: linear-gradient(312deg, #57693b, #638b43, #6daf4a, #76d450)
|
||||
}
|
||||
|
||||
.ui.progress.fine .bar {
|
||||
background-image: linear-gradient(312deg, #57693b, #638b43, #6daf4a, #76d450)
|
||||
}
|
||||
|
||||
.ui.progress>.bar {
|
||||
background-color: #000 !important
|
||||
}
|
||||
|
||||
.ui.progress.warning .bar {
|
||||
background-image: linear-gradient(269deg, #de4723, #de6425, #dd7d26, #db9428) !important
|
||||
}
|
||||
|
||||
.ui.progress.error .bar {
|
||||
background-image: linear-gradient(287deg, #12032a, #480e2a, #7c1028, #b20d24) !important
|
||||
}
|
||||
|
||||
.ui.progress.offline .bar {
|
||||
background-color: #000 !important
|
||||
}
|
||||
|
||||
.ui.progress .bar {
|
||||
min-width: 1.8em !important;
|
||||
border-radius: 15px !important;
|
||||
line-height: 1.65em !important;
|
||||
text-shadow: 1px 0 1px #eee, -1px 0 1px #000
|
||||
}
|
||||
|
||||
.ui.progress {
|
||||
border-radius: 50px;
|
||||
background: #d9e1e8;
|
||||
box-shadow: inset 3px 3px 6px #b8bfc5, inset -3px -3px 6px #faffff
|
||||
}
|
||||
|
||||
.service-status .good {
|
||||
border-radius: 7px !important;
|
||||
background: linear-gradient(145deg, #23c74a, #1ea73e) !important;
|
||||
box-shadow: 0 0 0 #20b342 !important
|
||||
}
|
||||
|
||||
.service-status .danger {
|
||||
border-radius: 7px !important;
|
||||
background: linear-gradient(145deg, #c71e1e, #a71919) !important;
|
||||
box-shadow: 0 0 0 #20b342 !important
|
||||
}
|
||||
|
||||
.service-status .warning {
|
||||
border-radius: 7px !important;
|
||||
background: linear-gradient(145deg, #ffa51a, #de8b16) !important;
|
||||
box-shadow: 0 0 0 #ed9417 !important
|
||||
}
|
||||
|
||||
.service-status .table {
|
||||
border: none !important;
|
||||
border-radius: 7px;
|
||||
background: #e6eef4;
|
||||
box-shadow: -13px -13px 25px #d4dbe0, 13px 13px 25px #f8ffff
|
||||
}
|
||||
|
||||
.service-status .table td .button {
|
||||
border: none !important;
|
||||
border-radius: 7px;
|
||||
background: #e6eef4;
|
||||
box-shadow: inset -3px -3px 6px #c4cacf, inset 3px 3px 6px #fff
|
||||
}
|
||||
|
||||
.service-status table thead .center {
|
||||
border: none !important;
|
||||
background: #e6eef4 !important
|
||||
}
|
||||
|
||||
.service-status .table td {
|
||||
border: none !important
|
||||
}
|
||||
|
||||
.ui.right.center.popup {
|
||||
margin: -3px 0 0 .914286em !important;
|
||||
-webkit-transform-origin: left 50% !important;
|
||||
transform-origin: left 50% !important
|
||||
}
|
||||
|
||||
.ui.bottom.left.popup {
|
||||
margin-top: 3px !important;
|
||||
margin-left: 1px !important
|
||||
}
|
||||
|
||||
.ui.top.left.popup {
|
||||
margin-bottom: 10px !important;
|
||||
margin-left: 0 !important
|
||||
}
|
||||
|
||||
.ui.top.right.popup {
|
||||
margin-right: 0 !important;
|
||||
margin-bottom: 8px !important
|
||||
}
|
||||
|
||||
.ui.left.center.popup {
|
||||
margin: -3px .91428571em 0 0 !important;
|
||||
-webkit-transform-origin: right 50% !important;
|
||||
transform-origin: right 50% !important
|
||||
}
|
||||
|
||||
.ui.left.center.popup:before,
|
||||
.ui.right.center.popup:before {
|
||||
border: 0 solid #fafafaeb !important;
|
||||
background: #fafafaeb !important
|
||||
}
|
||||
|
||||
.ui.top.popup:before {
|
||||
border-color: #fafafaeb transparent transparent !important
|
||||
}
|
||||
|
||||
.ui.popup:before {
|
||||
border-color: #fafafaeb transparent transparent !important
|
||||
}
|
||||
|
||||
.ui.bottom.left.popup:before {
|
||||
border: 1px solid transparent !important;
|
||||
border-color: #fafafaeb transparent transparent !important;
|
||||
border-radius: 0 !important;
|
||||
background: #fafafaeb !important;
|
||||
-webkit-box-shadow: 0 0 0 0 #fafafaeb !important;
|
||||
box-shadow: 0 0 0 0 #fafafaeb !important;
|
||||
-webkit-tap-highlight-color: transparent !important
|
||||
}
|
||||
|
||||
.ui.bottom.right.popup:before {
|
||||
border: 1px solid transparent !important;
|
||||
border-color: #fafafaeb transparent transparent !important;
|
||||
border-radius: 0 !important;
|
||||
background: #fafafaeb !important -webkit-box-shadow:0 0 0 0 #fafafaeb !important;
|
||||
box-shadow: 0 0 0 0 #fafafaeb !important;
|
||||
-webkit-tap-highlight-color: transparent !important
|
||||
}
|
||||
|
||||
.ui.top.left.popup:before {
|
||||
border: 1px solid transparent !important;
|
||||
border-color: #fafafaeb transparent transparent !important;
|
||||
border-radius: 0 !important;
|
||||
background: #fafafaeb !important;
|
||||
-webkit-box-shadow: 0 0 0 0 #fafafaeb !important;
|
||||
box-shadow: 0 0 0 0 #fafafaeb !important;
|
||||
-webkit-tap-highlight-color: transparent !important
|
||||
}
|
||||
|
||||
.ui.top.right.popup:before {
|
||||
border: 1px solid transparent !important;
|
||||
border-color: #fafafaeb transparent transparent !important;
|
||||
border-radius: 0 !important;
|
||||
background: #fafafaeb !important;
|
||||
-webkit-box-shadow: 0 0 0 0 #fafafaeb !important;
|
||||
box-shadow: 0 0 0 0 #fafafaeb !important;
|
||||
-webkit-tap-highlight-color: transparent !important
|
||||
}
|
||||
|
||||
.ui.left.center.popup:before {
|
||||
border: 1px solid transparent !important;
|
||||
border-color: #fafafaeb transparent transparent !important;
|
||||
border-radius: 0 !important;
|
||||
background: #fafafaeb !important;
|
||||
-webkit-box-shadow: 0 0 0 0 #fafafaeb !important;
|
||||
box-shadow: 0 0 0 0 #fafafaeb !important;
|
||||
-webkit-tap-highlight-color: transparent !important
|
||||
}
|
||||
|
||||
.status.cards .ui.content.popup {
|
||||
min-width: 20rem !important;
|
||||
border: 1px solid transparent !important;
|
||||
border-radius: 5px !important;
|
||||
background-color: #fafafaeb !important;
|
||||
font-family: Arial, Helvetica, sans-serif !important;
|
||||
line-height: 2rem !important
|
||||
}
|
||||
|
||||
#app .accordion .title {
|
||||
text-shadow: 2px 2px 3px #c4cacf, -2px -2px 3px #fff;
|
||||
color: #787878 !important;
|
||||
font-weight: 900 !important
|
||||
}
|
||||
|
||||
#app .accordion .content {
|
||||
padding-top: 1.5em !important
|
||||
}
|
||||
|
||||
.description .wide {
|
||||
margin-top: 1em
|
||||
}
|
||||
|
||||
.description .wide:nth-child(odd) {
|
||||
text-shadow: 2px 2px 3px #c4cacf, -2px -2px 3px #fff;
|
||||
color: #787878 !important;
|
||||
font-weight: 500
|
||||
}
|
||||
|
||||
.description .wide:nth-child(8) {
|
||||
text-shadow: 2px 2px 3px #c4cacf, -2px -2px 3px #fff;
|
||||
color: #787878 !important;
|
||||
font-weight: 500
|
||||
}
|
||||
|
||||
.description .wide:nth-child(10) {
|
||||
text-shadow: 2px 2px 3px #c4cacf, -2px -2px 3px #fff;
|
||||
color: #787878 !important;
|
||||
font-weight: 500
|
||||
}
|
||||
|
||||
.description .wide:nth-child(14) {
|
||||
text-shadow: 2px 2px 3px #c4cacf, -2px -2px 3px #fff;
|
||||
color: #787878 !important;
|
||||
font-weight: 500
|
||||
}
|
||||
|
||||
.description .wide:nth-child(16) {
|
||||
text-shadow: 2px 2px 3px #c4cacf, -2px -2px 3px #fff;
|
||||
color: #787878 !important;
|
||||
font-weight: 500
|
||||
}
|
||||
|
||||
.stackable .card .content .header {
|
||||
text-align: center;
|
||||
text-shadow: 2px 2px 3px #c4cacf, -2px -2px 3px #fff;
|
||||
color: #525151 !important;
|
||||
font-weight: 500
|
||||
}
|
||||
|
||||
.stackable .card .content .header .popup {
|
||||
text-align: left;
|
||||
color: #000 !important;
|
||||
text-shadow: 0 0 0 #333 !important;
|
||||
font-weight: 100 !important
|
||||
}
|
||||
|
||||
.ui.menu .item>img:not(.ui) {
|
||||
display: none
|
||||
}
|
||||
|
||||
#app .accordion .content .card:not(:first-child) {
|
||||
margin-left: 10px
|
||||
}
|
||||
|
||||
.ui.menu .container .item {
|
||||
text-shadow: 2px 2px 3px #c4cacf, -2px -2px 3px #fff;
|
||||
color: #787878 !important;
|
||||
font-weight: 500
|
||||
}
|
||||
|
||||
.right.menu .positive {
|
||||
background: #e6eef4 !important;
|
||||
text-shadow: 2px 2px 3px #c4cacf, -2px -2px 3px #fff;
|
||||
color: #787878 !important;
|
||||
font-weight: 500
|
||||
}
|
||||
|
||||
.service-status .table {
|
||||
text-shadow: 2px 2px 3px #c4cacf, -2px -2px 3px #fff;
|
||||
color: #787878 !important;
|
||||
font-weight: 500
|
||||
}
|
||||
|
||||
.celled .aligned .thirteen .fine {
|
||||
width: 95% !important
|
||||
}
|
||||
|
||||
.celled .aligned .thirteen .fine small {
|
||||
color: #eee !important;
|
||||
text-shadow: 0 0 #fff
|
||||
}
|
||||
|
||||
.service-status>h2 {
|
||||
text-shadow: 2px 2px 3px #c4cacf, -2px -2px 3px #fff
|
||||
}
|
||||
|
||||
.ui.success.message {
|
||||
border-radius: 11px !important;
|
||||
background: #e6eef4 !important;
|
||||
box-shadow: 7px 7px 15px #cfd6dc, -7px -7px 15px #fdffff !important;
|
||||
color: #1a531b !important
|
||||
}
|
||||
|
||||
.ui.error.message {
|
||||
border-radius: 11px !important;
|
||||
background: #e6eef4 !important;
|
||||
box-shadow: 7px 7px 15px #cfd6dc, -7px -7px 15px #fdffff !important;
|
||||
color: red !important
|
||||
}
|
||||
|
||||
.ui.warning.message {
|
||||
border-radius: 11px !important;
|
||||
background: #e6eef4 !important;
|
||||
box-shadow: 7px 7px 15px #cfd6dc, -7px -7px 15px #fdffff !important;
|
||||
color: #f7c709 !important
|
||||
}
|
1
resource/static/theme-daynight/css/main.css
vendored
@ -1 +0,0 @@
|
||||
footer{background-color:#2f2f2f;color:#f2f2f2;font-size:14px}footer .footer-container{display:flex;justify-content:center;flex-direction:column;text-align:center;padding:1rem}footer .footer-container p{width:100%;margin-top:1rem}footer .footer-container a{color:#f2f2f2}footer .footer-container div{width:100%}*,*::before,*::after{box-sizing:border-box;margin:0;padding:0;text-decoration:none}body{font-family:Microsoft Yahei,Avenir,Segoe UI,Hiragino Sans GB,STHeiti,Microsoft Sans Serif,WenQuanYi Micro Hei,sans-serif;overflow-x:hidden;min-height:100vh;display:grid;grid-template-rows:1fr auto;background-color:#334561;color:#e1e1e1}article{display:flex;justify-content:center;align-items:center}.passwd-container{display:grid;min-height:320px;background-color:#e5e5e5;color:#121212;border-radius:5px;padding:1em 1.2em;box-shadow:0 2px 5px rgba(0,0,0,.3);width:100%;max-width:400px;width:calc(100% - 2em);margin:0 auto}.passwd-container input[type=password]{border:1px solid #a6a6a6;border-radius:4px;font-size:1em;padding-left:2em;min-width:100px;height:3em}.passwd-container input[type=password]::placeholder{text-align:right}.passwd-container button{margin-top:1em;margin-bottom:2em;border:none;background:none;border:1px solid #a6a6a6;border-radius:4px;background-color:#1670c5;color:#f2f2f2;font-size:1em;font-weight:bold;letter-spacing:1px;cursor:pointer;padding:.5em 0}.passwd-container button:hover{background-color:#1e85e6}h2{font-size:2em;text-align:center;color:#3c3c3c}h4{text-align:left;font-size:1em;font-weight:normal;letter-spacing:1px;height:1.5em}form{display:grid;position:relative}.passwd-icon{height:1em;width:1.34em;position:absolute;top:42px;left:10px}.passwd-icon g{fill:#494949}.logo{display:flex;align-items:center;justify-content:center;font-size:1.2em}.logo a{color:#3c3c3c;font-weight:bold}.logo a+a{margin-left:.8em}/*# sourceMappingURL=passwd.css.map */
|
BIN
resource/static/theme-daynight/img/flag/AD.png
vendored
Before Width: | Height: | Size: 9.0 KiB |
BIN
resource/static/theme-daynight/img/flag/AE.png
vendored
Before Width: | Height: | Size: 9.3 KiB |
BIN
resource/static/theme-daynight/img/flag/AF.png
vendored
Before Width: | Height: | Size: 10 KiB |
BIN
resource/static/theme-daynight/img/flag/AG.png
vendored
Before Width: | Height: | Size: 11 KiB |
BIN
resource/static/theme-daynight/img/flag/AL.png
vendored
Before Width: | Height: | Size: 10 KiB |
BIN
resource/static/theme-daynight/img/flag/AM.png
vendored
Before Width: | Height: | Size: 9.0 KiB |
BIN
resource/static/theme-daynight/img/flag/AR.png
vendored
Before Width: | Height: | Size: 9.6 KiB |
BIN
resource/static/theme-daynight/img/flag/AT.png
vendored
Before Width: | Height: | Size: 9.0 KiB |
BIN
resource/static/theme-daynight/img/flag/AU.png
vendored
Before Width: | Height: | Size: 12 KiB |
BIN
resource/static/theme-daynight/img/flag/AZ.png
vendored
Before Width: | Height: | Size: 9.7 KiB |
BIN
resource/static/theme-daynight/img/flag/BA.png
vendored
Before Width: | Height: | Size: 11 KiB |
BIN
resource/static/theme-daynight/img/flag/BB.png
vendored
Before Width: | Height: | Size: 9.8 KiB |
BIN
resource/static/theme-daynight/img/flag/BD.png
vendored
Before Width: | Height: | Size: 10 KiB |
BIN
resource/static/theme-daynight/img/flag/BE.png
vendored
Before Width: | Height: | Size: 9.0 KiB |
BIN
resource/static/theme-daynight/img/flag/BF.png
vendored
Before Width: | Height: | Size: 9.7 KiB |
BIN
resource/static/theme-daynight/img/flag/BG.png
vendored
Before Width: | Height: | Size: 9.0 KiB |
BIN
resource/static/theme-daynight/img/flag/BH.png
vendored
Before Width: | Height: | Size: 9.8 KiB |
BIN
resource/static/theme-daynight/img/flag/BI.png
vendored
Before Width: | Height: | Size: 13 KiB |
BIN
resource/static/theme-daynight/img/flag/BJ.png
vendored
Before Width: | Height: | Size: 9.1 KiB |
BIN
resource/static/theme-daynight/img/flag/BN.png
vendored
Before Width: | Height: | Size: 12 KiB |
BIN
resource/static/theme-daynight/img/flag/BO.png
vendored
Before Width: | Height: | Size: 9.6 KiB |
BIN
resource/static/theme-daynight/img/flag/BR.png
vendored
Before Width: | Height: | Size: 12 KiB |
BIN
resource/static/theme-daynight/img/flag/BS.png
vendored
Before Width: | Height: | Size: 10 KiB |
BIN
resource/static/theme-daynight/img/flag/BT.png
vendored
Before Width: | Height: | Size: 12 KiB |
BIN
resource/static/theme-daynight/img/flag/BW.png
vendored
Before Width: | Height: | Size: 9.0 KiB |
BIN
resource/static/theme-daynight/img/flag/BY.png
vendored
Before Width: | Height: | Size: 10 KiB |
BIN
resource/static/theme-daynight/img/flag/BZ.png
vendored
Before Width: | Height: | Size: 11 KiB |
BIN
resource/static/theme-daynight/img/flag/CA.png
vendored
Before Width: | Height: | Size: 9.9 KiB |
BIN
resource/static/theme-daynight/img/flag/CD.png
vendored
Before Width: | Height: | Size: 12 KiB |
BIN
resource/static/theme-daynight/img/flag/CF.png
vendored
Before Width: | Height: | Size: 9.9 KiB |
BIN
resource/static/theme-daynight/img/flag/CG.png
vendored
Before Width: | Height: | Size: 11 KiB |
BIN
resource/static/theme-daynight/img/flag/CH.png
vendored
Before Width: | Height: | Size: 9.6 KiB |
BIN
resource/static/theme-daynight/img/flag/CI.png
vendored
Before Width: | Height: | Size: 9.0 KiB |
BIN
resource/static/theme-daynight/img/flag/CL.png
vendored
Before Width: | Height: | Size: 9.5 KiB |
BIN
resource/static/theme-daynight/img/flag/CM.png
vendored
Before Width: | Height: | Size: 9.5 KiB |
BIN
resource/static/theme-daynight/img/flag/CN.png
vendored
Before Width: | Height: | Size: 10 KiB |
BIN
resource/static/theme-daynight/img/flag/CO.png
vendored
Before Width: | Height: | Size: 9.0 KiB |
BIN
resource/static/theme-daynight/img/flag/CR.png
vendored
Before Width: | Height: | Size: 9.0 KiB |
BIN
resource/static/theme-daynight/img/flag/CU.png
vendored
Before Width: | Height: | Size: 11 KiB |
BIN
resource/static/theme-daynight/img/flag/CV.png
vendored
Before Width: | Height: | Size: 10 KiB |
BIN
resource/static/theme-daynight/img/flag/CY.png
vendored
Before Width: | Height: | Size: 10 KiB |
BIN
resource/static/theme-daynight/img/flag/CZ.png
vendored
Before Width: | Height: | Size: 10 KiB |
BIN
resource/static/theme-daynight/img/flag/DE.png
vendored
Before Width: | Height: | Size: 9.0 KiB |
BIN
resource/static/theme-daynight/img/flag/DJ.png
vendored
Before Width: | Height: | Size: 10 KiB |
BIN
resource/static/theme-daynight/img/flag/DK.png
vendored
Before Width: | Height: | Size: 9.2 KiB |
BIN
resource/static/theme-daynight/img/flag/DM.png
vendored
Before Width: | Height: | Size: 11 KiB |
BIN
resource/static/theme-daynight/img/flag/DO.png
vendored
Before Width: | Height: | Size: 9.4 KiB |
BIN
resource/static/theme-daynight/img/flag/DZ.png
vendored
Before Width: | Height: | Size: 10 KiB |
BIN
resource/static/theme-daynight/img/flag/EC.png
vendored
Before Width: | Height: | Size: 10 KiB |
BIN
resource/static/theme-daynight/img/flag/EE.png
vendored
Before Width: | Height: | Size: 9.0 KiB |
BIN
resource/static/theme-daynight/img/flag/EG.png
vendored
Before Width: | Height: | Size: 9.3 KiB |
BIN
resource/static/theme-daynight/img/flag/ER.png
vendored
Before Width: | Height: | Size: 12 KiB |
BIN
resource/static/theme-daynight/img/flag/ES.png
vendored
Before Width: | Height: | Size: 9.7 KiB |
BIN
resource/static/theme-daynight/img/flag/ET.png
vendored
Before Width: | Height: | Size: 11 KiB |
BIN
resource/static/theme-daynight/img/flag/FI.png
vendored
Before Width: | Height: | Size: 9.4 KiB |
BIN
resource/static/theme-daynight/img/flag/FJ.png
vendored
Before Width: | Height: | Size: 12 KiB |
BIN
resource/static/theme-daynight/img/flag/FM.png
vendored
Before Width: | Height: | Size: 10 KiB |
BIN
resource/static/theme-daynight/img/flag/FR.png
vendored
Before Width: | Height: | Size: 9.0 KiB |
BIN
resource/static/theme-daynight/img/flag/GA.png
vendored
Before Width: | Height: | Size: 9.0 KiB |
BIN
resource/static/theme-daynight/img/flag/GB.png
vendored
Before Width: | Height: | Size: 12 KiB |
BIN
resource/static/theme-daynight/img/flag/GD.png
vendored
Before Width: | Height: | Size: 12 KiB |
BIN
resource/static/theme-daynight/img/flag/GE.png
vendored
Before Width: | Height: | Size: 10 KiB |
BIN
resource/static/theme-daynight/img/flag/GH.png
vendored
Before Width: | Height: | Size: 9.5 KiB |
BIN
resource/static/theme-daynight/img/flag/GM.png
vendored
Before Width: | Height: | Size: 9.0 KiB |
BIN
resource/static/theme-daynight/img/flag/GQ.png
vendored
Before Width: | Height: | Size: 10 KiB |